Multiple return values from an omp declare simd function

General OpenMP discussion

Multiple return values from an omp declare simd function

Postby angainor » Thu Feb 08, 2018 6:51 am

Hello, everyone,

I'm struggling to vectorize a C++ function, which must return more than a single (small vector) value. A trivial example looks as follows (https://godbolt.org/g/oug1i8):

Code: Select all
#pragma omp declare simd simdlen(4)
double test(double v1, double v2, double &out)
{
    out  = (v1+v2)/2;
    return (v1-v2)/2;
}


In essence, simd-vectorized functions can by default return a single vector. But the above code is not vectorized by the compilers unless I declare linear(ref(out)). I do not want to do this, because I don't need to store this value in a global linear array. I only need it in local computations in the caller.

Is there any way for me to return this second value within the OpenMP framework without using a global linear array? I do not mind if it is stored in a small, local array, as long as I do not have to specify some large linear pointer.

Thanks a lot!

Marcin Krotkiewski
angainor
 
Posts: 2
Joined: Tue Feb 06, 2018 5:09 am

Re: Multiple return values from an omp declare simd function

Postby MichaelKlemm » Fri Feb 09, 2018 6:50 am

Hi,

I'm afraid that there's not a good solution for this problem at this point for OpenMP 4.5. Here are two options that you can use:

* Split it in two different functions. I'm not sure if this will be at all possible, as it really depends on the size of the function.

* Use a short array (w/ length of register size) on the caller site and use the modulo operator to make sure that the caller stays in the bounds of the array. That way you can keep the function as is and you won't have to allocate a global array, but rather only a small temporary array in the calling code.

Kind regards,
-michael
MichaelKlemm
 
Posts: 3
Joined: Mon Oct 04, 2010 8:52 am

Re: Multiple return values from an omp declare simd function

Postby angainor » Thu Feb 15, 2018 12:48 am

Hi, Michael,

Thanks for your answer. I can't split the function, of course. Your second suggestion would be perfect. The problem is that the compilers do not vectorize the function call - or at least I don't know how to make them. Probably in this case the compilers identify some data dependence on the short array entries, although in fact there is none. The following does not work, i.e., call to test is scalar:

Code: Select all
#pragma omp declare simd simdlen(4) linear(v2)
double test(double v1, double *v2) __attribute__ ((noinline));
double test(double v1, double *v2)
{
  *v2 = (*v2-v1)*0.5;
  return (v1+*v2)*0.5;
}

void run(int n)
{
  double temp[4] = {1,2,3,4};
  void *ptr;
  posix_memalign(&ptr, 32, sizeof(double)*n);
  double *out = (double*)ptr;

#pragma omp for simd
  for(int i=0; i<n; i++){
    out[i] = test((double)i, temp+i%4);
  }
}


Is there an omp directive that can force vectorization? like ivdep in the Intel compiler.

The only way I've managed to do what I want is through inlining of test, but that is not an ideal solution - it can't always be done.

Regards,

Marcin
angainor
 
Posts: 2
Joined: Tue Feb 06, 2018 5:09 am


Return to Using OpenMP

Who is online

Users browsing this forum: Exabot [Bot], Google [Bot] and 5 guests

cron