Answered C++ AMP passing multidimensional arrays to array_view

  • Tuesday, April 10, 2012 9:40 AM
     
      Has Code

    Hi,

    I am just started with C++ AMP and was trying out some trivial examples to understand the working of C++ AMP. I was trying to pass a matrix(2D array) to array_view and landed up with errors "left of '.data' must have class/struct/union", "left of '.size' must have class/struct/union" and "container element type and array view type must match"

    int** temp=new int*[5];
    	array_view<int,2> a(5,2,temp);
    
    	parallel_for_each(
    		a.extent,
    		[=](index<2> idx)restrict(direct3d)
    	{
    		int row=idx[0];
    		int col=idx[1];
    
    		a[idx]=row*10+col;
    	}
    );

    Can you please tell me what is cause for this reason?

All Replies

  • Tuesday, April 10, 2012 11:52 AM
     
      Has Code

    Hi Sridutt, It looks like you are defining and using array_view "a" incorrectly.  Try this:

    #include <amp.h>
    #include <iostream>
    
    using namespace concurrency;
    
    int main()
    {
        int * temp = new int[10];
    
        array_view<int, 2> a(5, 2, temp);
    
        parallel_for_each(
            a.extent, [=](index<2> idx) restrict(amp)
        {
            int row=idx[0];
            int col=idx[1];
    
            a(row, col) = row*10+col;
        });
        a.synchronize();
        for (int i = 0; i < 10; ++i)
            std::cout << temp[i] << " ";
        std::cout << "\n";
        return 0;
    }
    

  • Tuesday, April 10, 2012 12:41 PM
     
      Has Code

    Hi Ken,

    Thanks alot for the inputs. But, what I have to do incase i have a 2 D array as below

    int** temp=new int*[5];

    how do i pass it to array_view.

    Also, can you please tell me what was wrong when I defined and used array_view "a"? I can see I used the restrict(direct3d) rather than restrict(amp). But apart from this, what went wrong?

  • Tuesday, April 10, 2012 3:18 PM
     
     Answered Has Code

    I may be mistaken, but it just doesn't seem possible for one to create an array of arrays. I've tried a lot of different possibilities, but the compiler doesn't like anything with pointers or array_views containing array_views: see line "2482" of the C++ AMP spec at http://download.microsoft.com/download/4/0/E/40EA02D8-23A7-4BD2-AD3A-0BFFFB640F28/CppAMPLanguageAndProgrammingModel.pdf  .  It is possible in CUDA to create these kinds of data structures (and in OpenCL with difficulty)--but, those languages have their own problems, too.  It's just easier to create one linear array on the host, then cast it to what you want.  Alternatively, you could create two data structures that overlay each other, one for the GPU, and the other for the CPU.

    Just a minor point...In your code, you define an array of an array of int's, but you only allocate the 1st dimension, not the second.  To do that, you need a for-loop that allocates an array of 2 int's:

        for (int i = 0; i < 5; ++i) temp[i] = new int[2];

    Without that initialization, your code wouldn't work even in non-C++ AMP code.

    In the kernel you could use "a[idx] = row*10+col;" no problem. I rewrote that, but didn't need to.  So, there really wasn't much wrong with what you had.  Your C++ AMP code works fine otherwise.

    Ken

  • Tuesday, April 10, 2012 9:15 PM
    Owner
     
     Answered

    Hi Sridutt,

    The problem with using "int **" as the input for an array_view is that it is not dense.  In your example,

        int** temp=new int*[5];

    what you have is an array of pointers to ints.  This is different than what "int temp[2][5]" gives you, which is a dense array of 2*5 integers, with no pointers inside the array.

    The array_view type must be bound to a dense type, because in the end it's just going to copy bits to and from the GPU; it won't chase pointers.  In order to use array_view (or C++ AMP in general), you'll have to represent your arrays in dense form.  Ken has offered one such solution, which is to use a single-dimensional array to hold the dense values, and then let array_view add 2-dimensionality.

    Hope that helps.


    ++don;

  • Wednesday, April 11, 2012 5:17 AM
     
     
    Thanks alot Ken and Don.