Paraisoが生成するC++コードのAPI
今回はParaisoが生成するコードの使い方を見ていきます。HelloWorld
フォルダでGenerator.hs
を実行すると、dist
というフォルダが作られてその下にC++のヘッダやソースが生成されているはずです。まずはヘッダを見てください。
class TableMaker{ private: std::vector<int> om_s0_table; private: int om_s1_total; private: std::vector<int> om_m0_5; public: TableMaker () : om_s0_table(om_memory_size()), om_m0_5(om_memory_size()) { }
このように、静的変数のための記憶領域やコンストラクタが定義されています。Paraisoの生成するクラスは、この他にもいくつかのアクセッサ関数を定義します。まずは、OMのサイズを取得するための関数がこちらです。全領域のサイズおよび、各次元ごとのサイズを取得できます。(これサイズがint
型なのはまずいな・・・)
public: int om_size () { return 200; } public: int om_size_0 () { return 10; } public: int om_size_1 () { return 20; }
Paraisoが副次的に生成する関数の名前はすべてom_
から始まるようになっています。ユーザーは静的変数やカーネルに、すべて異なり、かつどれもom_
から始まらないような名前をつけてください。そうすればコード生成時に名前が衝突することはありません。
今のHelloWorld
カーネルにはありませんが、配列変数で、近傍の値をとってくるshift
命令を含むカーネルをコンパイルすると、Paraisoは通信のための余白領域を確保し、[0..size-1]
までの領域が無事に計算できるようにします。この場合、実際に確保されたメモリの大きさはom_size()
等が返す値よりも大きくなります。このメモリサイズを取得できる関数群がom_memory_size()
などです。
public: int om_memory_size () { return 200; } public: int om_memory_size_0 () { return 10; } public: int om_memory_size_1 () { return 20; }
そしてこれが余白を取得する関数群です。
public: int om_lower_margin_0 () { return 0; } public: int om_lower_margin_1 () { return 0; } public: int om_upper_margin_0 () { return 0; } public: int om_upper_margin_1 () { return 0; }
Array変数に対しては要素へのアクセッサが、Scalar変数に対しては単なるアクセッサが定義されます。
public: int & table (int i0, int i1) { return (om_s0_table)[((om_lower_margin_0()) + (i0)) + ((om_memory_size_0()) * ((om_lower_margin_1()) + (i1)))]; } public: int & total () { return om_s1_total; }
また、配列の生データへのアクセッサも提供されますが、「生」データが具体的にどんなフォーマットなのかは実装の詳細に依存します。
public: std::vector<int> & table () { return om_s0_table; }
最後に、OMの定義で与えたカーネルに対応するメソッドが生成されます。
public: void create () ; };