Visible to Intel only — GUID: GUID-F0BA3F0B-86BB-4352-8055-9FCD3316C192
Visible to Intel only — GUID: GUID-F0BA3F0B-86BB-4352-8055-9FCD3316C192
Accessor Concept
Accessor and const_accessor objects obtained via n_container::access() and n_container::const_access() provide access to read from or write to cells inside an n_container.
Syntax
The following methods return objects meeting the requirements of the accessor concept.
auto n_container::access();
auto n_container::const_access();
auto accessor_concept::section(n_bounds_t<…>);
auto accessor_concept::translated_to(n_index_t<…>);
auto accessor_concept::translated_to_zero();
Description
Accessor objects provide read/write access to individual cells of an n-dimensional container. Index values passed to a sequence of array subscript operator calls will produce a proxy concept that can import to or export the primitive data the corresponding cell inside the container.
auto image = make_n_container<MyStruct, layout::soa>(n_extent[128][256]);
auto acc = image.access();
MyStruct in_value(100.0f, 200.0f, 300.0f);
acc[64][128] = in_value;
MyStruct out_value = acc[64][128];
assert(out_value == in_value);
Accessors also know their valid iteration space, which can queried using the template function bound_d<int DimensionT>(accessor).
assert(bounds_d<0>(acc) == bounds(0_fixed,128));
assert(bounds_d<1>(acc) == bounds(0_fixed,256));
An accessor may have a non-zero index space if it has a translation embedded into it, bounds_d will reflect any such translation.
auto shifted_acc = acc.translated_to(n_index[1000][2000]);
assert(bounds_d<0>(shifted_acc) == bounds(1000,1128));
assert(bounds_d<1>(shifted_acc) == bounds(2000,2256));
This is useful to have a smaller sized container participate in a calculation over a portion of a larger index space, simplifying programming as the same index variable can be used, and the accessor takes care of applying the necessary translation. An accessor may represent a subsection over the original extents, bounds_d will identify the valid iteration space for that accessor.
auto subsection_acc = a.section(n_bounds[bounds(64,96)][bounds(128,160)]);
assert(bounds_d<0>(subsection_acc) == bounds(64, 96));
assert(bounds_d<1>(subsection_acc) == bounds(128, 160);
It can also be useful to have subsections be translated back to start their iteration space at 0. For efficiency, the translated_to_zero() method is provided to create an accessor shifted back to zero.
auto zb_sub_acc = a.section( n_bounds[bounds(64, 96)][bounds(128, 160)] ).translated_to_zero();
assert(bounds_d<0>(zb_sub_acc) == bounds(0, 32));
assert(bounds_d<1>(zb_sub_acc) == bounds(0, 32));
If fewer array subscript calls applied to an accessor than its rank, the result is another accessor of a lower rank. This can be useful to obtain accessors suitable to pass to code expecting lower rank accessors. Such as a obtaining a 3d accessor from a 4d container by specifying only a single index via array subscript. This has the effect of embedding the index value of the dimension inside accessor. When the final dimension is sliced, the result is a proxy object to the cell inside the container corresponding to the embedded index values inside the sliced accessors
auto image4d = make_n_container<MyStruct, layout::soa>(n_extent[10][20][128][256]);
MyStruct in_value(100.0f, 200.0f, 300.0f);
auto acc4d = image4d.access();
auto acc3d = acc4d[5];
auto acc2d = acc3d[10];
auto acc1d = acc2d[64];
acc1d[128] = in_value;
MyStruct out_value = acc4d[5][10][64][128];
assert(out_value == in_value);
The following table provides information on the requirements of the accessor concept.
Pseudo-Signature |
Description |
---|---|
|
Data type inside the cells of the container. |
|
Number of free dimensions of accessor |
|
Effects: constructs a copy of another accessor of the exact same type |
|
Requirements: rank == 1 and IndexT is one of: int, aligned<AlignmentT>, fixed<NumberT>, linear_index, or simd_index<LaneCountT> Effects: When only 1 free dimension is left, the operator[] will construct an element_concept which is the proxy to the cell inside the container. If this accessor was obtained with const_access(), then the proxy will provide read only interface to the cell’s data. Returns: The proxy object to cell inside the container corresponding to the position identified by the a_index along with any embedded index values for other dimensions |
|
Requirements: rank > 1 and IndexT is one of: int, aligned<AlignmentT>, fixed<NumberT>, linear_index, or simd_index<LaneCountT> Effects: When 2 or more free dimensions are left, the operator[] will construct another accessor_concept of lower rank embeding a_index inside of it, effectively fixing that dimension’s index value for any accesses made through the returned accessor_concept. Returns: The accessor_concept of lower rank ( one less free dimension). |
|
Requirements: DimensionT >=0 and DimensionT < rank Effects: Determine the bounds of a free dimension using DimensionT as a 0 based index starting at the leftmost dimension. Returns: bounds_t of the DimensionT |
|
Requirements: XX >=0 and XX < rank and XX < 20 Effects: Non templated methods to determine the bounds of a free dimension using XX as a 0 based index starting at the leftmost dimension. Returns: bounds_t of the XX dimension |
|
Requirements: DimensionT >=0 and DimensionT < rank Effects: Determine the extent of a free dimension using DimensionT as a 0 based index starting at the leftmost dimension. Returns: extent of the DimensionT |
|
Requirements: XX >=0 and XX < rank and XX < 20 Effects: Non templated methods to determine the extent of a free dimension using XX as a 0 based index starting at the leftmost dimension. Returns: extent of the XX dimension |
|
Requirements: a_n_index has same rank as the accessor Effects: construct an accessor_concept with an embedded translation such that accessing a_n_index will corresponds back to the current lower bounds. Easy way to think of it is that current iteration space is translated to a_n_index space. Returns: accessor_concept whose bounds have the same extents, but whose lower bounds start at the supplied a_n_index |
|
Effects: construct an accessor_concept with an embedded translation such that accessing [0] index for all dimensions will corresponds back to the current lower bounds. Easy way to think of it is that current iteration space is translated to [0] for all free dimensions. Returns: accessor_concept whose bounds have the same extents, but whose lower bounds start [0]…[0] |
|
Requirements: a_n_bounds has same rank as the accessor and a_n_bounds is contained by the accessors current bounds. Effects: construct an accessor_concept with using the supplied a_n_bounds to represent its valid iteration space. Because a_n_bounds must be contained within the existing bounds, we are effictively creating an accessor over a section of the container. Easy way to think of it is that current bounds are being restricted to a_n_bounds. Note: can be useful to chain a call translated_to_zero() on to the return value. Returns:accessor_concept whose bounds are set to the supplied a_n_bounds |