简体   繁体   中英

OpenMP 'parallel for' with prior initialisation

I am trying to parallelize a for-loop with OpenMP. Usually this should be fairly straightforward. However I need to perform thread specific initializations prior to executing the for-loop.

Specifically I have the following problem: I have a random number generator which is not thread-safe so I need create an instance of the RNG for every thread. But I want to make sure that not every thread will produce the same random numbers.

So I tried the following:

    #pragma omp parallel
    {
        int rndseed = 42;
        #ifdef _OPENMP
            rndseed += omp_get_thread_num();
        #endif

         // initialize randon number generator

         #pragma omp for
         for (int sampleid = 0; sampleid < numsamples; ++sampleid)
         {
             // do stuff
         }
    }

If I use this construct I get the following error message at runtime:

Fatal User Error 1002: '#pragma omp for' improperly nested in a work-sharing construct

So is there a way to do thread-specific initializations?

Thanks

I think there's a design error.

A parallel for loop is not just N threads with N the number of cores for example, but potentially N*X threads, with 1 <= N*X < numsamples.

If you want an "iteration private" variable, then declare it just inside the loop-body (but you know that already); but declaring a thread-private variable for use inside a parallel for loop is probably not justified enough.

The error you have:

Fatal User Error 1002: '#pragma omp for' improperly nested in a work-sharing construct

refers to an illegal nesting of worksharing constructs . In fact, the OpenMP 3.1 standard gives the following restrictions in section 2.5:

  • Each worksharing region must be encountered by all threads in a team or by none at all.
  • The sequence of worksharing regions and barrier regions encountered must be the same for every thread in a team.

From the lines quoted above it follows that nesting different worksharing constructs inside the same parallel region is not conforming.

Even though the illegal nesting is not visible in your snippet, I assume it was hidden by an oversimplification of the post with respect to the actual code. Just to give you an hint the most common cases are:

  • loop worksharing constructs nested inside a single construct (similar the example here )
  • loop worksharing constructs nested inside another loop construct

In case you are interested, in this answer the latter case is discussed more in details.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM