Я использую Hybridizer для суммирования FloatResidentArray, и я не могу вернуть рассчитанную сумму на устройство (или хост) из-за необходимости в операторе ref в заключительном операторе AtomicExpr.apply.
Рассмотрим следующий код, который основан на примере GenericReduce, предоставленном Altimesh.
Код принимает резидентный массив устройства a с плавающей запятой длины N и вычисляет сумму - это значение помещается в total [0] .
[Kernel]
public static void Total(FloatResidentArray a, int N, float[] total)
{
var cache = new SharedMemoryAllocator<float>().allocate(blockDim.x);
int tid = threadIdx.x + blockDim.x * blockIdx.x;
int cacheIndex = threadIdx.x;
float sum = 0f;
while (tid < N)
{
sum = sum + a[tid];
tid += blockDim.x * gridDim.x;
}
cache[cacheIndex] = sum;
CUDAIntrinsics.__syncthreads();
int i = blockDim.x / 2;
while (i != 0)
{
if (cacheIndex < i)
{
cache[cacheIndex] = cache[cacheIndex] + cache[cacheIndex + i];
}
CUDAIntrinsics.__syncthreads();
i >>= 1;
}
if (cacheIndex == 0)
{
AtomicExpr.apply(ref total[0], cache[0], (x, y) => x + y);
}
}
Приведенный выше код не компилируется, поскольку вы не можете передать float [] и FloatResidentArray в одном и том же списке параметров.
Если total определен как сам FloatResidentArray, то компилятор не позволит использовать ключевое слово ref в последней строке кода.
Если я просто передам число с плавающей запятой, возвращаемая переменная не будет обновлена с суммой.
Если я передам ref float - тогда программа выдаст ошибку времени выполнения в тот момент, когда HybRunner оборачивает приведенный выше код для создания динамического - сообщение об ошибке будет
Типы значений по ссылке не поддерживаются
Как мне вернуть сумму? - либо на устройство, либо на хост-память - оба приемлемы.