Переменные 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 я не могу этого сделать... как я могу это сделать??
- Объявите постоянную переменную в моем файле *.cu
- Установите значение (массив) из моего *.cs файла в эту константу
- Используйте значение из константы 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.