Vengineerの妄想

人生を妄想しています。

Graphcore : Poplar Tutorial (その2)

@Vengineerの戯言 : Twitter
SystemVerilogの世界へようこそすべては、SystemC v0.9公開から始まった 

tutorials/poplar/tut2_operations/complete/tut2_complete.cpp では、プログラムに popopsのOpを追加しています。

popops::add を使って、v1+v2 => v3 , v3+v2 => v4, v1+v2.transpose => v5 にしています。

// Extend program with elementwise add (this will add to the sequence)
Tensor v3 = popops::add(graph, v1, v2, prog, "Add");
prog.add(PrintTensor("v3", v3));

// Use the result of the previous calculation
Tensor v4 = popops::add(graph, v3, v2, prog, "Add");
prog.add(PrintTensor("v4", v4));

// Example element wise addition using a transposed view of the data
Tensor v5 = popops::add(graph, v1, v2.transpose(), prog, "Add");
prog.add(PrintTensor("v5", v5));

 https://github.com/graphcore/examples/blob/master/tutorials/poplar/tut3_vertices/complete/tut3_complete.cpp では、Vertex を生成し、何らかのOpを実行する例題です。

graph.addComputeSetにて、ComputeSet を生成し、そのComputeSetに Op を割りあてた Vertex を追加しています。Vertexの入力は、v1.slice(i,4) を4つ、出力はv[i]を4つ。このVertex(vtx)を 0~3 の Tile に割当、処理時間として20を割り当てています。

    ComputeSet computeSet = graph.addComputeSet("computeSet");
    for (unsigned i = 0; i < 4; ++i) {
        VertexRef vtx = graph.addVertex(computeSet, "SumVertex");
        graph.connect(vtx["in"], v1.slice(i, 4));
        graph.connect(vtx["out"], v2[i]);
        graph.setTileMapping(vtx, i);
        graph.setCycleEstimate(vtx, 20);
    }

生成した Vertexの実行(Execute) を Program に追加します。上の popops の add と同じで感じです。

    // Add step to execute the compute set
    prog.add(Execute(computeSet)); 

SumVertex は、下記のように、C++のクラスとして実装し、compute メソッドで実際の処理を行っています。入力は、poplar::Input の in 、出力あh、poplar::Output の out になります。

class SumVertex : public poplar::Vertex {
    public:
    // Fields
        poplar::Input<poplar::Vector<float>> in;
        poplar::Output<float> out;

    // Compute function
    bool compute() {
        *out = 0;
        for (const auto &v : in) {
            *out += v;
        }
        return true;
     }
};