i have existing fortran source code working on adding c to, , having difficulty passing array c fortran function , receiving array back.
it compiles without errors, when attempt run code, says that:
"dimension of array 'p2' (in fortran function) has extent 3 instead of -4537421815 (or other similar number)"
i not sure going on here. attach 2 codes below.
note: have removed lot of variable initialization lines think seems unnecessary finding problem.
c function:
#include <stdio.h> #include <stdlib.h> extern "c" double* __multiphase_tools_mod_project(double p1[],double *mydt,int *myi,int *myj,int *myk); extern "c" void cuda_(int *ptr_band, double *ptr_u, double *ptr_v, double *ptr_w) { double *pt_out; double pt_in[3]; // loop on domain , compute fluxes near interfaces //======================================================================================= // x face //======================================================================================= (k = kmin; k <= kmax; k++) { (j = jmin; j <= jmax; j++) { (i = imin; <= imax; i++) { if (abs(band[i-1][j][k]) <= nband_cfl && abs(band[i][j][k]) <= nband_cfl ) { (int n = 1; n < 10; n++) { pt_in[0] = pt[0][n][1]; pt_in[1] = pt[1][n][1]; pt_in[2] = pt[2][n][1]; pt_out = __multiphase_tools_mod_project(pt_in,&neg_dt_uvw,&i,&j,&k); } } } } } return; }
fortran function:
function project(p1,mydt,myi,myj,myk) result(p2) use math use iso_c_binding implicit none real(wp), dimension(3) :: p2 real(wp), dimension(3), intent(in) :: p1 real(wp), intent(in) :: mydt integer, intent(in) :: myi,myj,myk real(wp), dimension(3) :: v1,v2,v3,v4 v1=get_velocity(p1 ,myi,myj,myk) v2=get_velocity(p1+0.5_wp*mydt*v1,myi,myj,myk) v3=get_velocity(p1+0.5_wp*mydt*v2,myi,myj,myk) v4=get_velocity(p1+ mydt*v3,myi,myj,myk) p2=p1+mydt/6.0_wp*(v1+2.0_wp*v2+2.0_wp*v3+v4) return end function project
fortran functions return array use hidden argument , implemented subroutines. why can't write compatible c function, because can't portably determine hidden argument properties.
for example
function f() result(res) real :: res(3) res = [1.,2.,3.] end
looks in gcc internal code as
f (struct array1_real(kind=4) & __result) { }
i suggest convert function subroutine. way can control argument (parameter) array , can make c interface:
subroutine project(p1,p2,mydt,myi,myj,myk) bind(c) real(wp), dimension(3), intent(out):: p2 ...
or can write wrapper subroutine calls function maintain fortran functionality unchanged.
Comments
Post a Comment