最終更新日時(UTC):
が更新

履歴 編集

customization point object
<execution>

std::execution::bulk_chunked(C++26)

namespace std::execution {
  struct bulk_chunked_t { unspecified };
  inline constexpr bulk_chunked_t bulk_chunked{};
}

概要

bulk_chunkedは、インデクス空間を区間分割したチャンク単位でタスクを一括実行するSenderアダプタである。

bulk_chunkedパイプ可能Senderアダプタオブジェクトであり、パイプライン記法をサポートする。

実行制御ライブラリのデフォルト動作では、下記のように振る舞う。

  • 並列Scheduler上では、インデクス空間を区間分割されたチャンク単位で並列実行される。
  • 明示的にカスタマイズされていなければ、各インデクスに対する処理は逐次実行される。

効果

説明用の式sndr, policy, shape, fに対して、型Policyremove_cvref_t<decltype(policy)>、型Shapedecltype(auto(shape))、型Funcdecay_t<decltype((f))>とする。下記いずれかの条件をみたすとき、呼び出し式bulk_chunked(sndr, policy, shape, f)不適格となる。

そうでなければ、呼び出し式bulk_chunked(sndr, policy, shape, f)sndrが1回だけ評価されることを除いて、下記と等価。

transform_sender(
  get-domain-early(sndr),
  make-sender(bulk_chunked, product-type<see below, Shape, Func>{policy, shape, f}, sndr))

product-typeの第1テンプレート引数は、Policycopy_constructibleのモデルであるときPolicyとなる。そうでなければ、const Policy&となる。

Senderアルゴリズムタグ bulk_chunked

Senderアルゴリズム動作説明用のクラステンプレートimpls-forに対して、下記の特殊化が定義される。

namespace std::execution {
  template<>
  struct impls-for<bulk_chunked_t> : default-impls {
    static constexpr auto complete = see below;

    template<class Sndr, class... Env>
    static consteval void check-types();
  };
}

impls-for<bulk_chunked_t>::completeメンバは、下記ラムダ式と等価な関数呼び出し可能なオブジェクトで初期化される。

[]<class Index, class State, class Rcvr, class Tag, class... Args>
  (Index, State& state, Rcvr& rcvr, Tag, Args&&... args) noexcept
  -> void requires see below {
    if constexpr (same_as<Tag, set_value_t>) {
      auto& [policy, shape, f] = state;
      constexpr bool nothrow = noexcept(f(auto(shape), auto(shape), args...));
      TRY-EVAL(rcvr, [&]() noexcept(nothrow) {
        f(static_cast<decltype(auto(shape))>(0), auto(shape), args...);
        Tag()(std::move(rcvr), std::forward<Args>(args)...);
      }());
    } else {
      Tag()(std::move(rcvr), std::forward<Args>(args)...);
    }
  }

Tagset_value_t以外の型であるとき、もしくは式f(auto(shape), auto(shape), args...)適格なときに限って、上記ラムダ式のrequires節が満たされる。

メンバ関数impls-for<bulk_chunked_t>::check-typesの効果は下記の通り。

auto cs = get_completion_signatures<child-type<Sndr>, FWD-ENV-T(Env)...>();
auto fn = []<class... Ts>(set_value_t(*)(Ts...)) {
  if constexpr (!invocable<remove_cvref_t<data-type<Sndr>>, Ts&...>)
    throw unspecified-exception();
};
cs.for-each(overload-set{fn, [](auto){}});

unspecified-exceptionexceptionから派生した型となる。

カスタマイゼーションポイント

Senderアルゴリズム構築時およびReceiver接続時に、関連付けられた実行ドメインに対してexecution::transform_sender経由でSender変換が行われる。 デフォルト実行ドメインでは無変換。

説明用の式out_sndrbulk_chunked(sndr, policy, shape, f)戻り値Senderとし、式rcvrを式connect(out_sndr, rcvr)適格となるReceiverとする。式connect(out_sndr, rcvr)開始(start)時に下記を満たす非同期操作を生成しない場合、動作は未定義となる。

  • 説明用のargssndrの値完了結果を参照する左辺値式のパック、またはcopy_constructibleのモデルであるならばそれらの値のdecayコピーのパックとする。sndrが値完了したとき、
    • out_sndrもまた値完了するとき、範囲[0, shape]にある型Shapeの0個以上のbeのペアに対してf(b, e, args...)を呼び出す。このときb < eであり、かつ0からshapeまでの型Shapeの全てのiにおいて、beのペアに対してiが範囲[b, e)にあるような呼び出しが正確に1回だけ存在する。
    • out_sndrset_error(rcvr, eptr)で完了するとき、エラー完了ハンドラが呼び出される前に非同期操作f呼び出しのサブセットを呼び出す可能性があり、eptrは下記いずれかを指すexception_ptrとなる。
    • out_sndrset_stopped(rcvr)で完了するとき、停止完了ハンドラが呼び出される前に非同期操作f呼び出しのサブセットを呼び出す可能性がある。
  • sndrset_valueで完了しないとき、その完了操作はrecvに転送される。
  • パラメータpolicyは、アルゴリズムに対応した非同期操作の実行を並列化する方法、およびfに適用する方法を規程する。並列アルゴリズム要素アクセス関数に対する権限と要件はfに適用される。

#include <print>
#include <execution>
namespace ex = std::execution;

int main()
{
  ex::sender auto sndr =
    ex::just()
    | ex::bulk_chunked(3, ex::seq,
        [](int begin, int end) {
          for (int i = begin; i < end; i++) {
            std::println("{}", i);
          }
        });
  std::this_thread::sync_wait(sndr);
}

出力

0
1
2

バージョン

言語

  • C++26

処理系

関連項目

参照