How to use Intel C/C++ compiler to compile CUDA8.0 , or nvcc? [duplicate] - windows

In the project properties page of CUDA project in visual studio, there seems to be the option to custom the host compiler. But after I selected the intel C++ compiler, the -ccbin option still points to the cl.exe.
selecting intel C++ compiler as the platform toolset
the -ccbin option still points to cl.exe
I do understand that under windows environment, the default host compiler for CUDA project is cl.exe and the following posts confirmed that cl.exe was the only option on windwos. But these were quite some time ago, I'd like to ask again if this is still the case or we use a different host compiler now?
Intel C++ Composer and CUDA
Specify compiler NVCC uses to compile host-code

It's still the case. The only supported environments are listed in the installation guide for windows. The intel compiler is not listed.
By comparison, the corresponding section of the linux installation guide shows that a certain version of the intel compiler (ICC) is supported for the host compiler.
In the future, you should be able to refer to the corresponding documents published with newer CUDA toolkits to determine compiler support.

I often find myself using Intel C++ together with CUDA for fluid simulations, and I may be able to help if you are still interested in an answer.
You have not specified which version of Visual Studio you are referring to, but I imply that you are talking about Visual Studio Professional/Enterprise or any of that line of fully featured IDEs.
While I haven't extensively used any of those, there is a way of using Intel C++ (and by extension, any compiler) with CUDA, in Visual Studio Code. If you decide to go this route, and since you mentioned Windows, here is the procedure:
To make things simple, download the C++ tutorial build from here. If you want to make the build yourself, instructions are found on MSDN here.
After the download, you should have a build.bat file in the project directory. Open the file to edit it.
Replace everything inside the build.bat file as follows:
#echo off
call "Path\to\compilervars.bat" intel64
call "Path\to\vcvarsall.bat" x64
set compilerflags=/Zi /EHsc -I"%MKLROOT%"\include
set linkerflags= mkl_intel_ilp64.lib mkl_intel_thread.lib mkl_core.lib libiomp5md.lib
icl.exe /Foobj\helloworld /Fdobj\ -c -I. -I"%CUDA_PATH%"\include %compilerflags% helloworld.cpp /link %linkerflags%
"Path\to\nvcc.exe" -gencode=arch=compute_61,code=\"sm_61,compute_61\" -IPath\to\CUDA\include -G -maxrregcount=0 --machine 64 --compile -cudart static -g -DWIN64 -DNDEBUG -D_CONSOLE -Xcompiler "/EHsc /W3 /nologo /Od /FS /Fdobj\ /Zi /RTC1 /MD /MP" -o obj\hello2.obj "hello.cu"
icl.exe -o bin\hello.exe /Fdobj\ obj\hello2.obj obj\helloworld.obj "%CUDA_PATH%"\lib\x64\cudart.lib %compilerflags% /link %linkerflags%
In other words, we tell the build process to:
Look for the compilervars.bat file (found in Intel C++ compiler /bin folder) and set Intel specific macros and variables for the build process
Look for the vcvarsall.bat file (found in Visual C++ compiler /VC folder) and set Visual C++ specific macros and variables for the build process
Set the Compiler and Linker Flags for the Intel C++ compiler.
IMPORTANT: Call the Intel C++ compiler to generate an Obj file from all the non-CUDA (i.e. .cpp files of the project - In this case, helloworld.cpp) and also include the CUDA headers if you need them. Make sure no CUDA kernel calls (functions with <<< >>>) happen here.
THEN: Call the CUDA compiler to generate an Obj file from all the CUDA files (i.e. the .cu extensions - In this case, hello.cu), in this case, I call the Obj file hello2.obj (I explicitly renamed it to show you how to do that).
FINALLY Call the C++ Compiler to generate the executable file by mentioning both Obj files as well as the cudart library for static linking.
Note that CUDA still needs VC++ so we allow it to access VC++ for only the part where it compiles CUDA files (which is why we had to initialize vcvarsall.bat), and stick to Intel C++ for the rest.

Related

linking boost on Windows asks for versioned lib

We have a large cmake based C++ project for Linux where we build boost ourselves via cmake exernal project.
The project used to build also on Windows for the classical Intel compiler. But I have no access to this old running configuration.
I use Intel oneAPI 2023.0 with LLVM based icx compiler (clang 15?) and a current MSVC community edition.
I built boost (1.81.0) without a target (as I still struggle with openAPI target) with --layout=system, hence lib names like libboost_atomic.a
In our C++ we do not let CMake search for boost but add the boost libs via target_link_libraries().
When I compile our application with icx I get a link error
Linking CXX executable ....\bin\cfs.exe LINK: command
"C:\PROGRA~2\Intel\oneAPI\compiler\latest\windows\bin\icx.exe /nologo
#CMakeFiles\cfs.dir\objects1 /Qoption,link, /machine:x64
/INCREMENTAL:NO /Qoption,link,/subsystem:console -Qiopenmp
/Qoption,link,/LIBPATH:C:\PROGRA~2\Intel\oneAPI\compile
r\latest\windows\bin\intel64\ifort.exe
/Qoption,link,/LIBPATH:C:\Users\fabia\code\master\release_icx\lib
[....] ....\lib\libboost_log_setup.lib
....\lib\libboost_serialization.lib [.....] /link
/out:....\bin\cfs.exe /implib:. ...\bin\cfs.lib
/pdb:C:\Users\fabia\code\master\release_icx\bin\cfs.pdb /version:0.0
/MANIFEST /MANIFESTFILE:....\bin\cfs.exe .manifest"
I get
fatal error LNK1104: file
"libboost_serialization-clangw16-mt-x64-1_81.lib" not found.
I have no idea where the string clangw16-mt-x64-1_81 comes from.
You can link the libraries present in the boost library path to your project either from the Command Prompt or within the Visual Studio IDE. Please refer to the below link for more details.
https://www.boost.org/doc/libs/1_81_0/more/getting_started/windows.html
If you do not find any binaries, you can add the macro BOOST_ALL_NO_LIB which tells the config system not to automatically select which libraries to link. Please refer to the below link for more details.
https://www.boost.org/doc/libs/1_81_0/libs/config/doc/html/index.html
Or
You can use the target Boost::disable_autolinking to disable automatic linking. Please refer to the below link for more details.
https://cmake.org/cmake/help/latest/module/FindBoost.html

Building ARM64 ASM in Visual Studio with CMake

I'm working on a cross-platform project which has some hand-written assembly to optimize performance for various CPU architectures. I'm converting this project to CMake from a proprietary build system, starting with compiling using Visual Studio on Windows. For x86 and AMD64, I've been able to assemble and link everything just fine, but I can't get it to work on ARM64 (or presumably ARM32, though I haven't tried that yet).
I'm including the ASM files in my sources as follows:
if(CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64")
list(APPEND SOURCES
amd64/aesasm.asm
...)
set_source_files_properties(
amd64/aesasm.asm
...
PROPERTY LANGUAGE ASM_MASM)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "X86")
# ...
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64")
list(APPEND SOURCES
arm64/fdef_asm.asm
...)
set_source_files_properties(
arm64/fdef_asm.asm
...
PROPERTY LANGUAGE ASM_MASM)
Then in my top-level CMakeLists.txt, I enable MASM using enable_language(ASM_MASM). For x86 and AMD64, CMake automatically finds ml/ml64.exe, configures the Visual Studio project correctly, and everything works.
But for ARM64, if I try the same thing, I get this error from Visual Studio when trying to build: MSB3721: The command "echo MASM not supported on this platform. As far as I can tell, this is because Visual Studio considers ARM assembly to be a different dialect, "MARMASM", with a different executable name for the assembler (armasm/armasm64.exe).
I tried setting enable_language(ASM_MARMASM) in my ARM64 toolchain file, but CMake does not recognize this as an ASM dialect, and gives me this error:
CMake Error: Could not find cmake module file: CMakeDetermineASM_MARMASMCompiler.cmake
CMake Error: Could not find cmake module file: F:/os/src/symcrypt/bin/CMakeFiles/3.15.3/CMakeASM_MARMASMCompiler.cmake
CMake Error at CMakeLists.txt:49 (enable_language):
No CMAKE_ASM_MARMASM_COMPILER could be found.
I also tried manually setting the assembler:
get_filename_component(VS_TOOLS_DIRECTORY ${CMAKE_LINKER} DIRECTORY)
find_file(ARM64_COMPILER "armasm64.exe" HINTS ${VS_TOOLS_DIRECTORY})
set(CMAKE_ASM_MARMASM_COMPILER ${ARM64_COMPILER})
enable_language(ASM_MARMASM)
message(STATUS "Manually set assembler to ${CMAKE_ASM_MARMASM_COMPILER}")
But this does not work either; I still get an error that No CMAKE_ASM_MARMASM_COMPILER could be found.
How can I include ARM/ARM64 assembly in my project?
Looks like CMake (still) does not have support for this. I found some bits in the .NET source code to work around it:
https://github.com/dotnet/runtime/blob/f8f63b1fde85119c925313caa475d9936297b463/eng/native/functions.cmake#L173-L207
and
https://github.com/dotnet/runtime/blob/f8f63b1fde85119c925313caa475d9936297b463/eng/native/configurecompiler.cmake#L611-L626
edit: As reference, here's the commit for a project I had this requirement for: https://dyncall.org/pub/dyncall/dyncall/rev/451299d50c1a

How to specify Intel C++ compiler icl as host compiler of a CUDA project in Visual Studio

In the project properties page of CUDA project in visual studio, there seems to be the option to custom the host compiler. But after I selected the intel C++ compiler, the -ccbin option still points to the cl.exe.
selecting intel C++ compiler as the platform toolset
the -ccbin option still points to cl.exe
I do understand that under windows environment, the default host compiler for CUDA project is cl.exe and the following posts confirmed that cl.exe was the only option on windwos. But these were quite some time ago, I'd like to ask again if this is still the case or we use a different host compiler now?
Intel C++ Composer and CUDA
Specify compiler NVCC uses to compile host-code
It's still the case. The only supported environments are listed in the installation guide for windows. The intel compiler is not listed.
By comparison, the corresponding section of the linux installation guide shows that a certain version of the intel compiler (ICC) is supported for the host compiler.
In the future, you should be able to refer to the corresponding documents published with newer CUDA toolkits to determine compiler support.
I often find myself using Intel C++ together with CUDA for fluid simulations, and I may be able to help if you are still interested in an answer.
You have not specified which version of Visual Studio you are referring to, but I imply that you are talking about Visual Studio Professional/Enterprise or any of that line of fully featured IDEs.
While I haven't extensively used any of those, there is a way of using Intel C++ (and by extension, any compiler) with CUDA, in Visual Studio Code. If you decide to go this route, and since you mentioned Windows, here is the procedure:
To make things simple, download the C++ tutorial build from here. If you want to make the build yourself, instructions are found on MSDN here.
After the download, you should have a build.bat file in the project directory. Open the file to edit it.
Replace everything inside the build.bat file as follows:
#echo off
call "Path\to\compilervars.bat" intel64
call "Path\to\vcvarsall.bat" x64
set compilerflags=/Zi /EHsc -I"%MKLROOT%"\include
set linkerflags= mkl_intel_ilp64.lib mkl_intel_thread.lib mkl_core.lib libiomp5md.lib
icl.exe /Foobj\helloworld /Fdobj\ -c -I. -I"%CUDA_PATH%"\include %compilerflags% helloworld.cpp /link %linkerflags%
"Path\to\nvcc.exe" -gencode=arch=compute_61,code=\"sm_61,compute_61\" -IPath\to\CUDA\include -G -maxrregcount=0 --machine 64 --compile -cudart static -g -DWIN64 -DNDEBUG -D_CONSOLE -Xcompiler "/EHsc /W3 /nologo /Od /FS /Fdobj\ /Zi /RTC1 /MD /MP" -o obj\hello2.obj "hello.cu"
icl.exe -o bin\hello.exe /Fdobj\ obj\hello2.obj obj\helloworld.obj "%CUDA_PATH%"\lib\x64\cudart.lib %compilerflags% /link %linkerflags%
In other words, we tell the build process to:
Look for the compilervars.bat file (found in Intel C++ compiler /bin folder) and set Intel specific macros and variables for the build process
Look for the vcvarsall.bat file (found in Visual C++ compiler /VC folder) and set Visual C++ specific macros and variables for the build process
Set the Compiler and Linker Flags for the Intel C++ compiler.
IMPORTANT: Call the Intel C++ compiler to generate an Obj file from all the non-CUDA (i.e. .cpp files of the project - In this case, helloworld.cpp) and also include the CUDA headers if you need them. Make sure no CUDA kernel calls (functions with <<< >>>) happen here.
THEN: Call the CUDA compiler to generate an Obj file from all the CUDA files (i.e. the .cu extensions - In this case, hello.cu), in this case, I call the Obj file hello2.obj (I explicitly renamed it to show you how to do that).
FINALLY Call the C++ Compiler to generate the executable file by mentioning both Obj files as well as the cudart library for static linking.
Note that CUDA still needs VC++ so we allow it to access VC++ for only the part where it compiles CUDA files (which is why we had to initialize vcvarsall.bat), and stick to Intel C++ for the rest.

Specify compiler NVCC uses to compile host-code

When running nvcc, it always uses the Visual C++ compiler (cl.exe). How can I make it use the GCC compiler?
Setting the CC environment-variable to gcc didn't fix it. I also couldn't find any option for this in the executeables help-output.
On Windows, NVCC only supports the Visual C++ compiler (cl.exe) for host compilation.
You can of course compile .cpp (non-CUDA) code using GCC and link the objects with objects generated by nvcc.

Getting started with openMP. install on windows

I want to write parallel program in C++ using OpenMP, so I am getting started with OpenMP.
On the other words I am a beginner and I need good OpenMP guide telling how to install it.
Does someone know how to install OpenMP on Windows, then compile and run the program?
OpenMP is not something that you install. It comes with your compiler. You just need a decent compiler that supports OpenMP and you need to know how to enable OpenMP support since it is usually disabled by default.
The standard compiler for Windows comes from Microsoft and it is the Microsoft Visual C/C++ compiler from Visual Studio. Unfortunately its OpenMP support is a bit outdated - even the latest and greatest Visual Studio only supports OpenMP 2.0 (an outdated standard version from 2002). See here for more information on how to use OpenMP in Visual Studio. There are other compilers available as well - both Intel C/C++ Compiler (commercial license required) and GCC (freely available) support newer OpenMP versions and other compilers are available too.
You can start learning OpenMP by visiting the OpenMP web site here. Also there is a great tutorial on OpenMP from Lawrence Livermore National Laboratory available here.
2020 Update: Microsoft now ships Clang for Windows with Visual Studio. Although it is a bit convoluted, one can (ab)use the Clang-cl toolset to produce working 32-bit OpenMP programs. A number of steps are necessary:
If not already installed, add Clang and Clang-cl using the Visual Studio 2019 Installer.
Set the project's platform toolset (project Properties -> General -> Platform Toolset) to "LLVM (clang-cl)".
Enable Clang OpenMP support by adding -Xclang -fopenmp to the compiler options in project Properties -> C/C++ -> All Options -> Additional Options.Important: make sure that OpenMP support is disabled before switching the platform toolset (this is the default for new C++ projects). It seems that VS remembers the setting and still passes /openmp even though the language configuration for Clang has no option for OpenMP. If clang-cl.exe throws error MSB8055 (unsupported /openmp option) during build, set the platform toolset back to "Visual Studio 2019 (vXXX)" and disable the OpenMP support in Properties -> C/C++ -> Language -> Open MP Support, then switch the platform toolset again to "LLVM (Clang-cl)".
Add libomp.lib to the additional libraries in project Properties -> Linker -> Input -> Additional Dependencies.
Add the path to libomp.lib to the linker search path by adding a new entry with value $(LLVMInstallDir)\lib in project Properties -> Linker -> General -> Additional Library Directories.
Add a post-build action that copies LLVM's libomp.dll to the project output directory (without this step, running the executable will fail unless libomp.dll is in the DLL search path). In project Properties -> Build Events -> Post-Build Event -> Command Line:
xcopy /y "$(LLVMInstallDir)\bin\libomp.dll" "$(SolutionDir)$(Configuration)"
Build and run the project.
Note: this is very much likely still unsupported by Microsoft and it only works for x86 projects since the LLVM libraries shipped with VS are 32-bit only.
So here is what I did to finally get OpenMP working on my Windows 10 PC:
Get MinGW - Download and grab what you need to get the basic gcc compiler and the g++ pakage (its really easy to do). You can always run g++ -v to make sure it is up and running
Run mingw-get upgrade --recursive "gcc<4.7.*" "gcc-g++<4.7.*" This is the "Fun" part. Because at this time there was no libgomp library supported in their 4.9.* version my gcc wasn't able to recognize <omp.h> the last support version was 4.7.2 so with this I finally was able to run my openMP
To compile run g++ -fopenmp myOpenMPFile.cpp -o myOpenMP and it will all work from there
gcc -fopenmp myOpenMPFile.cpp -o myOpenMP will also work for C code
I would like to share what I did to get OpenMP working on my Windows 10 PC (things have got even simpler in 2019)
I installed MinGW distribution from here with GCC 8.2.0 compiler. The maintainer of the distribution has already added winpthreads and OpenMP support to GCC.
I compiled my code with -fopenmp flag as follows: g++ -fopenmp main.cpp -o exec
Note: the MinGW distribution provides support for many useful libraries (such as Boost 1.69.0) and other utilities. I found it to be very useful.

Resources