Hi everyone,
I’m dealing with the acceleration of a CFD code written in Fortran90 (MPI) and compiled with mpif90 under nvhpc-23.1. The GPU acceleration is performed with OpenACC and it is a multi GPU code. During the acceleration of a subroutine I have this error in compilation:
Accelerator restriction: call to ‘egspar’ with no acc routine information
The function egspar
is called inside a triple DO loop in this way:
SUBROUTINE MolProp
USE global_mod
USE common_alloc
USE common_mpi
USE openacc
!$acc update device(B,BBB,MINi,MAXi,MINj,MAXj,MINk,MAXk)
!$acc update device(Yi(:,:,:,:),T(:,:,:),p(:,:,:),rho(:,:,:),Wmix(:,:,:))
!$acc parallel loop gang vector collapse(3) &
!$acc& private(s,ss,T_ijk,Wmix_ijk,Yi_ijk,Mis,Ks,Xir,appo,appo1,appo2,appo3,appo4,appo5,appo6) &
!$acc& private(T_dim,c,DelTc,c_p1,d3,d4,d5,d2_KT,T_LJij,T_LJij2,T_LJij3,T_LJij4,T_LJij5,OMij,f) &
!$acc& private(VISC_ijk,COND_ijk,DIFF_ijk) &
!$acc& private(p_app,W_app,yyi_ijk,xxir,dtemp,CCp,st,st1,d_ij,stampa) &
!$acc& copy(i,j,k) copyin(Yi(:,:,:,:),T(:,:,:),Wmix(:,:,:),p(:,:,:),rho(:,:,:)) copyout(VISC(:,:,:),COND(:,:,:),DIFF(:,:,:,:))
do k = MINk(BBB)-GHOST ,MAXk(BBB)+GHOST
do j = MINj(BBB)-GHOST ,MAXj(BBB)+GHOST
do i= MINi(BBB)-GHOST ,MAXi(BBB)+GHOST
!....Some calculations performed correctly.....
call egspar(T_ijk, xxir, yyi_ijk, CCp, weg, iweg, st, st1 )
end do
end do
end do
where, for the sake of clarity yyi_ijk
is a POINTER. Nevertheless, egspar
is written in another file, which unfortunately is written in C language. The function is the following:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <openacc.h>
int egspar_c ( double T, double *x, double y, double *cp, double *weg, int *iweg ){
double summa, aaa, sss, wwtr, app, app1 ;
int ns, i, j ;
lspar_c(egegeg_.JFLAG, *(weg+egegeg_.IEGPA), T, *(weg+egegeg_.IDLT1), *(weg+egegeg_.IDLT2), *(weg+egegeg_.IDLT3), *(weg+egegeg_.IDLT4),
*(weg+egegeg_.IDLT5), *(weg+egegeg_.IDLT6), *(weg+egegeg_.IEGRU), egegeg_.NS, (weg+egegeg_.IEGWT), (weg+egegeg_.IBIN),
(weg+egegeg_.IETA), (weg+egegeg_.IETALG), (weg+egegeg_.IAIJ), (weg+egegeg_.IBIJ), (weg+egegeg_.ICIJ), (weg+egegeg_.ICTAIJ),
(weg+egegeg_.IFITA), (weg+egegeg_.IFITB), (weg+egegeg_.IFITC), (weg+egegeg_.ICINT), cp, (weg+egegeg_.ICXI),
(weg+egegeg_.IEPSIJ), (weg+egegeg_.IEGEPS), (weg+egegeg_.IEGCFD), (weg+egegeg_.IEGCFE), (weg+egegeg_.IEGZRT),
(weg+egegeg_.IEGDIP), (iweg+egegeg_.IEGLIN));
summa = 0.0e0;
ns = egegeg_.NS;
for (int i = 0; i<ns; i++)
summa = summa + *(x+i);
*(weg+egegeg_.ISUMTR) = summa;
aaa = summa / (double) ns;
sss = 1.0e-16;
wwtr = 0.0e0;
for (int i = 0; i<ns; i++) {
*(weg + egegeg_.IXTR + i ) = *(x + i) + sss *( aaa - *(x + i) );
wwtr = wwtr + *(weg + egegeg_.IXTR + i ) * *(weg + egegeg_.IEGWT + i );
}
*(weg + egegeg_.IWWTR) = wwtr;
for (int i = 0; i<ns; i++)
*(weg + egegeg_.IYTR + i ) = *(weg + egegeg_.IXTR + i ) * *(weg + egegeg_.IEGWT + i ) / wwtr;
egzero_c( ns, weg + egegeg_.IAUX);
for (int i = 0; i<ns; i++){
app1 = *(weg + egegeg_.IYTR + i ); app = 0.0e0;
for (int j = i+1; j<ns; j++){
app = app + *(weg + egegeg_.IYTR + j);
*(weg + egegeg_.IAUX + j) = *(weg + egegeg_.IAUX + j) + app1;
}
*(weg + egegeg_.IAUX + i ) = *(weg + egegeg_.IAUX + i) + app;
}
}
This C code is compiled in the following way:
nvc -c -acc=gpu -target=gpu,noautopar -gpu=cc80 -Mpreprocess -Mfree -Mextend -Munixlogical -Mbyteswapio -traceback -Mchkstk -Mnostack_arrays -Mnofprelaxed -Mnofpapprox -Minfo=accel …/SHARED_FILES/EGSlib_c.c
I don’t understand this type of problem, since, I always do the same with other call
to functions or subroutines written in Fortran, but I’ve never had an issue of this type. Could it be related to the fact that is written in C? I have to admit that I have no experience in C programming therefore I have some problems dealing with it.
Thank you in advance,
-Matteo