Enable Cuda Code Indexing in Clion

I use Clion to develop a cuda program. Code highlighting works great when the extension is .h. However, when it is changed to .cuh, Clion just treats the new file as a regular text file, and I could not enable code highlighting. I understand that the complete Cuda software chain is out of the question, so I won’t hope that Clion will parse expressions like mykernel <<1024, 100 β†’>. However, I will be more than satisfied if he can parse the file in the same way as parsing a regular / cpp header file.

Thank you very much

+5
source share
6 answers

Right-click file in the project tool window β†’ Associate with file type β†’ C ++

However, Clion does not officially support cuda; it cannot parse cuda syntax. A.

+3
source

First, make sure you specify CLION to handle .cu and .cuh as C ++ using the File Types settings menu.

CLion cannot parse CUDA language extensions, but it provides a preprocessor macro that is defined only when clion parses the code. You can use this to implement almost full CUDA support yourself.

Most of the problem is that the CLION parser is reset using keywords such as __host__ or __device__ , as a result of which it cannot do things that otherwise know how to do it: Fail

In this example, CLion did not understand Dtype because the CUDA stuff confused its parsing.

The smallest solution to this problem is to let the clion preprocessor macros ignore the new keywords, fixing the worst of the broken:

 #ifdef __JETBRAINS_IDE__ #define __host__ #define __device__ #define __shared__ #define __constant__ #define __global__ #endif 

This fixes the above example:

Yay

However, CUDA functions such as __syncthreads , __popc will still not be indexed. So it will be CUDA, like threadIdx . One option is to provide endless preprocessor macros (or even structure descriptions) for them, but it is ugly and sacrifices type safety.

If you use the Clang CUDA interface, you can do better. Clang implements implicitly defined inline CUDAs by defining them in headers, which are then included when compiling your code. They provide definitions of things like threadIdx . Pretending to be a CUDA compiler preprocessor and including device_functions.h , we can get __popc and friends to work too:

 #ifdef __JETBRAINS_IDE__ #define __host__ #define __device__ #define __shared__ #define __constant__ #define __global__ // This is slightly mental, but gets it to properly index device function calls like __popc and whatever. #define __CUDACC__ #include <device_functions.h> // These headers are all implicitly present when you compile CUDA with clang. Clion doesn't know that, so // we include them explicitly to make the indexer happy. Doing this when you actually build is, obviously, // a terrible idea :D #include <__clang_cuda_builtin_vars.h> #include <__clang_cuda_intrinsics.h> #include <__clang_cuda_math_forward_declares.h> #include <__clang_cuda_complex_builtins.h> #include <__clang_cuda_cmath.h> #endif // __JETBRAINS_IDE__ 

This will give you perfect indexing of almost all CUDA code. CLion even gracefully handles the syntax <<<...>>> . It places a small red line under one character at each end of the launch block, but otherwise considers it as a function call - this is completely normal:

Launch

+7
source

Thanks! I added more β€œfake” ads to allow CLION to better analyze CUDA:

 #ifdef __JETBRAINS_IDE__ #define __CUDACC__ 1 #define __host__ #define __device__ #define __global__ #define __forceinline__ #define __shared__ inline void __syncthreads() {} inline void __threadfence_block() {} template<class T> inline T __clz(const T val) { return val; } struct __cuda_fake_struct { int x; }; extern __cuda_fake_struct blockDim; extern __cuda_fake_struct threadIdx; extern __cuda_fake_struct blockIdx; #endif 
+7
source

if you want clion to parse all your .cu files like .cpp or any other supported file type, you can do this:

  • Go to File β†’ Settings β†’ Editor β†’ File Types
  • Select the type of file you want to analyze, as in the first column (.cpp)
  • Click the plus sign of the second column and write * .cu

  • Click apply, and clion will parse all your .cu files as it was the type of file you specified in the top column (.cpp)

you can see additional documentation here

+3
source

I expanded this answer using the method found in this answer to provide a more complete now you can have .x , .y and .z work correctly with the error and use the dim grid. In addition to this, I updated the list to include most of the built-in and values ​​found in the CUDA 8.0 Documentation Guide . Please note that this should be fully compatible with C ++ and possibly C. It does not have all the functions taken into account (missing atomistic, mathematical functions (just include math.h for most), texture, surface, time, warp votie and shuffle, statement, initial frames and video function)

 #ifdef __JETBRAINS_IDE__ #include "math.h" #define __CUDACC__ 1 #define __host__ #define __device__ #define __global__ #define __noinline__ #define __forceinline__ #define __shared__ #define __constant__ #define __managed__ #define __restrict__ // CUDA Synchronization inline void __syncthreads() {}; inline void __threadfence_block() {}; inline void __threadfence() {}; inline void __threadfence_system(); inline int __syncthreads_count(int predicate) {return predicate}; inline int __syncthreads_and(int predicate) {return predicate}; inline int __syncthreads_or(int predicate) {return predicate}; template<class T> inline T __clz(const T val) { return val; } template<class T> inline T __ldg(const T* address){return *address}; // CUDA TYPES typedef unsigned short uchar; typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; typedef unsigned long long ulonglong; typedef long long longlong; typedef struct uchar1{ uchar x; }uchar1; typedef struct uchar2{ uchar x; uchar y; }uchar2; typedef struct uchar3{ uchar x; uchar y; uchar z; }uchar3; typedef struct uchar4{ uchar x; uchar y; uchar z; uchar w; }uchar4; typedef struct char1{ char x; }char1; typedef struct char2{ char x; char y; }char2; typedef struct char3{ char x; char y; char z; }char3; typedef struct char4{ char x; char y; char z; char w; }char4; typedef struct ushort1{ ushort x; }ushort1; typedef struct ushort2{ ushort x; ushort y; }ushort2; typedef struct ushort3{ ushort x; ushort y; ushort z; }ushort3; typedef struct ushort4{ ushort x; ushort y; ushort z; ushort w; }ushort4; typedef struct short1{ short x; }short1; typedef struct short2{ short x; short y; }short2; typedef struct short3{ short x; short y; short z; }short3; typedef struct short4{ short x; short y; short z; short w; }short4; typedef struct uint1{ uint x; }uint1; typedef struct uint2{ uint x; uint y; }uint2; typedef struct uint3{ uint x; uint y; uint z; }uint3; typedef struct uint4{ uint x; uint y; uint z; uint w; }uint4; typedef struct int1{ int x; }int1; typedef struct int2{ int x; int y; }int2; typedef struct int3{ int x; int y; int z; }int3; typedef struct int4{ int x; int y; int z; int w; }int4; typedef struct ulong1{ ulong x; }ulong1; typedef struct ulong2{ ulong x; ulong y; }ulong2; typedef struct ulong3{ ulong x; ulong y; ulong z; }ulong3; typedef struct ulong4{ ulong x; ulong y; ulong z; ulong w; }ulong4; typedef struct long1{ long x; }long1; typedef struct long2{ long x; long y; }long2; typedef struct long3{ long x; long y; long z; }long3; typedef struct long4{ long x; long y; long z; long w; }long4; typedef struct ulonglong1{ ulonglong x; }ulonglong1; typedef struct ulonglong2{ ulonglong x; ulonglong y; }ulonglong2; typedef struct ulonglong3{ ulonglong x; ulonglong y; ulonglong z; }ulonglong3; typedef struct ulonglong4{ ulonglong x; ulonglong y; ulonglong z; ulonglong w; }ulonglong4; typedef struct longlong1{ longlong x; }longlong1; typedef struct longlong2{ longlong x; longlong y; }longlong2; typedef struct float1{ float x; }float1; typedef struct float2{ float x; float y; }float2; typedef struct float3{ float x; float y; float z; }float3; typedef struct float4{ float x; float y; float z; float w; }float4; typedef struct double1{ double x; }double1; typedef struct double2{ double x; double y; }double2; typedef uint3 dim3; extern dim3 gridDim; extern uint3 blockIdx; extern dim3 blockDim; extern uint3 threadIdx; extern int warpsize; #endif 
+3
source

I found that clion seems to encode all the assembly targets, not just the target that you chose to build. My strategy was to make .cpp symbolic links from my .cu files and create a clion / cmake C ++ build child target (for indexing only) that references these .cpp links. This approach seems to work on small cuda / thrust C ++ 11 projects in Klion 2017.3.3 on Unbuntu 16.04.3.

I'm doing it:

  • register wedge .cu / cuh files as in other answers
  • add the vudoo cuda / clion macro to my .cu files, as in other answers (voodoo position may be important, but I have not encountered any problems yet).
  • create .cpp / .hpp symbolic links for your .cu / .cuh files in the project directory
  • create a new folder with a single file named clionShadow / CMakeLists.txt, which contains:
 cmake_minimum_required(VERSION 3.9) project(cudaNoBuild) set(CMAKE_CXX_STANDARD 11) add_executable(cudaNoBuild ../yourcudacode.cpp ../yourcudacode.hpp) target_include_directories(cudaNoBuild PUBLIC ${CUDA_INCLUDE_DIRS}) 
  • add a dependency to clionShadow / CMakeLists.txt at the end of your main CMakeLists.txt with a line like this:
 add_subdirectory(clionShadow) 

Now clion parses and indexes .cu files through ".cpp files".

Remember that the goal of cudaNoBuild is not to build - it will use C ++ toolkit, which will not work. If you suddenly get compilation errors, check the target settings of the clion assembly - I noticed that it sometimes mixes and compares the current build settings between projects. In this case, go to the Edit_Configurations dialog in the Run menu and make sure that the client has not changed target_executable for the purpose of cudaNoBuild.

Edit: Ha! After recovering the cache of CMake and ide after upgrading to clion 2017.3.3, everything does not work as before. Indexing works only for .cpp files, and breakpoints work only for .cu files.

0
source

Source: https://habr.com/ru/post/1258036/


All Articles