Question

Suppose I have a Concurrency::array whose size I only know at run-time, and that size may be zero:

using namespace Conurrency;
array<int> myArray (datasource); // can't do this if datasource is zero-sized!
parallel_for_each(someExtent,[&](index<1> idx) restrict(amp)
{
  // if the size of myArray is 0, I won't use it!
}

On the host this problem is trivial; you simply declare a zero-sized vector and any range-based loop will simply ignore it. In C++ AMP, you'd have to design a separate kernel function for each array that might be null-sized... Surely there's a better way, why can't we just have zero-sized arrays in the first place?

How do programmers avoid this sort of problem?

I am currently avoiding it by doing the following, of which I'm not proud:

using namespace Conurrency;
if (datasource.size() == 0) datasource.push_back(0); // assuming datasource is a vector
array<int> myArray (datasource); // can't do this if datasource is zero-sized!
parallel_for_each(someExtent,[&](index<1> idx) restrict(amp)
{
  // if the size of myArray is 0, I won't use it!
}
Was it helpful?

Solution

The short answer is that you cannot have a zero sized array. Nor can you have an extent with a length of zero for any of its ranks. For better or worse that's just the way it is. C++ AMP assumes that any work passed to it is real work. Remember on the CPU there is no overhead for having a zero length loop or a zero length array. This may not be the case on the GPU, there is still a potential overhead for declaring the array on the accelerator and passing a kernel to the GPU via a DMA buffer. There may also be an underlying limitation in DirectX 11 (I've not had time to look).

In this case (unless I'm misunderstanding the problem) work is being done but some of the input data (myArray) may be zero length, but someExtent is non-zero.

If in fact someExtent is also zero then the simplest solution would simply be to wrap the code which calls the parallel_for_each in a conditional statement that skips the call entirely for zero values.

If someExtent is always non-zero but you need to pass in a zero length myArray then I'd suggest adding one to the length of myArray and simply accounting for that in your calculation.

In either case I think this works around the zero length array issue. If it doesn't then please provide more details.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top