ManagedCuda и постоянные переменные


Я использую 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 I кажется, я не в состоянии этого сделать... как я могу это сделать??

  1. объявите постоянную переменную в моем файле*. cu
  2. задайте значение (массив) из my *.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 2

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 в области extern "C", имейте в виду, что имена искажаются. В этом случае вы можете посмотреть точное искаженное имя в коде PTX.