Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28543 Discussions

Unexpected changes to variables when calling functions in C++ dynamic linked libraries

Jiayu_Leng
Novice
2,083 Views

Hi there,

    I'm trying to use the GPU to parallelize some of the code in a Fortran program. But when I called a function in the C++ dynamic link library, I found that some variable values inside Fortran had changed.  With a small test(linked below), I found that the address of the variable in Fortran overlapped with the address of the member variable in the object in C. I want to know why such memory errors occur and how I can avoid them.

Jiayu_Leng_0-1705480747014.pngJiayu_Leng_1-1705480817887.png

 

Environment:

I'm building C libraries with Visual Studio 17 2022

Fortran program with Visual Studio 14 2015 and parallel_studio_ex_2016

Labels (2)
0 Kudos
18 Replies
El_Zorro_Oro
New Contributor I
2,052 Views

   This is just my recommendation, it will not necessarily solve the problem.

   However, it is the consensus, IMHO, that, as software engineers, we use the latest tools.

   So, it is recommend that you upgrade the Fortran Compiler to the one provided in Intel OneAPI package.

   It is also recommend that you upgrade to Visual Studio 2019, my IT organization, Lockheed Martin,  has recommend against using Visual Studio 2017.

   The OneAPI Fortran Compiler is, IMHO, the best available, and it is provided free.  I have used it to compile one of the largest Fortran programs ever written, NASTRAN(R).  

   I have also used Visual Studio 2019 for many years and it works well with the OneAPI Fortran.

   Attached are some notes that I wrote up years ago, you may find them useful.

 

Jiayu_Leng
Novice
2,010 Views

    Thank you Oro for your advice! I tried updating the test environment. Now with Fortran compiled by OneAPI in VS2019, but I still got the same Error.

Jiayu_Leng_1-1705566038276.png

 

0 Kudos
Barbara_P_Intel
Employee
1,975 Views

Which Intel Fortran compiler are you using? Only ifx is capable of offloading to Intel GPUs.

Now for the C++. It looks like it's written in CUDA. Is that right? If so, that won't work. CUDA code should be migrated to SYCL or rewritten in C++.

 

0 Kudos
Jiayu_Leng
Novice
1,938 Views

Hi Barbara!

    Thank your reply! I'm using w_BaseKit_p_2024.0.1.45 and w_HPCKit_p_2024.0.1.35 IFX Intel Fortran Compiler.

Jiayu_Leng_0-1705651875357.png

    Since there is no usable Fortran Cuda compiler on Windows, I'm trying to use dll to add C/C++ in Fortran process.  My C++ or CUDAC part is trying to use CUDA to help with the parallelization.  I didn't get your mean by saying "If its written in CUDA, that won't work.". Please tell me more about that. 

    I'd be very grateful if you could tell me problems in my code!

0 Kudos
El_Zorro_Oro
New Contributor I
1,917 Views

HI Jiayu,

Just an additional thought or two.

I have not coded C++ to run with Fortran, but in the old days (1980), we had to remember two rules when linking C with FORTRAN;

1. That FORTRAN uses pointers, so any variables in the call stack had to be of type ptr in C.

and

2. That the call  stack in C was in reverse order of Fortran.

Maybe that is the case today and why variable are stepping on each other.

Just a thought.

 

0 Kudos
El_Zorro_Oro
New Contributor I
1,918 Views

Hi Jiayu,

This just my suggestion based on past experience.

The use of dll-s are neat, but with todays computers, not really necessary, IMHO.

So a static .exe may resolve the issue since the linker has to resolve external (C++) references.

The PowerPoint charts that I sent earlier shows how to create a static (i.e.  stand alone) .exe;  no dll-s needed.

Good luck,

 

0 Kudos
Jiayu_Leng
Novice
1,609 Views

Hi Oro!

    Had using static libraries to build the test but with the same problem.

Jiayu_Leng_0-1706075949725.pngJiayu_Leng_1-1706076031679.pngJiayu_Leng_2-1706076081695.png

 

0 Kudos
Barbara_P_Intel
Employee
1,907 Views

@Jiayu_Leng, which GPU do you plan to use with this executable? Intel? Nvidia?

 

0 Kudos
El_Zorro_Oro
New Contributor I
1,886 Views

Hi Jiayu,

When you finally get something working would you please supply some code fragments and process?

Thanks and good luck.

0 Kudos
Jiayu_Leng
Novice
1,804 Views

Thank you Oro! I'll try my best. I'll send you codes, when it gets some progress.

0 Kudos
Jiayu_Leng
Novice
1,618 Views

Hi, Oro!

    I haven't tried the method of using static libraries you suggested before yet.

    I may have found a potential solution, but I'm not sure if this approach is valid on different compilers.  In MWE, I use a struct exported to Fortran. Use a type in Fortran to receive this struct.  This prevents the address of the variable in the struct from coinciding with the address of other variables in Fortran. As shown in the red circle in the picture.

Jiayu_Leng_0-1706072907296.png

    myArray in the picture is an array I allocated in Fortran. I tried to use the variable obj_ptr in the structure that stores the pointer to the class in C. But I found this attempt to be useless, because obj_ptr is ultimately assigned in C through the following createGlobalStruct function.

Jiayu_Leng_1-1706073491690.png

    There is no conflict between the memory allocated in C and Fortran.

Jiayu_Leng_2-1706073940296.png

    I think this method may cause the dynamically allocated memory in Fortran to conflict with the memory of the member variables of the class in C. It's just that I found on multiple runs that Fortran allocates enough memory for a dummyarray. So there is a potential problem here, but I did successfully call functions from C++ and CUDA in Fortran.

0 Kudos
Jiayu_Leng
Novice
1,149 Views

Fortran seems to be passing the address of type(c_ptr) by default. So when I operate the globalData object in C, its like change a double pointer of the globalData. Problem solved by adding `value` keyword to Fortran interface of type(c_ptr) globalDataPtr.  The globalDataPtr in Fortran should be passed by value. 

0 Kudos
Jiayu_Leng
Novice
1,804 Views

Hi Barbara,

    I'm using CUDA on Nvidia GPU.

0 Kudos
Barbara_P_Intel
Employee
1,721 Views

Intel Fortran is not supported on Nvidia GPUs.

Linking an Intel Fortran object file with a CUDA object file is not supported.

Intel Fortran executables will only run on Intel GPUs. 

Intel Fortran executables with SYCL routines will run only on Intel GPUs.

Sorry.

Now Cuda applications with no Fortran can be migrated to SYCL and there are plugins available to run on Nvidia and AMD GPUs. The info in this link will help you get started.

 

0 Kudos
Steve_Lionel
Honored Contributor III
1,529 Views

My guess is that you have a mismatch in what you are passing to the non-Fortran routine, which is writing memory outside of what you passed. Without a test case we can try ourselves, it's hard to say further.

0 Kudos
Steve_Lionel
Honored Contributor III
1,125 Views

Fortran doesn't pass anything by value unless the called routine has BIND(C) in its interface and the VALUE attribute is supplied for the argument. Note that VALUE in absence of BIND(C) passes a temporary copy by reference. 

0 Kudos
JohnNichols
Valued Contributor III
1,105 Views

Fortran doesn't pass anything by value unless the called routine has BIND(C) in its interface and the VALUE attribute is supplied for the argument. Note that VALUE in absence of BIND(C) passes a temporary copy by reference. 

---------------------------------------------------------------------------------------------------------------------------------------------

I was trying to explain this concept to my 16 year old daughter, she looked at me strangely and said, Dad I just want the cash.  

Ah. the innocence of youth.

 

0 Kudos
mecej4
Honored Contributor III
1,076 Views

An amusing analogy:

     Purchasing an article by paying cash: "Pass by Value"

     Purchasing with a credit card: "Pass by Reference"

Reply