Handling subsections of data in C++ AMP

This blog post assumes that you are familiar with array and array_view , two types provided by C++ AMP for handling and manipulating data. Many times depending on the problem you are working with, you may want to offset your origin point and operate on a smaller section of data in your computation. C++ AMP facilitates this experience by providing a rich set of section() APIs. In this blog post, I will walk you through the complete set of section() APIs offered by C++ AMP.

array::section

The type array in C++ AMP provides member function section() which returns a subsection/part of the original array. Following are the different overloads:

  1. array_view<T,N> section(const index<N>& idx, const extent<N>& ext) restrict(amp,cpu)
  2. array_view<T,N> section(const index<N>& idx) restrict(amp,cpu)
  3. array_view<T,N> section(const extent<N>& ext) restrict(amp,cpu)
  4. array_view<const T,N> section(const index<N>& idx, const extent<N>& ext) const restrict(amp,cpu)
  5. array_view<const T,N> section(const index<N>& idx) const restrict(amp,cpu)
  6. array_view<const T,N> section(const extent<N>& ext) const restrict(amp,cpu)

The first overload returns a subsection of the original array with the origin specified by “idx” and with the extent specified by “ext”. In the second overload, the extent of the returned subsection spans from “idx” to boundary of data. It is equivalent to section(idx, this->extent - idx) . The third overload the origin of returned subsection is zero. The last three functions are the same as the first three except that they return array_view<const T, N> which is read only.

array section specializations

The partial specializations of array<T, N> (i.e. array<T, 1> , array<T, 2> and array<T, 3> ) provide corresponding partial specializations of the above APIs as member functions. In addition, they also provide variations of the section() overloads which allow directly specifying the integer value for each dimension of index and extent. More often than not we work with data of one, two or three dimensions and these overloads make the use of section() even more convenient by eliminating the need to explicitly create index and extent objects.

Provided by partial specialization array<T, 1>

  1. array_view<T,1> section(const index<1>& idx, const extent<1>& ext) restrict(amp,cpu)
  2. array_view<T,1> section(const index<1>& idx) restrict(amp,cpu)
  3. array_view<T,1> section(const extent<1>& ext) restrict(amp,cpu)
  4. array_view<T, 1> section(int i0, int e0) restrict(amp,cpu)
  5. array_view<const T,1> section(const index<1>& idx, const extent<1>& ext) const restrict(amp,cpu)
  6. array_view<const T,1> section(const index<1>& idx) const restrict(amp,cpu)
  7. array_view<T,1> section(const extent<1>& ext) const restrict(amp,cpu)
  8. array_view<const T, 1> section(int i0, int e0) restrict(amp,cpu)

Provided by partial specialization array<T, 2>

  1. array_view<T,2> section(const index<2>& idx, const extent<2>& ext) restrict(amp,cpu)
  2. array_view<T,2> section(const index<2>& idx) restrict(amp,cpu)
  3. array_view<T,2> section(const extent<2>& ext) restrict(amp,cpu)
  4. array_view<T,2> section(int i0, int i1, int e0, int e1) restrict(amp,cpu)
  5. array_view<const T,2> section(const index<2>& idx, const extent<2>& ext) const restrict(amp,cpu)
  6. array_view<const T,2> section(const index<2>& idx) const restrict(amp,cpu)
  7. array_view<T,2> section(const extent<2>& ext) const restrict(amp,cpu)
  8. array_view<const T,2> section(int i0, int i1, int e0, int e1) restrict(amp,cpu)

Provided by partial specialization array<T, 3>

  1. array_view<T,3> section(const index<3>& idx, const extent<3>& ext) restrict(amp,cpu)
  2. array_view<T,3> section(const index<3>& idx) restrict(amp,cpu)
  3. array_view<T,3> section(const extent<3>& ext) restrict(amp,cpu)
  4. array_view<T,3> section(int i0, int i1, int i2, int e0, int e1, int e2) restrict(amp,cpu)
  5. array_view<const T,3> section(const index<3>& idx, const extent<3>& ext) const restrict(amp,cpu)
  6. array_view<const T,3> section(const index<3>& idx) const restrict(amp,cpu)
  7. array_view<T,3> section(const extent<3>& ext) const restrict(amp,cpu)
  8. array_view<const T,3> section(int i0, int i1, int i2, int e0, int e1, int e2) const restrict(amp,cpu)

The last four functions in each group above are semantically the same as the first four and differ only in return value: they return array_view<const T, N> which is read only. The array_view object returned by section() functions only wraps the underlying array partially and any modification (copying to, copying from or assignment) made to this array_view will reflect changes only to the portion of actual data covered by extent “ext” with origin “idx”.

array_view::section

The type array_view in C++ AMP provides exactly the same set of section() member functions (syntactically and semantically) as array except that the returned array_view object represents a subsection of the underlying array_view (which itself may represent subsection over another array_view or array or raw data).

In Closing

The ability to section the array and array_view and manipulate it through resulting array_view objects can come to benefits in many scenarios. Here is an example demonstrating the use section() APIs on our blog.

As usual, I would love to read your comments below or in our MSDN forum.