2016-10-11 3 views
5

Я использую Clion для разработки программы cuda. Выделение кода отлично работает, когда расширение является .h. Однако, когда он изменен на .cuh, Clion просто рассматривает новый файл как обычный текстовый файл, и я не смог включить выделение кода. Я понимаю, что полный инструментарий Cuda не может быть и речи, поэтому я не буду надеяться, что Clion проанализирует высказывания, подобные mykernel. < < < 1024, 100 >>>. Тем не менее, я буду более чем доволен, если он сможет проанализировать файл так же, как разбор обычного файла header/cpp.Включить индексирование кода Cuda в Clion

Большое спасибо

ответ

3

правой кнопкой мыши файл в окне инструментов проекта -> Ассоциированный с типом файла -> C++

Однако Clion не поддерживает технологию CUDA официально в настоящее время, он не может разобрать синтаксис Cuda.

+0

Решила проблему! Спасибо –

+0

У меня такая же проблема, но решение не работает. Я использую Clion 2016.2.2 на Ubuntu 16.04. Какую ОС вы используете? – GerryR

+1

Нашли ошибку, просто убедитесь, что файл с 'main' является' .cpp'. – GerryR

7

Прежде всего, убедитесь, что вы указываете CLION для обработки файлов .cu и .cuh как C++ с помощью меню настроек File Types.

CLion не может анализировать языковые расширения CUDA, но он обеспечивает макрос препроцессора, который определяется только тогда, когда clion анализирует код. Вы можете использовать это, чтобы реализовать почти полную поддержку CUDA самостоятельно.

Большая проблема в том, что анализатор CLion является откос по ключевым словам, как __host__ или __device__, заставляя его не делать то, что в противном случае знает, как это сделать: Fail

CLion не понял Dtype в этом примере , потому что материал CUDA путал его разбор.

Самое минимальное решение этой проблемы, чтобы дать clion препроцессора макросы игнорировать новые ключевые слова, зафиксировав худший из разбитости:

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

Это фиксирует вышеприведенный пример:

Yay!

Однако функции CUDA, такие как __syncthreads, __popc, по-прежнему не будут индексироваться. Так будет CUDA встроены, как threadIdx. Один из вариантов заключается в предоставлении бесконечных макросов препроцессора (или даже описаний структур) для них, но это уродливо и жертвует безопасностью типа.

Если вы используете интерфейс Clang CUDA, вы можете сделать лучше. Clang реализует неявно определенные встроенные CUDA, определяя их в заголовках, которые затем включаются при компиляции вашего кода. Они предоставляют определения таких вещей, как threadIdx. Делая вид, что препроцессор в CUDA компилятора и в том числе device_functions.h, мы можем получить __popc и друзей, чтобы работать, тоже:

#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__ 

Это поможет вам идеальный индексирование практически всего кода CUDA. CLion даже изящно справляется с синтаксисом <<<...>>>. Это ставит маленькую красную линию под одного символа на каждом конце блока запуска, но в противном случае рассматривает его как функцию вызова - который прекрасно:

Launch

+0

Если вы используете [cuda-api-wrappers] (https://github.com/eyalroz/cuda-api-wrappers), вам даже не нужно использовать эти раздражающие шевроны (примечание: self-plug.) – einpoklum

+0

Я действительно как и шевроны. Разделение параметров конфигурации запуска от параметров ядра довольно изящно. Ядра часто имеют большое количество позиционных аргументов, добавление еще четырех раздражает: D –

3

если вы хотите clion разобрать все ваши .CU файлы как.каст или любой другой поддерживаемый тип файла, вы можете сделать это:

  1. Перейти в меню Файл -> Настройки -> Редактор -> Типы файлов
  2. Выберите тип файла, который вы хотите, чтобы быть разобрано как в первом столбце (.cpp)
  3. Нажмите плюс знак второго столбца и написать * .cu

  4. Нажмите примениться и clion будет разбирать все .CU файлы, как это было тип файла, который указан в верхней колонке (.cpp)

вы можете увидеть дополнительную документацию here

+0

Это помогло мне понять, не знаю, как черта «окна инструментов проекта» находится в верхнем ответе. – snb

+0

Спасибо, что сообщили мне: с удовольствием помогите – Glacier11

7

Спасибо! Я добавил еще «поддельное» заявление, чтобы позволить CLion лучше разобрать 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 
+2

Вам нужно уточнить свой ответ, чтобы описать, что вы имеете в виду именно «расширенный». – Masoud

+1

Как вы это делаете? –

+0

Возможно, просто добавив фрагмент кода в C++ код или создание заголовка, который не строится за пределами IDE (см. JETBRAINS_IDE) define –

3

Я дополненной this answer с использованием методы найденной в this answer, чтобы обеспечить более полный синтаксический анализ макро, теперь вы можете иметь .x, .y и .z корректно работайте с проблемой, и используйте сетку dim. В дополнение к этому я обновил список, чтобы включить большинство свойств и значений, найденных в CUDA 8.0 documentation guide. Обратите внимание, что это должно иметь полную совместимость с C++ и, возможно, C. Это не имеет всех функций, учитываемых (недостающие атомистики, математические функции (просто включите math.h для большинства), текстуру, поверхность, время, warp votie и shuffle, утверждение, запуск границы, и функция видео)

#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 
+0

Вы могли бы найти [ мой пересмотренный подход] (https://stackoverflow.com/a/42288429/2283319) - общее решение, которое позволяет избежать переопределения юниверса самостоятельно: D –

+0

@ChrisKitching Wow, если использует этот компилятор, который определенно будет лучший подход. Еще один тик в поле для использования Clang over GCC. К сожалению, я уже поддержал ваш ответ b потому что я даже разместил свой. Похоже, что он легко связывается с синтаксисом встроенного редактирования, поскольку я полагаю, что Clion и почти все C++ IDE используют Clang для выполнения проверки ошибок компиляции. Я думаю, что Jetbrains может реализовать это в среде IDE довольно легко, даже если это только плагин. – snb

0

Я обнаружил, что clion кажется закодировать индексирование все строить цели, а не только цели, которую вы выбрали, чтобы построить. Моя стратегия заключалась в том, чтобы сделать .cpp символические ссылки из моих .cu-файлов и создать дочернюю цель clion/cmake C++ build (только для индексирования), которая ссылается на эти .cpp-ссылки. Этот подход, похоже, работает над небольшими cuda/thrust C++ 11 проектами в клионе 2017.3.3 в Unbuntu 16.04.3.

Я делаю это:

  • зарегистрировать .CU/CUH файлы с clion, как и в других ответах
  • добавить Cuda/clion макросъемку вуд в мой .CU файлы, как и в других ответы (позиция вуду может быть важна, но я еще не сталкивался с какими-либо проблемами).
  • Сделайте символические ссылки .cpp/.hpp на свои .cu/.cuh файлы в каталоге проектов.
  • Сделайте новая папка с единственным файлом с именем clionShadow/CMakeLists.txt, который содержит:
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}) 
  • добавить зависимость к clionShadow/CMakeLists.txt в конце основного CMakeLists.txt с линией, как это:
add_subdirectory(clionShadow) 

Теперь, clion анализирует и индексирует индексы файлов .cu через «.cpp-файлы».

Помните, что цель cudaNoBuild не предназначена для построения - она ​​будет использовать инструментарий C++, который не будет работать. Если вы вдруг получаете ошибки компиляции, проверяйте целевые настройки сборки clion - я заметил, что она иногда смешивает и сопоставляет текущие настройки сборки между проектами. В этом случае перейдите в диалог Edit_Configurations в меню «Выполнить» и убедитесь, что клион не изменил target_executable с целью cudaNoBuild.

Редактировать: Gah! После восстановления кэша CMake и ide после обновления до версии clion 2017.3.3 все работает не так, как раньше. Индексирование работает только для файлов .cpp, а точки останова работают только на .cu-файлы.