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_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; |
指定した位置の要素の参照を返します。 |
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 コンストラクターに渡す必要があります。 |