PGI does not support a function call in an OpenMP map clause

We have noticed that the PGI compiler does not support function calls in an OpenMP map clause. Please see the following compilation error which appears when using PGI-19.1 and FUNCTION_IN_PRAGMA is defined. The map clause looks like “map(tofrom:arr.dptr[0:arr.getSize()])” where getSize() is the function call causing the compilation error. The program shown below uses this method of mapping the data as well as a simpler method which does not use the getSize() function. The simpler method works.

+ pgc++ -mp -std=c++11 test.cxx -o test
+ ./test
Before increment
1
1
After increment
2
2
+ pgc++ -DFUNCTION_IN_PRAGMA -mp -std=c++11 test.cxx -o test
"test.cxx", line 45: error: invalid text in pragma
  #pragma omp target map(tofrom: arr, arr.dptr[0:arr.getSize()])
                                                              ^

"test.cxx", line 45: error: extra text after expected end of preprocessing
          directive
  #pragma omp target map(tofrom: arr, arr.dptr[0:arr.getSize()])
                                                               ^

2 errors detected in the compilation of "test.cxx".

The code is shown below

#include <cstdlib>
#include <iostream>

class Array1D
{
public:
  size_t size = 0;
  double * dptr;

  inline double& operator() (size_t i1) { return dptr[i1]; }

  Array1D() { size=0; dptr=NULL; }
  Array1D(const Array1D &p) { dptr=p.dptr; }

  Array1D(size_t in) { size=in; dptr=(double*)malloc(size*sizeof(double)); }

  ~Array1D() { if (size && dptr) free(dptr); }

  size_t getSize() { return size; }
};


int main()
{
  int i;
  const int sz = 2;
  Array1D arr(sz);

  std::cout << "Before increment" << std::endl;
  for (i=0; i<sz; ++i) arr(i) = 1;
  for (i=0; i<sz; ++i) std::cout << arr(i) << std::endl;

  /* Method 1 */
#pragma omp target map(tofrom: arr, arr.dptr[0:sz])
  {
    #pragma omp teams distribute parallel for
    for (i=0; i<sz; ++i) arr(i) += 1.0;
  }

  std::cout << "After increment" << std::endl;
  for (i=0; i<sz; ++i) std::cout << arr(i) << std::endl;

  /* Method 2 */
#ifdef FUNCTION_IN_PRAGMA
#pragma omp target map(tofrom: arr, arr.dptr[0:arr.getSize()])
  {
    #pragma omp teams distribute parallel for
    for (i=0; i<sz; ++i) arr(i) += 1.0;
  }
  std::cout << "After increment" << std::endl;
  for (i=0; i<sz; ++i) std::cout << arr(i) << std::endl;
#endif

  return 0;
}

Hi Chris,

Thanks for the report! I’ve add a problem report (TPR #27111) and sent to engineering for review.

Best Regards,
Mat