読者です 読者をやめる 読者になる 読者になる

Paraisoが生成するC++コードのAPI

ICFDP


今回は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 () ;
};