oneAPI 1.3 暫定仕様書 Rev. 1 の解説 (5)

その他

この記事は、https://www.oneapi.io/spec/ で 2023年9月14日に公開された『oneAPI 1.3 Provisional Specification Rev. 1』 (HTMLPDF) をベースにしています。原文は2000 ページ近くあり、翻訳の時間とリソースも限られるため、全文翻訳ではなく、記事形式で区切った仕様とその解説を提供することにしました。


この回では、『oneAPI 1.3 Provisional Specification Rev. 1』の「oneDPL」の「Parallel API」の節を取り上げています。

並列 API

oneDPL は、C++ 標準第 6 版 (通称 C++20) で追加された並列アルゴリズムを含む、C++ 標準 (英語) で定義される並列アルゴリズムのセットを提供します。これらのアルゴリズムはすべて、C++ 標準に準拠した実行ポリシーおよび DPC++ 実行ポリシーで動作します。

さらに、oneDPL は、SYCL* (英語) バッファー、特殊イテレーター、および一連の非標準並列アルゴリズムのラッパー関数を提供します。

C++ 標準に従った実行ポリシー

oneDPL には、C++ 標準 (英語) 第 6 版 (C++20) に語彙的に準拠した実行ポリシーと関連ユーティリティーのセットが含まれます。

// <oneapi/dpl/execution> で定義

namespace oneapi {
  namespace dpl {
    namespace execution {

      class sequenced_policy { /*unspecified*/ };
      class parallel_policy { /*unspecified*/ };
      class parallel_unsequenced_policy { /*unspecified*/ };
      class unsequenced_policy { /*unspecified*/ };

      inline constexpr sequenced_policy seq { /*unspecified*/ };
      inline constexpr parallel_policy par { /*unspecified*/ };
      inline constexpr parallel_unsequenced_policy par_unseq { /*unspecified*/ };
      inline constexpr unsequenced_policy unseq { /*unspecified*/ };

      template <class T>
      struct is_execution_policy;

      template <class T>
      inline constexpr bool is_execution_policy_v = oneapi::dpl::execution::is_execution_policy<T>::value;
    }
  }
}

詳細については、C++ 標準 (英語) の「実行ポリシー」を参照してください。

DPC++ 実行ポリシー

DPC++ 実行ポリシークラス oneapi::dpl::execution::device_policy は、アルゴリズムが実行される環境を指定します。

// <oneapi/dpl/execution> で定義

namespace oneapi {
  namespace dpl {
    namespace execution {

      template <typename KernelName = /*unspecified*/>
      class device_policy;

      device_policy<> dpcpp_default;

      template <typename KernelName = /*unspecified*/>
      device_policy<KernelName>
      make_device_policy( sycl::queue );

      template <typename KernelName = /*unspecified*/>
      device_policy<KernelName>
      make_device_policy( sycl::device );

      template <typename NewKernelName, typename OldKernelName>
      device_policy<NewKernelName>
      make_device_policy( const device_policy<OldKernelName>& = dpcpp_default );
    }
  }
}

dpcpp_default は、デフォルトの DPC++ デバイスでアルゴリズムを実行するために事前定義された実行ポリシー・オブジェクトです。

device_policy クラス

template <typename KernelName = /*unspecified*/>
class device_policy
{
public:
    using kernel_name = KernelName;

    device_policy();
    template <typename OtherName>
    device_policy( const device_policy<OtherName>& );
    explicit device_policy( sycl::queue );
    explicit device_policy( sycl::device );

    sycl::queue queue() const;
    operator sycl::queue() const;
};

device_policy タイプのオブジェクトは、DPC++ 準拠のデバイスでアルゴリズムを実行するために使用される sycl::queue に関連付けられます。アルゴリズムが device_policy で実行される場合、SYCL* バッファー (oneapi::dpl::begin/end を介して渡される)、ホストメモリー内のデータ、および USM デバイスメモリーを含む統合共有メモリー (USM) 内のデータを処理できます。ホストメモリーおよび USM に配置されたデータは、ポインターとランダム・アクセス・イテレーターとしてのみ oneDPL アルゴリズムに渡すことが可能です。ホストメモリーからデバイスにデータを転送したり、その逆を行う方法は未指定です。一時ストレージとの間で要素ごとにデータを移動することは、有益な実装であると考えられます。

KernelName テンプレート・パラメーターは、クラス・テンプレート内で kernel_name として別名化され、ポリシーが引き継がれるアルゴリズムによって実行される DPC++ カーネル名を明示します。

device_policy()

デフォルトのデバイスセレクターで作成されたキューに関連するポリシー・オブジェクトを作成します。

template <typename OtherName>
device_policy( const device_policy<OtherName>& policy )

指定されたポリシーのカーネル名を新しいポリシーに定義された kernel_name に変更して、policy と同じキューに関連付けられたポリシー・オブジェクトを作成します。

explicit device_policy( sycl::queue queue )

指定されたキューに関連するポリシー・オブジェクトを作成します。

explicit device_policy( sycl::device device )

特定のデバイスセレクター向けに作成されたキューに関連するポリシー・オブジェクトを作成します。

sycl::queue queue() const

ポリシーが関連付けられているキューを返します。

operator sycl::queue() const

ポリシーの sycl::queue オブジェクトへの暗黙の変換を許可します。

make_device_policy 関数

make_device_policy 関数テンプレートを使用すると、device_policy の作成が簡素化されます。

template <typename KernelName = /*unspecified*/>
device_policy<KernelName>
make_device_policy( sycl::queue queue )

queue に関連付けられたポリシー・オブジェクトを作成します。カーネル名はテンプレート引数として提供される可能性がありますが、それ以外では指定されません。

template <typename KernelName = /*unspecified*/>
device_policy<KernelName>
make_device_policy( sycl::device device )

device 上でアルゴリズムを実行するポリシー・オブジェクトを作成します。カーネル名はテンプレート引数として提供される可能性がありますが、それ以外では指定されません。

template <typename NewKernelName, typename OldKernelName>
device_policy<NewKernelName>
make_device_policy( const device_policy<OldKernelName>& policy = dpcpp_default )

テンプレート引数として提供された新しいカーネル名を使用して、policy から構築されたポリシー・オブジェクトを返します。ポリシー・オブジェクトが指定されていない場合、新しいポリシーは dpcpp_default から作成されます。

バッファーラッパー

//  <oneapi/dpl/iterator> で定義

namespace oneapi {
  namespace dpl {

    template < typename T, typename AllocatorT, typename TagT >
    /*unspecified*/ begin( sycl::buffer<T, /*dim=*/1, AllocatorT> buf,
                           TagT tag = sycl::read_write );

    template < typename T, typename AllocatorT, typename TagT >
    /*unspecified*/ begin( sycl::buffer<T, /*dim=*/1, AllocatorT> buf,
                           TagT tag, sycl::property::no_init );

    template < typename T, typename AllocatorT >
    /*unspecified*/ begin( sycl::buffer<T, /*dim=*/1, AllocatorT> buf,
                           sycl::property::no_init );


    template < typename T, typename AllocatorT, typename TagT >
    /*unspecified*/ end( sycl::buffer<T, /*dim=*/1, AllocatorT> buf,
                         TagT tag = sycl::read_write );

    template < typename T, typename AllocatorT, typename TagT >
    /*unspecified*/ end( sycl::buffer<T, /*dim=*/1, AllocatorT> buf,
                         TagT tag, sycl::property::no_init );

    template < typename T, typename AllocatorT >
    /*unspecified*/ end( sycl::buffer<T, /*dim=*/1, AllocatorT> buf,
                         sycl::property::no_init );

  }
}

oneapi::dpl::begin および oneapi::dpl::end は、DPC++ バッファーを oneDPL アルゴリズムに渡すヘルパー関数です。これらの関数はバッファーを受け取り、次の要件を満たす未指定型のオブジェクトを返します。

  • CopyConstructibleCopyAssignable、および比較可能な ==!= 演算子。
  • 有効な式は、a + na - na - b であり、a および b はタイプのオブジェクトで、n は整数値です。
  • begin または end 関数に渡されたバッファーを返す get_buffer() メソッドを提供します。

アルゴリズムを呼び出す場合、begin に渡すバッファーは end に渡すバッファーと同じでなければなりません。そうでない場合の動作は不定です。

SYCL* デダクション・タグ (TagT パラメーター) と sycl::property::no_init を使用すると、バッファーにアクセスするアルゴリズムで使用するアクセスモードを指定できます。このモードはヒントとして機能し、アルゴリズムのセマンティクスに応じてオーバーライドできます。アルゴリズムを呼び出す際は、beginend に同じアクセスモード引数を指定しなければなりません。そうでない場合の動作は不定です。

using namespace oneapi;
auto buf_begin = dpl::begin(buf, sycl::write_only);
auto buf_end_1 = dpl::end(buf, sycl::write_only);
auto buf_end_2 = dpl::end(buf, sycl::write_only, sycl::no_init);
dpl::fill(dpl::execution::dpcpp_default, buf_begin, buf_end_1, 42); // allowed
dpl::fill(dpl::execution::dpcpp_default, buf_begin, buf_end_2, 42); // not allowed

イテレーター

oneDPL イテレーターは、namespace oneapi::dpl<oneapi/dpl/iterator> ヘッダーで定義されています。

template <typename Integral>
class counting_iterator
{
  public:
    using difference_type = /* a signed integer type of the same size as Integral */;
    using value_type = Integral;
    using reference = Integral;

    counting_iterator();
    explicit counting_iterator(Integral init);

    reference operator*() const;
    reference operator[](difference_type i) const;

    difference_type operator-(const counting_iterator& it) const;

    counting_iterator operator+(difference_type forward) const;
    counting_iterator operator-(difference_type backward) const;

    counting_iterator& operator+=(difference_type forward);
    counting_iterator& operator-=(difference_type backward);

    counting_iterator& operator++();
    counting_iterator& operator--();
    counting_iterator& operator++(int);
    counting_iterator& operator--(int);

    bool operator==(const counting_iterator& it) const;
    bool operator!=(const counting_iterator& it) const;
    bool operator<(const counting_iterator& it) const;
    bool operator>(const counting_iterator& it) const;
    bool operator<=(const counting_iterator& it) const;
    bool operator>=(const counting_iterator& it) const;
};

counting_iterator は、整数カウンターに類似したランダム・アクセス・イテレーターのような型です。逆参照すると、counting_iterator はカウンター値に等しい整数 rvalue 値を提供します。逆参照操作によりカウンターを変更することはできません。counting_iterator の算術および比較オペレーターは、オペレーターに渡されたイテレーター・インスタンスのカウンターを表す整数型の値に適用されたように動作します。

class discard_iterator
{
  public:
    using difference_type = std::ptrdiff_t;
    using value_type = /* unspecified */;
    using reference = /* unspecified */;

    discard_iterator();
    explicit discard_iterator(difference_type init);

    reference operator*() const;
    reference operator[](difference_type) const;

    difference_type operator-(const discard_iterator& it) const;

    discard_iterator operator+(difference_type forward) const;
    discard_iterator operator-(difference_type backward) const;

    discard_iterator& operator+=(difference_type forward);
    discard_iterator& operator-=(difference_type backward);

    discard_iterator& operator++();
    discard_iterator& operator--();
    discard_iterator operator++(int);
    discard_iterator operator--(int);

    bool operator==(const discard_iterator& it) const;
    bool operator!=(const discard_iterator& it) const;
    bool operator<(const discard_iterator& it) const;
    bool operator>(const discard_iterator& it) const;
};

discard_iterator は、ランダム・アクセス・イテレーターのような型であり、逆参照されると任意の値を割り当て可能な lvalue を提供します。割り当ては discard_iterator インスタンスには影響せず、書き込みは破棄されます。discard_iterator の算術および比較オペレーターは、イテレーター・インスタンスによって維持される整数カウンター値に適用されるように振る舞い、相互に相対的な位置を決定します。

template <typename SourceIterator, typename IndexMap>
class permutation_iterator
{
  public:
    using difference_type =
        typename std::iterator_traits<SourceIterator>::difference_type;
    using value_type = typename std::iterator_traits<SourceIterator>::value_type;
    using pointer = typename std::iterator_traits<SourceIterator>::pointer;
    using reference = typename std::iterator_traits<SourceIterator>::reference;

    permutation_iterator(const SourceIterator& input1, const IndexMap& input2,
                         std::size_t index = 0);

    SourceIterator base() const;

    reference operator*() const;
    reference operator[](difference_type i) const;

    difference_type operator-(const permutation_iterator& it) const;

    permutation_iterator operator+(difference_type forward) const;
    permutation_iterator operator-(difference_type backward) const;

    permutation_iterator& operator+=(difference_type forward);
    permutation_iterator& operator-=(difference_type forward);

    permutation_iterator& operator++();
    permutation_iterator& operator--();
    permutation_iterator operator++(int);
    permutation_iterator operator--(int);

    bool operator==(const permutation_iterator& it) const;
    bool operator!=(const permutation_iterator& it) const;
    bool operator<(const permutation_iterator& it) const;
    bool operator>(const permutation_iterator& it) const;
    bool operator<=(const permutation_iterator& it) const;
    bool operator>=(const permutation_iterator& it) const;
};

permutation_iterator は、ランダム・アクセス・イテレーターに類似した型であり、逆参照値セットはソース・イテレーターによって定義され、逆参照値セットに対する反復順序は、別のイテレーターまたは permutation_iterator インデックスをソース・イテレーターのインデックスにマップするファンクターによって定義されます。permutation_iterator の算術および比較オペレーターは、イテレーター・インスタンスによって維持される整数カウンター値に適用されるように振る舞い、インデックス・マップ内の位置を決定します。

permutation_iterator::operator* は、呼び出されたインスタンスのカウンター値を使用して、インデックス・マップにインデックスを付加します。マップ内の対応する値は、ソース・イテレーターによって定義される値セットのインデックスとして使用されます。lvalue はオペレーターの結果として返されます。

permutation_iterator::operator[] は、パラメーター i をインデックス・マップへのインデックスとして使用します。マップ内の対応する値は、ソース・イテレーターによって定義される値セットのインデックスとして使用されます。lvalue はオペレーターの結果として返されます。

template <typename SourceIterator, typename IndexMap>
permutation_iterator<SourceIterator, IndexMap>
make_permutation_iterator(SourceIterator source, IndexMap map);
make_permutation_iterator constructs and returns an instance of permutation_iterator using the source iterator and index map provided.
template <typename Iterator, typename UnaryFunc>
class transform_iterator
{
  public:
    using difference_type = typename std::iterator_traits<Iterator>::difference_type;
    using reference = typename std::invoke_result<UnaryFunc,
                          typename std::iterator_traits<Iterator>::reference>::type;
    using value_type = typename std::remove_reference<reference>::type;
    using pointer = typename std::iterator_traits<Iterator>::pointer;

    Iterator base() const;

    transform_iterator(Iterator it, UnaryFunc unary_func);
    transform_iterator(const transform_iterator& input);
    transform_iterator& operator=(const transform_iterator& input);

    reference operator*() const;
    reference operator[](difference_type i) const;

    difference_type operator-(const transform_iterator& it) const

    transform_iterator operator+(difference_type forward) const;
    transform_iterator operator-(difference_type backward) const;

    transform_iterator& operator+=(difference_type forward);
    transform_iterator& operator-=(difference_type backward);

    transform_iterator& operator++();
    transform_iterator& operator--();
    transform_iterator operator++(int);
    transform_iterator operator--(int);

    bool operator==(const transform_iterator& it) const;
    bool operator!=(const transform_iterator& it) const;
    bool operator<(const transform_iterator& it) const;
    bool operator>(const transform_iterator& it) const;
    bool operator<=(const transform_iterator& it) const;
    bool operator>=(const transform_iterator& it) const;
};

transform_iterator は、ランダム・アクセス・イテレーターに類似した型であり、逆参照セットは提供される単項関数とソース・イテレーターによって定義されます。逆参照されると、transform_iterator はソース・イテレーターの対応する要素に適用された単項関数の結果をもたらします。単項関数の結果に要素への参照が含まれない限り、逆参照操作によってソース・イテレーターの要素を変更することはできません。transform_iterator の算術および比較オペレーターは、ソース・イテレーター自身に適用されるかのように動作します。

template <typename UnaryFunc, typename Iterator>
transform_iterator<UnaryFunc, Iterator>
make_transform_iterator(Iterator, UnaryFunc);

make_transform_iterator は、ソース・イテレーターとインデックス・マップを使用して、transform_iterator のインスタンスを構築して返します。

template <typename... Iterators>
class zip_iterator
{
  public:
    using difference_type = typename std::make_signed<std::size_t>::type;
    using value_type =
        std::tuple<typename std::iterator_traits<Iterators>::value_type...>;
    using reference = /* unspecified tuple of reference types */;
    using pointer =
        std::tuple<typename std::iterator_traits<Iterators>::pointer...>;

    std::tuple<Iterators...> base() const;

    zip_iterator();
    explicit zip_iterator(Iterators... args);
    zip_iterator(const zip_iterator& input);
    zip_iterator& operator=(const zip_iterator& input);

    reference operator*() const;
    reference operator[](difference_type i) const;

    difference_type operator-(const zip_iterator& it) const;
    zip_iterator operator-(difference_type backward) const;
    zip_iterator operator+(difference_type forward) const;

    zip_iterator& operator+=(difference_type forward);
    zip_iterator& operator-=(difference_type backward);

    zip_iterator& operator++();
    zip_iterator& operator--();
    zip_iterator operator++(int);
    zip_iterator operator--(int);

    bool operator==(const zip_iterator& it) const;
    bool operator!=(const zip_iterator& it) const;
    bool operator<(const zip_iterator& it) const;
    bool operator>(const zip_iterator& it) const;
    bool operator<=(const zip_iterator& it) const;
    bool operator>=(const zip_iterator& it) const;
};

zip_iterator は、1 つ以上のイテレーターで定義されたイテレーターに類似したタイプです。逆参照することで zip_iterator から返される値は、zip_iterator が定義されているソース・イテレーターを逆参照することで返される値のタプルです。zip_iterator の算術オペレーターは、操作が各イテレーターに適用されたかのように、zip_iterator インスタンスのソース・イテレーターを更新します。

template <typename... Iterators>
zip_iterator<Iterators...>
make_zip_iterator(Iterators...);

make_zip_iterator は、ソース・イテレーターのセットを使用して zip_iterator のインスタンスを構築して返します。

並列アルゴリズム

並列アルゴリズムは、namespace oneapi::dpl<oneapi/dpl/algorithm> ヘッダーで定義されています。

template<typename Policy, typename InputKeyIt, typename InputValueIt,
    typename OutputValueIt,
    typename T = typename std::iterator_traits<InputValueIt>::value_type,
    typename BinaryPred =
        std::equal_to<typename std::iterator_traits<InputKeyIt>::value_type>,
    typename BinaryOp =
        std::plus<typename std::iterator_traits<InputValueIt>::value_type>>
OutputValueIt
exclusive_scan_by_segment(Policy&& policy, InputKeyIt keys_first,
    InputKeyIt keys_last, InputValueIt values_first, OutputValueIt values_result,
    T initial_value = 0,
    BinaryPred binary_pred =
        std::equal_to<typename std::iterator_traits<InputKeyIt>::value_type>(),
    BinaryOp binary_op =
        std::plus<typename std::iterator_traits<InputValueIt>::value_type>());

oneapi::dpl::exclusive_scan_by_segment は、一連の値に binary_op 操作を適用することで、部分的なプリフィクス・スキャンを実行します。それぞれの部分スキャンは binary_pred プレディケートに従って、等しい値に関連付けられたキーによって決定される連続サブシーケンスに適用され、各スキャンの最初の要素は提供された初期値となります。戻り値は、結果シーケンスの終わりをターゲットにするイテレーターです。

省略された場合の初期値は、0 で初期化された InputValueIt イテレーター型の value_type インスタンスです。キーの比較でバイナリー述語が省略されている場合、InputKeyIt イテレーター・タイプの value_type を持つ std::equal_to のインスタンスが使用されます。値のサブシーケンス要素を組み合わせるため二項演算オペレーターが指定されていない場合は、InputValueIt イテレーター型の value_type を持つ std::plus のインスタンスが使用されます。

template<typename Policy, typename InputKeyIt, typename InputValueIt,
    typename OutputValueIt,
    typename BinaryPredcate =
        std::equal_to<typename std::iterator_traits<InputKeyIt>::value_type,
    typename BinaryOp =
        std::plus<typename std::iterator_traits<InputValueIt>::value_type>>
OutputValueIt
inclusive_scan_by_segment(Policy&& policy, InputKeyIt keys_first,
    InputKeyIt keys_last, InputValueIt values_first, OutputValueIt values_result
    BinaryPred binary_pred =
        std::equal_to<typename std::iterator_traits<InputKeyIt>::value_type>(),
    BinaryOp binary_op =
        std::plus<typename std::iterator_traits<InputValueIt>::value_type>());

oneapi::dpl::inclusive_scan_by_segment は、一連の値に binary_op 操作を適用することで、部分的なプリフィクス・スキャンを実行します。それぞれの部分スキャンは binary_pred プレディケートに従って、等しい値に関連付けられたキーによって決定される連続したサブシーケンスに適用されます。戻り値は、結果シーケンスの終わりをターゲットにするイテレーターです。

キーの比較でバイナリー述語が省略されている場合、InputKeyIt イテレーター・タイプの value_type を持つ std::equal_to のインスタンスが使用されます。値のサブシーケンス要素を組み合わせるため二項演算オペレーターが指定されていない場合は、InputValueIt イテレーター型の value_type を持つ std::plus のインスタンスが使用されます。

template<typename Policy, typename InputKeyIt, typename InputValueIt,
    typename OutputKeyIt, typename OutputValueIt,
    typename BinaryPredcate =
        std::equal_to<typename std::iterator_traits<InputKeyIt>::value_type,
    typename BinaryOp =
        std::plus<typename std::iterator_traits<InputValueIt>::value_type>>
std::pair<OutputKeyIt,OutputValueIt>
reduce_by_segment(Policy&& policy, InputKeyIt keys_first, InputKeyIt keys_last,
    InputValueIt values_first, OutputKeyIt keys_result,
    OutputValueIt values_result,
    BinaryPred binary_pred =
        std::equal_to<typename std::iterator_traits<InputKeyIt>::value_type>(),
    BinaryOp binary_op =
        std::plus<typename std::iterator_traits<InputValueIt>::value_type>());

oneapi::dpl::reduce_by_segment は値のシーケンスに対し部分的なリダクションを行います。それぞれのリダクションは、binary_pred プレディケートによる等しい関連キーによって決定される値の連続するサブシーケンスに対し、binary_op 操作で計算されます。サブシーケンスごとに、同じキーの最初が keys_result に格納され、計算されたリダクション値が values_result に格納されます。戻り値は、結果シーケンスの終わりを保持するイテレーターのペアです。

キーの比較でバイナリー述語が省略されている場合、std::equal_to のインスタンスと InputKeyIt イテレーター型の value_type が使用されます。二項演算オペレーターが指定されていない場合、std::plus のインスタンスと InputValueIt イテレーター・タイプの value_type を使用して識別されたそれぞれのサブシーケンス値を結合します。

template<typename Policy, typename InputIt1, typename InputIt2, typename OutputIt,
    typename Comparator =
        std::less<typename std::iterator_traits<InputIt>::value_type>>
OutputIt
binary_search(Policy&& policy, InputIt1 start, InputIt1 end,
    InputIt2 value_first, InputIt2 value_last, OutputIterator result,
    Comparator comp =
        std::less<typename std::iterator_traits<InputIt1>::value_type>());

oneapi::dpl::binary_search は、[value_first, value_last) のそれぞれの値で [start, end) のデータに対してバイナリー検索を実行します。検索されたデータが存在する場合、[result, result + distance(value_first, value_last)) の対応する要素は true に設定され、それ以外は false に設定されます。

コンパレーターが指定されない場合、operator< を使用して検索値が検索対象範囲内の各要素よりも小さいか判断します。

[start, end) の要素 e は、使用するコンパレーターに関連して分割される必要があります。[start, end) のすべての要素 e[value_first, value_last) の特定の検索値 vcomp(e, v) は、!comp(v, e) を意味します。

template<typename Policy, typename InputIt1, typename InputIt2, typename OutputIt,
    typename Comparator =
        std::less<typename std::iterator_traits<InputIt>::value_type>>
OutputIt
lower_bound(Policy&& policy, InputIt1 start, InputIt1 end,
    InputIt2 value_first, InputIt2 value_last, OutputIterator result,
    Comparator comp =
        std::less<typename std::iterator_traits<InputIt1>::value_type>());

oneapi::dpl::lower_bound は、[value_first, value_last) のそれぞれの値の [start, end) のデータに対してバイナリー検索を実行し、コンパレーターで定義された順序に従って検索値を [start, end) に挿入可能な最小インデックスを見つけます。そして最小インデックスが、[result, result + distance(value_first, value_last)) の対応する要素に割り当てられます。

コンパレーターが指定されない場合、operator< を使用して検索値が検索対象範囲内の各要素よりも小さいか判断します。

[start, end) の要素 e は、使用するコンパレーターに関連して分割される必要があります。

template<typename Policy, typename InputIt1, typename InputIt2, typename OutputIt,
    typename Comparator =
        std::less<typename std::iterator_traits<InputIt>::value_type>>
OutputIt
upper_bound(Policy&& policy, InputIt1 start, InputIt1 end,
    InputIt2 value_first, InputIt2 value_last, OutputIterator result,
    Comparator comp =
        std::less<typename std::iterator_traits<InputIt1>::value_type>());

oneapi::dpl::upper_bound は、[value_first, value_last) のそれぞれの値の [start, end) のデータに対してバイナリー検索を実行し、コンパレーターで定義された順序に従って検索値を [start, end) に挿入可能な最大インデックスを見つけます。そして最大インデックスが、[result, result + distance(value_first, value_last)) の対応する要素に割り当てられます。

コンパレーターが指定されない場合、operator< を使用して検索値が検索対象範囲内の各要素よりも小さいか判断します。

[start, end) の要素 e は、使用するコンパレーターに関連して分割される必要があります。


法務上の注意書き

The content of this oneAPI Specification is licensed under the Creative Commons Attribution 4.0 International License (英語). Unless stated otherwise, the sample code examples in this document are released to you under the MIT license (英語).

This specification is a continuation of Intel’s decades-long history of working with standards groups and industry/academia initiatives such as The Khronos Group*, to create and define specifications in an open and fair process to achieve interoperability and interchangeability. oneAPI is intended to be an open specification and we encourage you to help us make it better. Your feedback is optional, but to enable Intel to incorporate any feedback you may provide to this specification, and to further upstream your feedback to other standards bodies, including The Khronos Group SYCL* specification, please submit your feedback under the terms and conditions below. Any contribution of your feedback to the oneAPI Specification does not prohibit you from also contributing your feedback directly to other standard bodies, including The Khronos Group under their respective submission policies.

By opening an issue, providing feedback, or otherwise contributing to the specification, you agree that Intel will be free to use, disclose, reproduce, modify, license, or otherwise distribute your feedback at its sole discretion without any obligations or restrictions of any kind, including without limitation, intellectual property rights or licensing obligations.

This document contains information on products, services and/or processes in development. All information provided here is subject to change without notice.

© Intel Corporation. Intel、インテル、Intel ロゴ、その他のインテルの名称やロゴは、Intel Corporation またはその子会社の商標です。

* その他の社名、製品名などは、一般に各社の表示、商標または登録商標です。

« パート 4        目次        パート 6 »
タイトルとURLをコピーしました