はじめに
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つの整数の加算をするサンプルプログラムを見てみます。