I am using Hybridizer to total a FloatResidentArray and I am not able to return the calculated total to the device (or host) because of the need for a ref statement in the final AtomicExpr.apply statement. Consider the following code which is based on the GenericReduce example provided by Altimesh. The code takes a device resident array a, of float of length N and calculates the total – this value is placed in 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);
}
}
The above code does not compile because you cannot pass a float[] and a FloatResidentArray in the same parameter list.
If total is defined as a FloatResidentArray itself, then the compiler will not allow the ref keyword to be used in the final line of code.
If I simply pass a float, then the returned variable is not updated with the total.
If I pass a ref float - then the program throws a runtime error at the point where the HybRunner wraps the above code to create the dynamic – the error message is
Value types by reference are not supported
How do I return the total? –either to Device or Host memory – both are acceptable.
