gfx_factory クラス

概要

gfx_factory クラスは、インテル® TBB ベースのプログラムの汎用計算でインテル® グラフィックス・テクノロジーの使用を簡略化する、streaming_node の Factory コンセプトを実装します。

注意

gfx_factory の現在の実装は、メモリー・バッファー・オブジェクトを同時に使用することを許可していません。そのため、gfx_factory でカスタマイズされた複数のストリーミング・ノードを互いに接続することはできません。

構文

class gfx_factory;

ヘッダー

#define TBB_PREVIEW_FLOW_GRAPH_NODES 1
#define TBB_PREVIEW_FLOW_GRAPH_FEATURES 1
#include "tbb/gfx_factory.h"

説明

gfx_factory は、インテル® TBB フローグラフからインテル® プロセッサー・グラフィックスの低レベルの機能を使用した処理 (ターゲットへの入力データをアップロードして、ターゲットでカーネルを実行し、結果をグラフへ返す) を行います。

gfx_factory は、インテル® C++ コンパイラーで提供される API の上に実装され、キューに追加されたユーザー定義のカーネル関数のオフロード、および CPU とプロセッサー・グラフィックス間のデータ共有を制御します。gfx_factory を使用するには、インテル® C++ コンパイラー 16.0 以降が必要です。

API の詳細は、『インテル® C++ コンパイラー 18.0 デベロッパー・ガイドおよびリファレンス』の「最適化およびプログラミング・ガイド」 > 「インテル® グラフィックス・テクノロジー」 > 「インテル® グラフィックス・テクノロジー向けのプログラミング」 > 「概要: API ベースのオフロード」を参照してください。

カーネル関数

gfx_factory とともに使用するカーネル関数は、インテル® Cilk™ Plus を使用して記述されたデータ並列セクションを含む個別のユーザー定義関数です。関数は、プロセッサー・グラフィックス実行のカーネル・エントリー・ポイントに変換される __declspec(target(gfx_kernel)) で注釈を付ける必要があります。

サンプル

static __declspec(target(gfx_kernel))
void vector_square(int *v, size_t n) {
    cilk_for(size_t i = 0; i < n; ++i) {
        v[i] = v[i] * v[i];
    }
}

GFX バッファー

gfx_factory は、データ配列の抽象化である gfx_buffer テンプレート・クラスを使用します。このクラスは、計算オフロードカーネルがプロセッサー・グラフィックスで実行されている間、ホストとターゲット間でデータ配列を共有する処理を行います。

template <typename T>
class gfx_buffer {
public:

  typedef implementation-defined iterator;
  typedef implementation-defined const_iterator;

  typedef std::size_t size_type;

  gfx_buffer();
  gfx_buffer(size_type size);

  T* data();
  const T* data() const;

  size_type size() const;

  const_iterator cbegin() const;
  const_iterator cend() const;
  iterator begin();
  iterator end();

  T& operator[](size_type pos);
  const T& operator[](size_type pos) const;
};

次の表は、このテンプレート・クラスのメンバーの詳細な情報を提供します。

メンバー

説明

iterator;

const_iterator;

実装により定義されるイテレーター型。

gfx_buffer();

空の gfx_buffer を作成するコンストラクター。

gfx_buffer(size_type size);

特定サイズの gfx_buffer を作成するコンストラクター。要素は T() を呼び出して初期化される値です。

T* data();

const T* data() const;

データ格納配列のポインターを返します。

size_type size() const;

バッファーの要素の数を返します。

iterator begin();

const_iterator cbegin() const;

コンテナーの最初の要素のイテレーターを返します。

iterator end();

const_iterator cend() const;

コンテナーの最後の要素に続く要素のイテレーターを返します。

T& operator[](size_type pos);

const T& operator[](size_type pos) const;

指定した位置の要素の参照を返します。

Device Selector

streaming_node には、特定の計算をオフロードするデバイスを選択するファンクター (Device Selector) が必要です。しかし、基本的な API はインテル® プロセッサー・グラフィックスでのみ動作するため、特定のデバイスを選択するオプションはありません。このため、Factory により提供されるダミーの Device Selector、gfx_factory::dummy_device_selector() を使用する必要があります。

サンプル

次のコードは、単純なベクトル 2 乗のサンプルです。

#include <iostream>

#include <cilk/cilk.h>

#include "tbb/flow_graph.h"
#include "tbb/gfx_factory.h"

static __declspec(target(gfx_kernel))
void vector_square(int *v, size_t n) {
    cilk_for(size_t i = 0; i < n; ++i) {
        v[i] = v[i] * v[i];
    }
}

int main() {
    using namespace tbb::flow;

    typedef tuple< gfx_buffer<int>, size_t > kernel_args;
    typedef streaming_node< kernel_args, queueing, gfx_factory > gfx_node;

    graph g;
    gfx_factory factory(g);

    gfx_node squaring(g, vector_square, gfx_factory::dummy_device_selector(), factory);


    function_node< gfx_buffer<int> > 
        validation(g, unlimited, 
            [](const gfx_buffer<int>& buffer) {
                bool is_correct = std::all_of(buffer.cbegin(), buffer.cend(),
                                                  [](int i) {return i == 4; });
                if (is_correct) {
                    std::cout << "結果は正しい"  << std::endl;
                }
            });

    make_edge(output_port<0>(squaring), validation);

    const size_t array_size = 1000000;
    gfx_buffer<int> buffer(array_size);
    std::fill(buffer.begin(), buffer.end(), 2);

    squaring.set_args(port_ref<0, 1>);
    input_port<0>(squaring).try_put(buffer);
    input_port<1>(squaring).try_put(array_size);

    g.wait_for_all();
}

パブリックメンバー

gfx_factory クラスは、streaming_node で定義される Factory コンセプトを実装します。

詳細は、streaming_node の説明を参照してください。

namespace tbb {
namespace flow {

class gfx_factory {
public:

  typedef implementation-defined device_type;
  typedef implementation-defined kernel_type;

  gfx_factory(tbb::flow::graph& g);

  template <typename ...Args>
  void send_data(device_type device, Args&... args);

  template <typename ...Args>
  void send_kernel(device_type device, const kernel_type& kernel, Args&... args);

  template <typename FinalizeFn, typename ...Args>
  void finalize(device_type device, FinalizeFn fn, Args&... args);

  class dummy_device_selector;
};

}
}

次の表は、このテンプレート・クラスのメンバーの詳細な情報を提供します。

メンバー

説明

device_type;

kernel_type;

実装により定義される型。

gfx_factory(tbb::flow::graph& g);

メイン・コンストラクター。グラフとデバイス間の同期のためにグラフの参照を格納します。

template <typename ...Args>

void send_data(device_type device, Args&... args);

デバイスとデータを共有します。

template <typename ...Args>

void send_kernel(device_type device, const kernel_type& kernel, Args&... args);

カーネルをインオーダー・オフロード・キューに入れます。

template <typename FinalizeFn, typename ...Args>

void finalize(device_type device, FinalizeFn fn, Args&... args);

ノードのサクセサーが存在しない場合、カーネル実行をファイナライズします。

class dummy_device_selector;

ダミーのデバイス・セレクター・ファンクター。streaming_node コンストラクターに渡す必要があります。

関連情報