Search code examples
openmp

Open MP: private structure with shared element?


Is the following possible?

EDIT: Minimal working example:

#include <omp.h>
#include <stdio.h>

struct foo
{
        int a;
        int b;
};

int main(int argc, char ** argv)
{
  struct foo outerFoo;
  int * p = &outerFoo.a;

  outerFoo.a = 1;

  printf("outerFoo @ %p, a=%d\n", &outerFoo, outerFoo.a);

#pragma omp parallel private(outerFoo), shared(p)
  {
    printf("Thread %d: outerFoo @ %p, a=%d, p = %p,p->:%d\n",
           omp_get_thread_num(),
           &outerFoo, outerFoo.a,p,*p);

#pragma omp critical // i know i can use atomic here
    {
        *p=*p+1;
    }
  }

  printf("a:%d\n",outerFoo.a);
  return 0;
}

Solution

  • What you have written is certainly possible. Whether it does what you want is impossible for us to tell, since you haven't told us what that is!

    I strongly suspect that it doesn't, since it will generate new, uninitialized instances of somestruct in each thread, and a shared pointer to the outer scope instance.

    Consider this code which is effectively the same as yours, but compileable

    #include <omp.h>
    #include <cstdio>
    
    class foo
    {
    public:
      int a;
      int b;
      foo() : a(0), b(1) {}
    };
    
    int main(int argc, char ** argv)
    {
      foo outerFoo;
      int * p = &outerFoo.a;
    
      outerFoo.a = 27;
    
      printf("outerFoo @ %p, a=%d, b=%d\n", &outerFoo, outerFoo.a, outerFoo.b);
    #pragma omp parallel private(outerFoo), shared(p)
      {
        printf("Thread %d: outerFoo @ %p, a=%d, b=%d, p = %p\n",
               omp_get_thread_num(),
               &outerFoo, outerFoo.a, outerFoo.b,p);
      }
    
      return 0;
    }
    

    It prints something like this

    OMP_NUM_THREADS=4 ./a.out
    outerFoo @ 0x7fffffffd080, a=27, b=1
    Thread 0: outerFoo @ 0x7fffffffcb80, a=0, b=1, p = 0x7fffffffd080
    Thread 3: outerFoo @ 0x2aaaacf4fa80, a=0, b=1, p = 0x7fffffffd080
    Thread 2: outerFoo @ 0x2aaaacb4da80, a=0, b=1, p = 0x7fffffffd080
    Thread 1: outerFoo @ 0x2aaaac74ba00, a=0, b=1, p = 0x7fffffffd080
    

    So you can see that happening. There is one outer instance of the class and four inner ones. All of them have all of the struct fields.