Как настроить мой код/VS10 для распознавания вызовов функций CUDA в файлах .c?

По сути, у меня есть компилятор, компилирующий мои файлы .cu, и у меня (я думаю) полная работа с этими файлами .cu, но когда я пытаюсь их вызвать (kernel<<<1,1>>>(void)), компилятор регистрирует синтаксические ошибки из-за синтаксиса CUDA. Кроме того, такие вызовы, как cudaMalloc, не работают в файлах c.

Вот три очень коротких файла, так что я могу сказать вам, где ошибка.

//kernel.cu    
#include "kernel.h"
#include <cuda.h>
#include <cuda_runtime_api.h>

__global__ int kernel(void){     
    return 5;
}

и

//kernel.h
#ifndef _KERNEL_h_
#define _KERNEL_h_

extern "C" int kernel(void);

#endif

и

//main.c
#include "kernel.h"
#include <cuda.h>
#include <cuda_runtime_api.h>

int main() {
   int* device_a;

   cudaMalloc( (void**)&device_a, sizeof(int) );

   kernel<<<1,1>>>();
}

Я получил заголовочный файл из некоторых примеров SDK. Кроме того, у меня есть конфигурация сборки с CUDA 4.2, поэтому файл .cu компилируется. Если я сделал какие-либо случайные синтаксические ошибки, то это потому, что я упростил его для публикации, а не потому, что он действительно есть в исходнике, хотя, пожалуйста, укажите это на всякий случай.

kernel.cu компилируется нормально.

В kernel.h есть ошибка: «ошибка C2059: синтаксическая ошибка:« строка »» в строке «extern ...». (Может быть, это потому, что я взял это из примера на С++?)

main.c имеет ошибку: «ошибка C2065:« ядро ​​»: необъявленный идентификатор»

и: "ошибка C2059: синтаксическая ошибка: '‹'"

но когда я комментирую вызов ядра, так что это просто cudaMalloc, я получаю: «ошибка LNK2019: неразрешенный внешний символ _cudaMalloc@8, на который ссылается функция _main»

и: "фатальная ошибка LNK1120: 1 неразрешенный внешний"

Это что-то с Visual Studio 2010 или что-то, что я не включаю? Из примеров SDK я не могу сказать, что я делаю неправильно, кроме того, они нашли способ, я думаю, не использовать тройную скобку (CTRL + F не находит). Любая помощь приветствуется. Заранее спасибо!

РЕДАКТИРОВАТЬ: посмотрев еще несколько примеров, они прекрасно используют синтаксис тройной скобки.

РЕДАКТИРОВАТЬ: Для тех, кто использует это как ссылку, функции __global__ могут возвращать только void. Если вы попытаетесь вернуть что-то еще, как это сделал я, вы получите ошибки компилятора.


person Eric Thoma    schedule 04.06.2012    source источник
comment
Как вам удалось успешно скомпилировать и запустить ядро, не возвращающее пустоту?   -  person geek    schedule 05.06.2012
comment
Я этого не сделал. Это был еще один недостаток, который я обнаружил позже. Однако он регистрирует действительно четкую ошибку компилятора.   -  person Eric Thoma    schedule 06.06.2012


Ответы (1)


  1. Поместите функции, которые вызывают ядро ​​CUDA, в файлы .cu.

  2. Настройте VS2010 для компиляции файлов CU с помощью компилятора CUDA, а не встроенного (используйте файлы правил CUDA (Cuda.props, Cuda.xml, Cuda.targets), расположенные в CUDA SDK).

  3. Я рекомендую размещать ядра в файлах с другим расширением (например, в файлах .curnel), чтобы они не компилировались напрямую (только при вызове).

  4. Я рекомендую поместить объявление функций, которые вызывают ядра CUDA, в файлы .cuh.

person Danny Varod    schedule 04.06.2012
comment
Результаты поиска выдают это руководство (которое я не читал, поэтому не несу ответственности за его правильность): ademiller.com/blogs/tech/2010/08/ - person Danny Varod; 04.06.2012
comment
Думаю, у меня есть конфигурация сборки для компиляции файлов .cu с помощью компилятора CUDA. Я поместил в файл .cu функцию, которая вызывает ядро, но эта функция по-прежнему содержит синтаксические ошибки в скобках. Мне также кажется, что файлы .cu и .c не знают друг друга, потому что даже когда файл .cu компилируется, основная функция не может вызывать простые функции c внутри. - person Eric Thoma; 04.06.2012
comment
Файлы .cu и .c должны видеть только файлы .cuh и .h, на которые они ссылаются в разделе include. Линкер соединяет их. Добавьте #ifdef CUDACC (не помню точный синтаксис — проверьте SDK) над каждым файлом .cu, чтобы убедиться, что определения компиляции верны. - person Danny Varod; 04.06.2012
comment
@EricThoma: Вы не забыли создать файл заголовка для функций в файле .cu и #include его в файле .c? - person Roger Dahl; 05.06.2012
comment
@EricThoma: Ре. синтаксические ошибки, не беспокойтесь о них, пока файл компилируется. VC++ проверяет файл на наличие синтаксических ошибок, как если бы это был файл .c. Вы можете оставить все как есть, но если вы хотите это исправить: ademiller.com/blogs/tech/2010/10/ - person Roger Dahl; 05.06.2012
comment
@DannyVarod Теперь я заставил CUDA работать с файлами C, и синтаксис угловых скобок работает. Единственная проблема заключается в том, что моя функция C call(), которая находится в файле cu и вызывает ядро, не может быть вызвана из main. У меня есть прототип для вызова в kernel.h, который включен в main. Ошибка: ошибка LNK2019: неразрешенный вызов внешнего символа, указанный в функции main. По сути, main видит прототип, но, как мне кажется, не видит реальной функции. Любой совет? Большое спасибо, вы очень помогли. - person Eric Thoma; 05.06.2012
comment
@EricThoma: поместите включение в фигурные скобки extern "C" {}. - person Roger Dahl; 05.06.2012
comment
@Roger Dahl Вау, большое спасибо. Вы не представляете, сколько разочарований это спасло меня. Желаю вам получить за это несколько очков stackoverflow! - person Eric Thoma; 05.06.2012
comment
@EricThoma: SO баллы - это просто спасибо в числовой форме. Ваш письменный очень ценится. Получайте удовольствие от своего проекта CUDA. :) - person Roger Dahl; 05.06.2012