Переменные ManagedCuda и __constant__

Я использую ManagedCuda в C#, и у меня есть один вопрос, на который я не могу найти ответ... может быть, вы можете мне помочь. Я читал, что в C++ и CUDA вы можете объявить переменную (которая является массивом), например:

__constant__ double myVar[X]; (для хранения массива элементов X)

и затем позже используйте это, чтобы установить значение из кода хоста:

cudaMemcpyToSymbol(myVar, &arrayFromHost[0], sizeof(arrayFromHost) * numElements, 
                   size_t(0),cudaMemcpyHostToDevice);

так что теперь вы можете использовать что-то вроде:

__global__ void myFunction(double *res)
{
    *res = myVar[0] + 2.5;
}

используя значение, которое было установлено в myVar от хозяина...

но в ManagedCuda я не могу этого сделать... как я могу это сделать??

  1. Объявите постоянную переменную в моем файле *.cu
  2. Установите значение (массив) из моего *.cs файла в эту константу
  3. Используйте значение из константы 1. в функции в том же файле *.cu

(или __device__ переменная... я не знаю... это будет переменная, которая получит массив (с неизвестным количеством элементов) при первом запуске, и с тех пор функция будет ссылаться на свои значения, но эта переменная никогда не изменится)

Прямо сейчас я только объявляю CudaDeviceVariable и я больше не трогаю его, но в моем ядре мне всегда приходится отправлять DevicePointer, что, как мне кажется, усложняет понимание при чтении...

Прямо сейчас это выглядит примерно так:

myKernel.Run(staticData.DevicePointer, moreData.DevicePointer, 
             evenMoreData.DevicePointer, numberOfElementsWhichNeverChange,            
             moreStaticData.DevicePointer, myResults.DevicePointer)

Я хотел бы пропустить 3 параметра, которые имеют данные, которые никогда не меняются, и установить их в другой функции, например setData.Run(numElements, staticData, moreStaticData);
и использовать из констант или переменных устройства в других функциях в моем *.cu файле.

1 ответ

Решение

В myKernel есть метод SetConstantVariable(), который делает именно то, что вы хотите. Просто позвоните, прежде чем запускать ядро: в вашем файле *.cu:

extern "C" 
{
    __constant__ double myConstVarInCuda[5];
    __global__ void myFunction(double *res) 
    { 
        *res = myConstVarInCuda[0] + 2.5; 
    } 
}

В C#:

 double[] myVarInCS = new double[] { 1.0, 2.0, 3.0, 4.0, 5.0 };    
    myKernel.SetConstantVariable("myConstVarInCuda", myVarInCS);
    myKernel.Run(...);

Если вы не объявляете свой код Cuda в внешней области видимости "C", помните, что имена искажаются. В этом случае вы можете найти точное искаженное имя в коде PTX.

Другие вопросы по тегам