OpenACC supports type-bound procedures in C++?

First, I am really sorry to ask this question as I asked a similar one before. Please see the link: Procedure in derived type data The simple test code there was written in modern Fortran (using type-bound procedures and OpenACC does not support this feature).

My advisor asked me earlier tody: if we write the code using C++, then does OpenACC support type-bound procedures? Since I am not a CS guy, I do not know exactly what a type-bound procedure looks like in C++ (It looks like OpenACC supports member functions in a class in C++, but it does not support type-bound procedures in Fortran?). I need to write a very simple C++ code with OpenACC, and then prove OpenACC does not support type-bound procedures, even using C++. I know this question is a little weird but I have to figure it out. Can anyone give a simple example, or offer some information?

Thanks very much!

Best,

Weicheng

Hi Weicheng,

While you can use C++ class methods in OpenACC compute regions, this would be equivalent to calling a module subroutine. The equivalent to a Fortran type bound procedure would be a C++ virtual function, which is also not supported in an OpenACC compute regions.

With virtual functions, the decision as to which function to call is delayed until the actual call. This requires what is called a “trampoline” or “jump table” to jump to the correct device address of the function. We don’t yet have this mechanism available on the device, and why we don’t support virtual functions. Plus, this mechanism would cause overhead to your program and have an adverse impact on your performance.

-Mat

Hi Mat,

Thank you very much for your reply! This really makes sense to me. I’ll explain to my advisor in that way.

Best,

Weicheng Xue

Hi Mat,

Sorry to bother you again! I still need to formulate a C++ code to show my advisor that OpenACC does not support virtual functions, together with what you said earlier. I have a pretty simple code, and the compiling error looks new to me (not sure whether it is due to virtual function). Could you please have a check? Thanks a lot!

#include<stdlib.h>
#include<stdio.h>
#include<math.h>
//#include<iostream>

using namespace std;

class abstract_boundary_setting{
  public:

  int idx_max;

  #pragma acc routine
  virtual void bc_wall(int imax, int i, float *vel_i){
  }
};

class boundary_setting : public abstract_boundary_setting{
  public:

  #pragma acc routine
  void bc_wall(int imax, int i, float *vel_i){
    vel_i[i] = imax+i;
  }
};

int main(){

  int i;
  int imax = 100;
  float vel[imax];
  abstract_boundary_setting *boundary;

  for ( i=0; i<imax; i++ ){
	vel[i] = (float)(pow(float(i),2));
  }

  boundary_setting boundary_derived;
  boundary = & boundary_derived;

  boundary->idx_max = imax;

  #pragma acc enter data copyin(vel)

  #pragma acc kernels default(present) present(vel)
  #pragma acc loop independent
  for ( i=0; i<boundary->idx_max; i++ ){
      boundary->bc_wall(imax, i, vel);
  }

  #pragma acc exit data copyout(vel)

  //cout << vel[imax-1] << endl;
  //cout << 2*vel[imax-2]-vel[imax-3] << endl;

  printf("%f\n", vel[imax-1]);

  return 0;

}

If compiled with OpenACC: “pgc++ -acc -Minfo=accel derived_procedure_test_1D.cpp -o derived_procedure_test_1D”, then it returns:

[weich97@nr163 OpenACC_Test]$ pgc++ -acc -Minfo=accel derived_procedure_test_1D.cpp -o derived_procedure_test_1D
PGCC-S-0155-Invalid accelerator region: branching into or out of region is not allowed  (derived_procedure_test_1D.cpp: 47)
main:
     47, Accelerator clause: upper bound for dimension 0 of array 'vel' is unknown
         Generating enter data copyin(vel[:1])
         Invalid accelerator region: branching into or out of region is not allowed
     56, Accelerator clause: upper bound for dimension 0 of array 'vel' is unknown
         Generating exit data copyout(vel[:1])
abstract_boundary_setting::bc_wall(int, int, float *):
     14, Generating acc routine seq
         Generating Tesla code
boundary_setting::bc_wall(int, int, float *):
     22, Generating acc routine seq
         Generating Tesla code
PGCC/x86 Linux 17.5-0: compilation completed with severe errors

Best,

Weicheng

Hi Weicheng,

I believe the copyin and copyout sections should be vel[:imax]) instead of just vel. Otherwise you’re just copying in the first element.

What version of pgcc are you using? This is what is returned for me when I try your code:

main:
     48, Generating enter data copyin(vel[:imax])
         Accelerator restriction: loop contains unsupported statement type
         Accelerator region ignored
     49, Accelerator restriction: unsupported statement type: opcode=JSRA
     57, Generating exit data copyout(vel[:imax])

It compiles and runs fine if I remove the run-time polymorphism. In any case, I think your example is fine.

Hi,

Thanks a lot! I am now using PGI/17.5. What version are you using? Yeah, I agree that we cannot use polymorphism. I have a similar Fortran code which uses type-bound procedures, and it also has this "unsupported statement type"error. This (similar error for C++) is what I expected.

Best,

Weicheng