OpenMP enforce the order in which tasks are created

75 Views Asked by At

I am new to OpenMP and think my use case is not simple - hence looking for pointers on approach.

Is there a way to enforce execution of tasks in order they are spawned in OpenMP?

What I want to achieve is as follows

My data is a packet of data which contains a sequence number and sensor id.

The order of sequence number must be maintained for each sensor id but different sensor ids can execute in parallel.

In pseudo code - so please excuse the syntax. I am seeking conceptual understanding.

#pragma parallel for ordered 
for data in data_packet_by_sequence

#pragma task nowait
   omp_set_lock(data.sensor_id)
   process_data(data) // must execute in order of data.sequence 
   omp_unset_lock(data.sensor_id)

But the problem is that the process data might be schedule in a sequence that does not honor the sequence number of the packet

How can I enforce that when a sensor data is processed, it respects the data.sequence ordering?

Thanks in advance.

2

There are 2 best solutions below

4
PierU On

I think that the depend clause is a solution. I should rather write a comment because I am not really sure this works and is a proper answer, but writing (pseudo-)code in comments is difficult...

int dep[nbsensors];

#pragma omp parallel
#pragma omp single nowait
{
    for data in data_packet_by_sequence {
        #pragma omp task firstprivate(...) depend(inout:dep[data.sensor_id])
        process_data(data);
    }
}

Explanation: when a task that has a depend(out:x) clause is running, it prevents all other tasks with a depend(in:x) clause to start. As a consequence, among the tasks having a depend(inout:x) clause (same x for all of them), only one of them can run at a given time.

You don't even need to actually write something in dep[].

0
PierU On

There is actually a very simple solution, where all the threads execute the whole loop, but a given thread processes only some selected sensors:

#pragma omp parallel
{
    int nbthreads = omp_get_num_threads();
    int ithread = omp_get_thread_num();
    for data in data_packet_by_sequence {
        if ((data.sensor_id*nbthreads)/nbsensors == ithread) 
           process_data(data);
    }
}

This garantees that all the data from a given sensor are processed sequentially by the same thread