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?
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.
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
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.