Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

Fortran - C Codes , OpenMP issue

Noemi_Gonzalez
Beginner
506 Views

Hello

I have a Fortran code that communicates with a C code using a DLL.

The OpenMP directives was developed for a couple of do loops in the Fortran code and the OpenMP compilation for the fortran code was turn ON using the following properties: OpenMP Conditional Compilation: YES,  Process Open MP Directives: Generate Parallel Code (/Qopenmp).

The C code does not has any OpenMP code and the openmp compilation properties are set up as OFF. 

If I compile the fortran code without OpenMP the executable run and communicates correctly with the DLL. When the fortran code is compiled turning ON the OpenMP directives, then the datafilenames that are passed through the DLL are wrong.

The following show the error that is generated when the OpenMP switches are activated in the properties page of the fortran code:

Without OpenMP the filenames that are passed through the DLL from Fortran to C are:

PATH1=  'C:\ Models\Test\REV 2nd ON\SFRC.IN'

PATH2= 'C:\ Models\Test\REV 2nd ON\SFRC.OUT''

PATH3= 'C:\ Models\Test\REV 2nd ON\SFRC.ERR '

Without OpenMP the filenames that are received tin the C code are:

f1= 'C:\ Models\Test\REV 2nd ON\SFRC.IN'

f2= 'C:\ Models\Test\REV 2nd ON\SFRC.OUT''

f3= 'C:\ Models\Test\REV 2nd ON\SFRC.ERR '

 

With OpenMP the filenames that are passed through the DLL from Fortran to C are:

PATH1=  'C:\ Models\Test\REV 2nd ON\SFRC.IN'

PATH2= 'C:\ Models\Test\REV 2nd ON\SFRC.OUT''

PATH3= 'C:\ Models\Test\REV 2nd ON\SFRC.ERR '

f1= 'C:\ Models\Test\REV 2nd ON\SFRC.IN   C:\ Models\Test\REV 2nd ON\SFRC.OUT    C:\ Models\Test\REV 2nd ON\SFRC.ERR '

f2= 'C:\ Models\Test\REV 2nd ON\SFRC.OUT    C:\ Models\Test\REV 2nd ON\SFRC.ERR ''

f3= 'C:\ Models\Test\REV 2nd ON\SFRC.ERR '

It can be seen that the f1 , f2, and f3 path and filenames are incorrect once they are passed from Fortran to C. The following are chuncks of the codes that can help to understand the issue.

CALL in FORTRAN CODE:

CALL swmm_run(f_1, f_2, f_3,swmmstep,refreshsw,Stimeflo2d,flo2dtimestep,swmm_dischin,swmm_disch,swmm_ynew,swmm_disinlet,swmm_fdep,swmm_invelev,swmm_crown,NoPonding,ErrorCod,swmm_outfq,swmm_outfwse,Flo2d_WSEs,Inflo_WSE,SWMMDummy,SSURCH_D_POPPED,swmm_outfpondvol,swmm_outfINV,swmm_DT_VOLACUM,swmm_NodeSurfArea,OUTF_GRID_UG,Flo2d_WSE,BuildNoSWMM,Check_SD,Dry_FLO2DStep)   !,Check_ValueNGR 04162014

Code in C:

__declspec(dllexport) int swmm_run(char* f1, char* f2, char* f3, int *swmmstep, int *refreshsw, double *Stimeflo2d, double *flo2dtimestep, double swmm_dischin[3000], double swmm_disch[3000], double swmm_ynew[3000], double swmm_disinlet[3000], double swmm_fdep[3000], double swmm_invelev[3000], double swmm_crown[3000], int NoPonding[3000], int *ErrorCod, double swmm_outfq[3000], double swmm_outfwse[3000], int Flo2d_WSEs[3000], double InfloWSE[3000], double SWMMDummy[12], double SSURCH_D_POPPED[3000], double swmm_outfpondvol[3000], double swmm_outfINV[3000], double *swmm_DT_VOLACUM, double swmm_NodeSurfArea[3000], int OUTF_GRID_UG[3000], double Flo2d_WSE[3000], char BuildNoSWMM[8], double *Check_SD, double *Dry_FLO2DStep)     //, double CheckValue[6]
04
//
05
//  Input:   f1 = name of input file  
06
//           f2 = name of report file
07
//           f3 = name of binary output file
08
//           swmmstep =  switch used to read, and calculate depending on parameters
09
//           Stimeflo2dsw = time step
10
//  Output:  returns error code
11
//  Purpose: runs a simulation.
12
//
13
{
14
    int i, j, r, k, n, kk, jj, ii, m;
15
    int  n1, n2, linkoutf, NOutfall;
16
    float x, y, z;
17
    double z1, z2, RIM1, RIM2,Checkpipe;
18
        long theDay, theHour;
19
    DateTime elapsedTime = 0.0;
20
 
21
    // --- open the files & read input data
22
 
23
    ErrorCode = 0;
24
 
25
    if(*swmmstep == 1) //Opening data files
26
    {  
27
         newHour = 0;               
28
         oldHour = 0;                 
29
         *ErrorCod = 0;             
30
         RUNOFFSWITCH = 0;
31
         FLO2D_SIMUL=SWMMDummy[0];
32
                 swmm_open(f1, f2, f3);    // The filenames are not correctly transferred when OpenMP is ON in the Fortran properties

 

 

Thank you in advance for any help you can provide.

 

GR

0 Kudos
1 Solution
jimdempseyatthecove
Honored Contributor III
506 Views

>> When the fortran code is compiled turning ON the OpenMP directives, then the datafilenames that are passed through the DLL are wrong.

I suspect that your Fortran code did not append a NULL character to the file name (for use by the C fopen). Example

f1 = 'Foo.dat' // CHAR(0)

or

USE ISO_C_BINDING
...
f1 = 'Foo.dat' // C_NULL_CHAR

The change in compiler options may have altered the accidental occurrence of finding a NULL terminated file name.

Jim Dempsey

View solution in original post

0 Kudos
4 Replies
Yuan_C_Intel
Employee
506 Views

Hi, Gonzalez

How do you define f_1, f_2 and f_3 in your Fortran code? Do you have an interface for swmm in Fortran?

Is the "call swmm_run(...)" under an Openmp parallel loop or region?

Thanks.

 

0 Kudos
Noemi_Gonzalez
Beginner
506 Views

Hi Yolanda,

I defined those variables as:   CHARACTER*80 f_1, f_2, f_3

I have an interface in my fortran code.

The call swmm_run(...) is NOT inside an OpenMP loop or region.

Thanks for your reply.

GR

0 Kudos
jimdempseyatthecove
Honored Contributor III
507 Views

>> When the fortran code is compiled turning ON the OpenMP directives, then the datafilenames that are passed through the DLL are wrong.

I suspect that your Fortran code did not append a NULL character to the file name (for use by the C fopen). Example

f1 = 'Foo.dat' // CHAR(0)

or

USE ISO_C_BINDING
...
f1 = 'Foo.dat' // C_NULL_CHAR

The change in compiler options may have altered the accidental occurrence of finding a NULL terminated file name.

Jim Dempsey

0 Kudos
Yuan_C_Intel
Employee
506 Views

Hi, Gonzalez

Yes, agree with Jim.

You need to append the string in Fortran with a null-terminate character: '\0', when you pass the string to a C program.

Otherwise C string cannot recognize the string length and where to end it. 

The result with Openmp disabled maybe just be correct by chance.

Hope this helps.

Thanks.

0 Kudos
Reply