2
votes

Suppose I have an array with indices 0..n-1. Is there a way to choose which cells each thread would handle? E. g. thread 0 would handle cells 0 and 5, thread 1 would handle cells 1 and 6 and so on..

Currently the choice of cells which each thread operates is decided not by me, it's system chosen. I would like to get that control.

1

1 Answers

2
votes

When using a !$OMP PARALLEL DO with default parameter, work will be evenly shared among your threads. If you have, say, 10 threads and 1000 iterations, thread 0 will work on 1..100, thread 1 on 101..200 and so on.

If you want a finer control, do not use a PARALLEL DO. Use just a $! OMP PARALLEL that will run the same code in all your threads. In your code call OMP_get_thread_num that will return the id of the current thread. Then you can test this value and allocate to thread i whatever work you want. You can for instance compute a range of cells that should processed by this thread. OMP_get_num_threads that gives the total number of threads can also be useful.

For instance, for a static schedule, a omp parallel for on n elements in C is absolutely equivalent to

#pragma omp parallel
{
  int id_thread=omp_get_thread_num();
  int num_threads=omp_get_num_threads();
  int min_index=id_thread*(n/num_threads);
  int max_index=min((id_thread+1)*(n/num_threads),n)-1;
  for(int i=min_index; i<= max_index; i++){
     // whatever
  }
}

It is identical for a OMP PARALLEL DO in fortran (but I have a better knowledge of C syntax). If you want to process specific elements on a given thread, you can have more complex computations on the index range you want to consider in a given thread. So if you want to process every num_threads element (5 in you example), you can do:

#pragma omp parallel
{
  int id_thread=omp_get_thread_num();
  int num_threads=omp_get_num_threads();
  for(int i=id_thread; i<n; i+=num_threads){
     // whatever
  }
}

If num_threads=5, thread 0 will process elements 0, 5,..., thread 1 elements 1, 6, and so on. Fortran translation should be straighforward.