array_view without Data Source
In Visual Studio 2012, C++ AMP introduced concurrency::array_view as a primary interface to read and write multi-dimensional data across the CPU and GPU accelerators.
The construction of array_view always required a data source like std::vector, concurrency::array etc. It could be either a CPU pointer or any data container that supports .data() and .size() methods . Even in the scenarios, where a temporary container is required purely as an output buffer and its initial content and backing memory allocation is irrelevant, it is mandated to provide a data source.
Look the below code snippets which illustrate the above point.
Example 1:
1: array_view<const int, 1> arrViewA(M, vecA); // vecA is a const data source of type 'std::vector'
2: array_view<const int, 1> arrViewB(M, vecB); // vecB is a const data source of type 'std::vector
3:
4: std::vector<int> sumResult(arrViewA.extent.size());
5: array_view<int, 1> arrViewSum(M,sumResult); // Creation of array_view with resource
6: arrViewSum.discard_data();
7:
8: parallel_for_each(arrViewSum.extent, [=](const index<1> &idx) restrict(amp) {
9: arrViewSum[idx] = arrViewA[idx] + arrViewB[idx];
10: });
11: arrViewSum.synchronize();
12:
13: for (size_t i = 0; i < sumResult.size(); ++i) {
14: sumResult[i]; // Accessing the result of computation
15: }
Example 2:
1: array_view<const int, 1> arrViewA(M, vecA); // vecA is a const data source of type 'std::vector'
2: array_view<const int, 1> arrViewB(M, vecB); // vecB is a const data source of type 'std::vector'
3:
4: array<int, 1> arrSumResult(arrViewA.extent); // Creating Array object as output buffer
5: array_view<int, 1> arrViewSum(arrSumResult); // Creation of array_view over array
6: arrViewSum.discard_data();
7:
8: parallel_for_each(arrViewSum.extent, [=](const index<1> &idx) restrict(amp) {
9: arrViewSum[idx] = arrViewA[idx] + arrViewB[idx];
10: });
11:
12: for (size_t i = 0; i < sumResult.size(); ++i) {
13: arrViewSum.data[i]; // Accessing the result of computation
14: }
From the above code snippets, we will observe the following shortcomings:
a) Always a data source is required during to array_view construction
b) Requires the developers to learn about concurrency::array, array_view::discard_data.
c) Requires allocating the array on the right accelerator_view where, the array_view will be subsequently accessed. It also requires the users to specify the right accelerator_view to p_f_e, for using the array_view. Failure to specify the right accelerator_view may result in redundant data transfers to the targeted accelerator_view.
In Visual Studio 2013, these shortcomings have been addressed with the provision of “array_view construction without specifying a data source”. In short, this can be considered as creating an array_view, without any data source association and let the runtime allocate the underlying storage lazily as and when the array_view is accessed on accelerator_view or on the CPU.
- array_view without data source can be used only for read-write access. It cannot be constructed for read only purpose i.e., array_view<const T>.
- array_view without data source is just like any other ‘array_view’ object with no data association.
- array_view is initially uninitialized and behaves as if its contents have been “discard” immediately after construction.
- The “synchronize” API (the overload without any accelerator_view explicitly specified) will be a no-op for such an array_view.
Now, let’s rewrite the code snippets given in ‘Example 1’ and ‘Example 2’ using ‘array_view without data source’.
1: array_view<const int, 1> arrViewA(M, vecA); // vecA is a const data source of type 'std::vector'
2: array_view<const int, 1> arrViewB(M, vecB); // vecB is a const data source of type 'std::vector'
3:
4: array_view<int, 1> arrViewSum(M); // Creation of array_view without data resource
5:
6: parallel_for_each(arrViewSum.extent, [=](const index<1> &idx) restrict(amp) {
7: arrViewSum[idx] = arrViewA[idx] + arrViewB[idx];
8: });
9:
10: for (size_t i = 0; i < arrViewSum.extent.size(); ++i) {
11: arrViewSum.data[i]; // Accessing the result of computation
12: }
It is vividly evident that ‘array_view without data source’ is simple to use and in deed resulted in fewer lines of code :-)
In Closing
In this post we looked at the one of the improvements we’ve made to Array_views in Visual Studio 2013. Stay tuned for more blog posts on the improvements of C++ AMP in Visual Studio 2013. As usual, I would love to read your comments below or in our MSDN forum.
Comments
- Anonymous
April 10, 2014
Is it possible to create array_view without data source in VS 2012 with any patch? I have a situation in my code that i have to get data on device without using array as if i create array i have to do it dynamically an then free it which is not possible as pointers are not allowed inside parallel_foreach. i am working with class which has array_view as data member .