最終更新日時:
が更新

履歴 編集

function template
<simd>

std::simd::partial_scatter_to(C++26)

namespace std::simd {
  template<simd-vec-type V,
           ranges::contiguous_range R,
           simd-integral I,
           class... Flags>
    requires ranges::sized_range<R>
  constexpr void
    partial_scatter_to(const V& v,
                       R&& out,
                       const I& indices,
                       flags<Flags...> f = {});  // (1) C++26

  template<simd-vec-type V,
           ranges::contiguous_range R,
           simd-integral I,
           class... Flags>
    requires ranges::sized_range<R>
  constexpr void
    partial_scatter_to(const V& v,
                       R&& out,
                       const typename I::mask_type& mask,
                       const I& indices,
                       flags<Flags...> f = {});  // (2) C++26
}

概要

basic_vecの各要素を、インデックスを表すデータ並列型indicesで指定した連続メモリ領域outの飛び飛びの位置へ書き出す(scatter)。vi番目の要素は、outindices[i]番目の位置へ書き込まれる。インデックスが範囲外を指す場合でも安全に書き出せ、その位置へは書き込まれない。

  • (1) : 全要素を書き出す
  • (2) : maskの各要素がtrueである位置の要素のみを書き出す

  • v : scatterするデータ並列型の値

  • indices : 各要素が書き込み位置のインデックスを表す、整数要素のデータ並列型
  • f : scatterの動作を指定するflagsオブジェクト。既定値はflag_default。要素型が異なるメモリへの変換書き込みを許可するflag_convertや、メモリのアライメントを仮定するflag_alignedflag_overaligned<N>を指定できる

unchecked_scatter_toとの違いは、インデックスがoutの範囲外を指してもよい点である。範囲外の位置へは書き込まれない。

テンプレートパラメータ制約

  • V::size() == I::size()trueであること
  • std::ranges::iterator_t<R>std::indirectly_writable<std::ranges::range_value_t<R>>のモデルであること
  • V::value_typestd::ranges::range_value_t<R>へ明示的に変換可能であること

適格要件

  • std::ranges::range_value_t<R>「vectorizable type」であること
  • テンプレートパラメータパックFlagsflag_convertを含まない場合、V::value_typeからstd::ranges::range_value_t<R>への変換が値を保存すること

事前条件

  • 選択されたすべてのインデックスiについて、indices[i]の値が一意であること
  • Flagsflag_alignedを含む場合、std::ranges::data(out)alignment_v<V, std::ranges::range_value_t<R>>でアライメントされた領域を指すこと
  • Flagsflag_overaligned<N>を含む場合、std::ranges::data(out)Nでアライメントされた領域を指すこと

効果

0以上I::size()未満の各iについて、mask[i] && (indices[i] < std::ranges::size(out))trueであれば、以下を評価する。

ranges::data(out)[indices[i]] = static_cast<ranges::range_value_t<R>>(v[i]);

戻り値

なし。

#include <simd>
#include <array>
#include <print>

namespace simd = std::simd;

int main()
{
  simd::vec<int, 4> v([](int i) { return (i + 1) * 10; }); // {10, 20, 30, 40}

  // インデックス {0, 2, 4, 6} のうち、範囲外(4, 6)へは書き込まれない
  simd::vec<int, 4> indices([](int i) { return i * 2; });

  std::array<int, 4> out{};
  simd::partial_scatter_to(v, out, indices);

  for (int x : out) {
    std::print("{} ", x);
  }
  std::println("");
}

出力

10 0 20 0 

バージョン

言語

  • C++26

処理系

関連項目

参照