インテル® C++ コンパイラー 18.0 デベロッパー・ガイドおよびリファレンス

アクセサーコンセプト

n_container::access()n_container::const_access() を使用して取得可能な accessor オブジェクトと const_accessor オブジェクトは、n_container 内のセルを読み書きするためのアクセスを提供します。

構文

次のメソッドは、アクセサーコンセプトの要件を満たすオブジェクトを返します。

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();

説明

アクセサー・オブジェクトは、n 次元コンテナー内の個々のセルへの読み取り/書き込みアクセスを提供します。一連の配列添字演算子の呼び出しに渡されるインデックス値は、コンテナー内のセルに対応するプリミティブ・データをインポート/エクスポートできるプロキシーコンセプトを作成します。

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);
アクセサーは有効な反復空間を把握しており、それはテンプレート関数 bound_d<int DimensionT>(accessor) により照会できます。

assert(bounds_d<0>(acc) == bounds(0_fixed,128));
assert(bounds_d<1>(acc) == bounds(0_fixed,256));

アクセサーに変換処理が組込まれている場合、そのインデックス空間は非ゼロになり、bounds_d に変換処理が反映されます。

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));

これは、小さなコンテナーを使って、大きなインデックス空間の一部の計算を行う場合に便利です。同じインデックス変数を使用できるためプログラミングが容易になり、アクセサーにより必要な変換が行われます。アクセサーは、オリジナルの範囲のサブセクションを表すこともでき、bounds_d はアクセサーの有効な反復空間を特定します。

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);

また、サブセクションを反復空間の開始位置 0 に戻すのにも役立ちます。効率化のため、0 に戻したアクセサーを作成する translated_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));

アクセサーがランクよりも少ない配列添字呼び出しに対応する場合、低いランクの別のアクセサーを作成できます。これは、低いランクのアクセサーを想定しているコードに適したアクセサーを取得し、渡す際に便利です。例えば、配列添字で 1 つのインデックスのみを指定して、4D コンテナーから 3D アクセサーを取得できます。これは、次元のインデックス値をアクセサー内に埋め込む効果があります。最後の次元がスライスされると、スライスされたアクセサー内に埋め込まれたインデックス値に対応する、コンテナー内のセルへのプロキシー・オブジェクトが得られます。

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);

次の表は、アクセサーコンセプトの要件に関する情報です。

擬似署名

説明

typedef PrimitiveT primitive_type;

コンテナーのセル内のデータ型。

static constexpr int rank;

アクセサーの利用可能な次元数。

accessor_concept(const accessor_concept &a_other)

効果: 同じ型の別のアクセサーのコピーを構築します。

template<typename IndexT>
element_concept operator[] (const IndexT a_index) const

要件: rank == 1 および IndexT は次のいずれかです: int、aligned<AlignmentT>、fixed<NumberT>、linear_index、または simd_index<LaneCountT>。

効果: 利用可能な次元が 1 つのみの場合、operator[] はコンテナー内のセルへのプロキシーである element_concept を構築します。const_access() でこのアクセサーを取得すると、プロキシーはセルのデータへの読み取り専用インターフェイスを提供します。

戻り値: ほかの次元の埋め込みインデックス値と a_index によって識別された位置に対応する、コンテナー内のセルへのプロキシー・オブジェクト。

template<typename IndexT>
accessor_concept operator[] (const IndexT a_index) const 

要件: rank > 1 および IndexT は次のいずれかです: int、aligned<AlignmentT>、fixed<NumberT>、linear_index、または simd_index<LaneCountT>。

効果: 利用可能な次元が 2 つ以上ある場合、operator[] は a_index を埋め込んだ低いランクの別の accessor_concept を構築し、戻り値の accessor_concept でアクセスに利用されるその次元のインデックス値を修正します。

戻り値: 低いランクの accessor_concept (利用可能な次元が 1 つ少ない)。

template<int DimensionT>
auto bounds_d() const

要件: DimensionT >=0 および DimensionT < ランク。

効果: DimensionT を左端の次元から開始する 0 ベースのインデックスとして使用し、利用可能な次元の境界を特定します。

戻り値: DimensionT の bounds_t。

auto bounds_dXX() const 
(XX は 0-19)

要件: XX >=0 および XX < ランク および XX < 20。

効果: 非テンプレート・メソッドにより、XX を左端の次元から開始する 0 ベースのインデックスとして使用し、利用可能な次元の境界を特定します。

戻り値: XX 次元の bounds_t。

template<int DimensionT>
auto extent_d() const

要件: DimensionT >=0 および DimensionT < ランク。

効果: DimensionT を左端の次元から開始する 0 ベースのインデックスとして使用し、利用可能な次元の範囲を特定します。

戻り値: DimensionT の範囲。

auto extent_dXX() const 
(XX は 0-19)

要件: XX >=0 および XX < ランク および XX < 20。

効果: 非テンプレート・メソッドにより、XX を左端の次元から開始する 0 ベースのインデックスとして使用し、利用可能な次元の範囲を特定します。

戻り値: XX 次元の範囲。

template<typename ...IndexListT>
accessor_concept translated_to(
    n_index_t<IndexListT...> a_n_index) const

要件: a_n_index とアクセサーのランクが同じでなければならない。

効果: a_n_index へのアクセスを現在の下限に対応させる変換が組込まれた accessor_concept を構築します。つまり、現在の反復空間が a_n_index 空間に変換されます。

戻り値: 同じ範囲で、下限が a_n_index から開始する accessor_concept。

template<typename ...IndexListT>
accessor_concept translated_to_zero() const

効果: すべての次元で [0] インデックスへのアクセスを現在の下限に対応させる変換が組み込まれた accessor_concept。つまり、現在の反復空間が、すべての利用可能な次元で [0] に変換されます。

戻り値: 同じ範囲で、下限が [0]…[0] から開始する accessor_concept。

template<typename ...BoundsTypeListT>
    auto
    section(const n_bounds_t<BoundsTypeListT...> &a_n_bounds) const

要件: a_n_bounds とアクセサーのランクが同じで、a_n_bounds がアクセサーの現在の境界内になければなりません。

効果: a_n_bounds を使用して有効な反復空間を表す accessor_concept を構築します。a_n_bounds は既存の境界内になければならないため、コンテナーのセクションのアクセサーを作成します。つまり、現在の境界が a_n_bounds に制限されます。注: 戻り値に対して translated_to_zero() 呼び出しをチェーンするのに役立ちます。

戻り値: 境界が a_n_bounds に設定された accessor_concept