Настройка VS Intellisense для вызовов ядра CUDA

Я только что начал программирование CUDA, и все идет неплохо, мои графические процессоры распознаются и все. Я частично создал Intellisense в Visual Studio, используя это чрезвычайно полезное руководство здесь: http://www.ademiller.com/blogs/tech/2010/10/visual-studio-2010-adding-intellisense-support-for-cuda-c/

и здесь: http://www.ademiller.com/blogs/tech/2011/05/visual-studio-2010-and-cuda-easier-with-rc2/

Однако Intellisense по-прежнему не отвечает на вызовы ядра следующим образом:

// KernelCall.cu
#include <iostream>
#include "cuda.h"
#include "cuda_runtime.h"
#include "device_launch_parameters.h"

__global__ void kernel(void){}

int main()
{
    kernel<<<1,1>>>();

    system("pause");
    return 0;
}

Ядро линии < < 1,1 → > () подчеркнуто красным цветом, в частности, одна стрелка слева от первой с сообщением об ошибке "Ошибка: ожидаемое и выражение". Однако, если я нахожусь над функцией, ее тип и параметры возврата отображаются правильно. Он все еще компилируется просто отлично, мне просто интересно, как избавиться от этой маленькой досады.

Ответы

Ответ 1

Visual Studio предоставляет IntelliSense для С++, трюк из блога ученого-исследователя в основном опирается на сходство CUDA-C на С++, не более того.

На языке С++ правильный анализ угловых скобок вызывает проблемы. У вас < меньше, чем для шаблонов, а << - как сдвиг, вспомните не так давно, когда нам пришлось помещать пробел между вложенными объявлениями шаблонов.

Итак, выясняется, что парень из NVIDIA, который придумал этот синтаксис, не был экспертом по языку и случайно выбрал наихудший возможный разделитель, а затем утроил его, ну, у вас будут проблемы. Удивительно, что Intellisense работает вообще, когда видит это.

Единственным способом, которым я знаю, чтобы получить полный IntelliSense в CUDA, является переход от API-интерфейса Runtime к API-интерфейсу драйвера. С++ - это просто С++, а CUDA все еще (вроде) С++, нет ошибки <<<>>> для синтаксического анализа языка, который должен работать.

Ответ 2

Ничего себе, много пыли на этой теме. Я придумал исправление макроса (ну, скорее, обходное решение...) для этого, я думал, что поделюсь:

// nvcc does not seem to like variadic macros, so we have to define
// one for each kernel parameter list:
#ifdef __CUDACC__
#define KERNEL_ARGS2(grid, block) <<< grid, block >>>
#define KERNEL_ARGS3(grid, block, sh_mem) <<< grid, block, sh_mem >>>
#define KERNEL_ARGS4(grid, block, sh_mem, stream) <<< grid, block, sh_mem, stream >>>
#else
#define KERNEL_ARGS2(grid, block)
#define KERNEL_ARGS3(grid, block, sh_mem)
#define KERNEL_ARGS4(grid, block, sh_mem, stream)
#end

// Now launch your kernel using the appropriate macro:
kernel KERNEL_ARGS2(dim3(nBlockCount), dim3(nThreadCount)) (param1); 

Я предпочитаю этот метод, потому что по какой-то причине я всегда теряю '< < в моем коде, но макрос получает некоторую помощь через раскраску синтаксиса:).

Ответ 3

Начиная с VS 2015 и CUDA 7, вы можете добавить эти два варианта перед любыми другими, если ваши файлы имеют расширение .cu:

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

Нет необходимости в MACROS или что-то еще. Впоследствии все будет работать отлично.