Buiding ADDA and ADDA_OCL with visual studio2019 on windows

35 views
Skip to first unread message

Michel GROSS

unread,
May 29, 2024, 11:50:46 AM5/29/24
to ADDA questions and answers

I compiled ADDA on Windows using Visual Studio 2019 from the sources, without using the provided makefiles.

For the C/C++ project, I started from the "C/C++ Console Application" example project in Visual Studio 2019, selecting the Intel C++ Compiler 2024 and the Base Platform Toolset v142. I added the additional option "-Qstd=c99". I included the ADDA C/C++ source files in the project, excluding the files associated with OpenCL, namely "oclcore.c" and "oclmatvec.c".

During compilation, I encountered a small error in "param.c". With the options used in my project, the "_isatty" function is not defined in the <io.h> header but in the <corecrt_io.h> header. Therefore, I added the following to the "param.c" code:

#ifdef WINDOWS
#include <corecrt_io.h>
#endif

For the Fortran project, I started from the "Fortran DLL" example project in Visual Studio 2019, selecting the Intel IFX compiler. I added the ".f" and ".f90" source files. The compilation produces a dynamic library ".dll" and its import file ".lib" that must be used for linking the C/C++ executable. I chose to compile the Fortran code into a DLL to simplify linking. Indeed, on Windows, the code in a DLL contains all the libraries used by the DLL. Therefore, it is not necessary to add the Fortran libraries for linking the C/C++ project. Moreover, a DLL compiled with IFX can be used by a C/C++ code compiled with a GNU compiler (gcc or g++).

To create the Fortran DLL, I encountered two small issues. In a DLL project compiled with IFX, you need to explicitly indicate which functions should be exported. Therefore, I modified the headers of "bessel.f90" and "propaesplibreintadda.f" as follows:


    !DEC$ ATTRIBUTES DLLEXPORT :: BJNDD
    subroutine BJNDD ( n, x, bj, dj, fj )
........

     !DEC$ ATTRIBUTES DLLEXPORT :: propaespacelibreintadda
     
subroutine propaespacelibreintadda(Rij,k0a,
     
..........

Moreover, for DLLs compiled with IFX, the names of the exported functions are always in uppercase, and there is no addition of the underscore ("_") character. To use the Fortran functions from the C/C++ code, you need to modify the names used in the C/C++ code accordingly.

To access the Fortran DLL functions with minimal modification to the ADDA C/C++ code, I used wrappers:


void PROPAESPACELIBREINTADDA(const double *Rij,const double *ka,const double *gridspacex,const double *gridspacey,
const double *gridspacez,const double *relreq,double *result,int *ifail);


void propaespacelibreintadda_(const double* Rij, const double* ka, const double* gridspacex, const double* gridspacey,
const double* gridspacez, const double* relreq, double* result, int* ifail) {

PROPAESPACELIBREINTADDA(Rij,ka,gridspacex,gridspacey,
gridspacez,relreq,result,ifail);

};



void BJNDD(const int* n, const double* x, double* bj, double* dj, double* fj);



void bjndd_(const int* n, const double* x, double* bj, double* dj, double* fj) {

BJNDD(n, x, bj, dj, fj);

};

The construction of ADDA can be done without difficulty after adding the FFTW DLLs and their import libraries. The preprocessor options for the C/C++ code are:

If you need to add specific preprocessor options, please provide them, and I can include them in the translation.

_CRT_SECURE_NO_WARNINGS
NO_GITHASH
_WIN32

My computer has an NVIDIA GTX 760 graphics card with CUDA 11.4 installed, so I also compiled ADDA_OCL with Visual Studio 2019. The construction of the project is very similar to that of ADDA. Of course, you need to add the "oclcore.c" and "oclmatvec.c" source files and remove "matvec.c".
The compilation options for the C/C++ code are:

_CRT_SECURE_NO_WARNINGS
NO_GITHASH
_WIN32
OPENCL
OCL_READ_SOURCE_RUNTIME
SIZET_ULONG

Here is the continuation of the translation:

I encountered a small error in "oclcore.c" because UINT32_MAX and UINT64_MAX are not defined in <io.h> but in <stdint.h>.

Therefore, I added the following lines to the "oclcore.c" code:

#ifdef WINDOWS

#include<stdint.h>

#endif


I also encountered another error at runtime during the compilation of the last line of "oclkernels.cl", where the characters encountered did not seem to be UTF-8 characters.

I did not understand the meaning of this error, which seems to occur when reading the "oclkernels.cl" file. To solve this problem, I modified the reading of the "oclkernels.cl" file by using a "readKernelSource" function that I created. The code became:

// Read the kernel source from the file
   
size_t kernelSize;
   
char* cSourceString = readKernelSource("oclkernels.cl", &kernelSize);


cl_program program = clCreateProgramWithSource(context, 1, (const char**)&cSourceString, (const size_t*)&kernelSize, &err);


Here is the continuation of the translation with the code for the "readKernelSource" function:

The code for the "readKernelSource" function is:


//-------------------------------------------------------
char* readKernelSource(const char* filename, size_t* size) {
   
FILE* fp = fopen(filename, "r");
   
if (!fp) {
       
fprintf(stderr, "Failed to load kernel.\n");
       
exit(1);
   
}
   
fseek(fp, 0, SEEK_END);
   
*size = ftell(fp);
   
rewind(fp);
   
char* source = (char*)malloc(*size + 1);
   
fread(source, 1, *size, fp);
   
source[*size] = '\0';
   
fclose(fp);
   
return source;

}

//------------------------------------------------



To build the program, you need to add the OpenCL headers: #include <CL/cl.h> and the library "openCL.lib". These files can be found by downloading one of the OpenCL projects from Nvidia, for example, "oclVectorAdd.zip" from this link: " https://developer.nvidia.com/opencl"

To build the program, you also need to add the headers and libraries associated with "clFFT". The "clFFT" code can be obtained from GitHub: https://github.com/clMathLibraries/clFFT. The useful headers are located on GitHub in the subdirectory "clFFT-master\src\include". The libraries can be compiled from the "CMakeLists.txt" file using CMake or CLion. I performed this compilation by selecting the Microsoft compiler from Visual Studio 2019 in CMake or CLion. The necessary libraries for compiling ADDA_OCL with Visual Studio 2019 are "clFFT.lib" and "StatTimer.lib" as well as the DLLs "clFFT.dll" and "StatTimer.dll".

Best Regards

Michel Gross




Maxim Yurkin

unread,
May 30, 2024, 8:11:17 AM5/30/24
to adda-d...@googlegroups.com, gross...@gmail.com
Dear Michel,

That's really great! Thank you very much for putting so much efforts into compiling ADDA and (importantly!) documenting the process.

I hope you don't mind continuing the discussion about it. The overall goal is both to make the compilation as simple as possible and to potentially update the main ADDA source (so it will not affect the GCC compilation, but help with Visual Studio compilation).

First of all, I would like to bring your attention to file file `src/iw_compile.bat` that struggles with the same issues that you described (see also a brief list at https://github.com/adda-team/adda/issues/114#issuecomment-791227367 ), but adopts a bit different approach from the start. It keeps as much as possible in the console instead of setting a project in Visual Studio. Moreover, it was tested in 2021, it requires at least an update with respect to new Fortran sources, adding:
-Dbjndd_=BJNDD
to the line

Unfortunately, I do not have Visual Studio installed at the moment. So it would be great if you can test this script (or just tell me if it suits your original goal). Maybe, you can also update it to incorporate other compilation modes (contributions are always welcome).

Next, I am a surprised by the problem with `_isatty`. The Microsoft reference specifies that it should be available in <io.h> - https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/isatty?view=msvc-160 . While the particular implementation may be through sub-inclusion of <corecrt_io.h> - see, e.g., https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/ucrt/io.h - it still should be sufficient to include only <io.h>. The issue can, however, be with the specific <io.h> used (a combination of Intel compile with Visual Studio may have a few of them). I understand, that my request is not very specific, but please test it and provide more details (if you can).

Concerning the DLLs for Fortran sources - that seems to be a convenient option. Do you know if the lines that you added to Fortran sources affect standard ADDA compilation? I guess, gcc will just ignore them as comments. However, what if one uses Intel compiler on Unix with standard ADDA makefile? Does this lines have effect only if compiler is specifically building a DLL? Also, if this is used, it may probably be combined with alias attribute - see e.g. https://community.intel.com/t5/Intel-Fortran-Compiler/dllimport-directive-to-remove-the-underscore-prefix/m-p/1071559 (but it describes the "reverse" name change). Then no changes to the C code (or extra defines) will be needed. I am not sure if this alias will work for standard compilation into .obj file as well (as used in `src/iw_compile.bat`).

Concerning the reading of `oclkernels.cl`, your function seems to be similar to the code at:
So far, I see two differences. First, the order of arguments in `fread` is different, but they seem to be equivalent unless some error occurs. Second, you specifically initialize the last symbol to zero, which is definitely a good idea. I am now wondering, how the ADDA code worked previously. It may be that other combinations of OS and compiler more often feeds `malloc` with zero-allocated memory (for security or whatever reasons). So can you please try if adding the line
    cSourceString[sourceStrSize]='\0';
after fread(...); will solve your original problem with compilation?

Finally, we have recently updated instructions at https://github.com/adda-team/adda/wiki/InstallingMinGW , some of it may be relevant here.

Maxim.

P.S. This answer has been forwarded to your e-mail address for your convenience. However, if you want to continue the discussion please reply to the group's e-mail. You are also advised to check the corresponding discussion thread at http://groups.google.com/group/adda-discuss and/or subscribe to it to receive automatic notifications, since other answers/comments will not be necessarily forwarded to your e-mail.
--
You received this message because you are subscribed to the Google Groups "ADDA questions and answers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to adda-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/adda-discuss/CAHAMbgAhN5%2BKVxHEbS0c09hX%2BvCviBCYa%2BDv6YquHJ-ojwA06A%40mail.gmail.com.


Reply all
Reply to author
Forward
0 new messages