はじめに
Tenstorrent : TT-Metaliumのその3.今回は、カーネルプログラムのData Moverコアの例を見てみます。
ホスト側のプログラム
前回のホスト側のプログラムとほぼ同じです。カーネルプログラムの紐づけと、SetRuntimeArgs API の数が違うだけです。
#include "tt_metal/host_api.hpp" #include "tt_metal/impl/device/device.hpp" using namespace tt; using namespace tt::tt_metal; int main(int argc, char **argv) { // Initialize Program and Device constexpr CoreCoord core = {0, 0}; int device_id = 0; Device *device = CreateDevice(device_id); CommandQueue& cq = device->command_queue(); Program program = CreateProgram(); // Configure and Create Void DataMovement Kernels KernelHandle void_dataflow_kernel_noc0_id = CreateKernel( program, "tt_metal/programming_examples/hello_world_datamovement_kernel/kernels/dataflow/void_dataflow_kernel.cpp", core, DataMovementConfig{.processor = DataMovementProcessor::RISCV_0, .noc = NOC::RISCV_0_default}); KernelHandle void_dataflow_kernel_noc1_id = CreateKernel( program, "tt_metal/programming_examples/hello_world_datamovement_kernel/kernels/dataflow/void_dataflow_kernel.cpp", core, DataMovementConfig{.processor = DataMovementProcessor::RISCV_1, .noc = NOC::RISCV_1_default}); // Configure Program and Start Program Execution on Device SetRuntimeArgs(program, void_dataflow_kernel_noc0_id, core, {}); SetRuntimeArgs(program, void_dataflow_kernel_noc1_id, core, {}); EnqueueProgram(cq, program, false); printf("Hello, Core {0, 0} on Device 0, I am sending you some data. Standby awaiting communication.\n"); // Wait Until Program Finishes, Print "Hello World!", and Close Device Finish(cq); printf("Thank you, Core {0, 0} on Device 0, for the completed task.\n"); CloseDevice(device); return 0; }
カーネルプログラムの紐づけは、2つあります。一つ目は、下記の部分です。カーネルプログラムのソースコードは、"tt_metal/programming_examples/hello_world_datamovement_kernel/kernels/dataflow/void_dataflow_kernel.cpp"です。このカーネルプログラムは、Data Movement コア の RISCV_0 が実行します。
KernelHandle void_dataflow_kernel_noc0_id = CreateKernel( program, "tt_metal/programming_examples/hello_world_datamovement_kernel/kernels/dataflow/void_dataflow_kernel.cpp", core, DataMovementConfig{.processor = DataMovementProcessor::RISCV_0, .noc = NOC::RISCV_0_default});
もう一つのカーネルプログラムの紐づけは、下記の部分です。カーネルプログラムのソースコードは、"tt_metal/programming_examples/hello_world_datamovement_kernel/kernels/dataflow/void_dataflow_kernel.cpp"で、同じです。このカーネルプログラムは、Data Movement コア の RISCV_1 が実行します。
KernelHandle void_dataflow_kernel_noc1_id = CreateKernel( program, "tt_metal/programming_examples/hello_world_datamovement_kernel/kernels/dataflow/void_dataflow_kernel.cpp", core, DataMovementConfig{.processor = DataMovementProcessor::RISCV_1, .noc = NOC::RISCV_1_default});
SetRuntimeArgs API はそれぞれのカーネルプログラムに対応しています。
SetRuntimeArgs(program, void_dataflow_kernel_noc0_id, core, {}); SetRuntimeArgs(program, void_dataflow_kernel_noc1_id, core, {});
カーネルプログラム
カーネルプログラムは、下記にあります。
Data Movement コアの場合は、void kernel_main の中に書きます (Compute コアの時は、void MAIN でした)。カーネルプログラムでは、DPRINT_DATA0 / DPRINT_DATA1 にてメッセージを表示しています。 0
#include "debug/dprint.h" // required in all kernels using DPRINT #include "dataflow_api.h" void kernel_main() { // Nothing to move. Print respond message. // Make sure to export TT_METAL_DPRINT_CORES=0,0 before runtime. DPRINT_DATA0(DPRINT << "Hello, Master, I am running a void data movement kernel on NOC 0." << ENDL()); DPRINT_DATA1(DPRINT << "Hello, Master, I am running a void data movement kernel on NOC 1." << ENDL()); }
おわりに
今回は、Data Movement コアのサンプルプログラムについて、見ていました。
次回は、2つの整数の加算をするサンプルプログラムを見てみます。