- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Environment:
I'm building C libraries with Visual Studio 17 2022
Fortran program with Visual Studio 14 2015 and parallel_studio_ex_2016
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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++.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Oro!
Had using static libraries to build the test but with the same problem.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Jiayu,
When you finally get something working would you please supply some code fragments and process?
Thanks and good luck.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you Oro! I'll try my best. I'll send you codes, when it gets some progress.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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.
There is no conflict between the memory allocated in C and Fortran.
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Barbara,
I'm using CUDA on Nvidia GPU.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
An amusing analogy:
Purchasing an article by paying cash: "Pass by Value"
Purchasing with a credit card: "Pass by Reference"
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page