- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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
Ссылка скопирована
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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.
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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.
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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++.
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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!
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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.
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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,
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
Hi Oro!
Had using static libraries to build the test but with the same problem.
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
Hi Jiayu,
When you finally get something working would you please supply some code fragments and process?
Thanks and good luck.
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
Thank you Oro! I'll try my best. I'll send you codes, when it gets some progress.
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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.
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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.
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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.
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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.
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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.
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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.
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
An amusing analogy:
Purchasing an article by paying cash: "Pass by Value"
Purchasing with a credit card: "Pass by Reference"

- Подписка на RSS-канал
- Отметить тему как новую
- Отметить тему как прочитанную
- Выполнить отслеживание данной Тема для текущего пользователя
- Закладка
- Подписаться
- Страница в формате печати