Skip to main content

logicaffeine_compile/codegen_tt/
runtime.rs

1//! Fixed templates for the emitted TT-Metalium program: the compute-kernel
2//! preamble, the host orchestrator, and the CMake build glue. [`super::wrap`]
3//! splices the LOGOS→C compute body between the kernel preamble and the
4//! `kernel_main()` entry, and substitutes the `{KERNEL_FILE}` token in the host
5//! and CMake with [`super::KERNEL_FILE_NAME`].
6
7/// Prepended to the LOGOS→C compute body to form the compute kernel. Brings in
8/// the TT-Metalium data-movement + DPRINT APIs and bridges the C backend's
9/// `printf`/`puts` (how `Show` is emitted) to the host DPRINT stream, so kernel
10/// output is textually identical to the VM's.
11pub const TT_KERNEL_PREAMBLE: &str = r#"// Auto-generated by LOGOS codegen_tt — do not edit.
12// TT-Metalium compute kernel: runs a whole LOGOS program on ONE Tensix baby
13// RISC-V core (DataMovementProcessor::RISCV_0). `Show` output is streamed to the
14// host via the DPRINT server. The compute body below is the LOGOS→C lowering —
15// byte-for-byte equal to the VM (locked by the host oracle in tenstorrent_aot_lock).
16#include "dataflow_api.h"
17#include "debug/dprint.h"
18
19// --- Show bridge -------------------------------------------------------------
20// The C backend prints with printf/puts; on-core we format into a small stack
21// buffer and stream it through DPRINT so the host sees identical text.
22#ifndef LOGOS_TT_SHOW_BRIDGE
23#define LOGOS_TT_SHOW_BRIDGE
24#define printf(...) do { char _logos_lb[256]; snprintf(_logos_lb, sizeof _logos_lb, __VA_ARGS__); DPRINT << _logos_lb; } while (0)
25#define puts(_s)    do { DPRINT << (_s) << ENDL(); } while (0)
26#endif
27// --- LOGOS→C compute body ----------------------------------------------------
28"#;
29
30/// The host orchestrator. Opens a 1x1 unit mesh on device 0, creates a program
31/// with a single data-movement kernel on `RISCV_0`, launches it, waits, and
32/// closes. Targets the current TT-Metalium `MeshDevice` API (as in the
33/// `add_2_integers_in_riscv` example). `{KERNEL_FILE}` is the kernel source path.
34pub const TT_HOST_TEMPLATE: &str = r#"// Auto-generated by LOGOS codegen_tt — do not edit.
35// Host orchestrator for a single-Tensix-core LOGOS program.
36#include <tt-metalium/host_api.hpp>
37#include <tt-metalium/device.hpp>
38#include <tt-metalium/mesh_device.hpp>
39
40using namespace tt;
41using namespace tt::tt_metal;
42
43int main() {
44    // 1x1 unit mesh on device 0; DPRINT (TT_METAL_DPRINT_CORES) streams `Show` output.
45    auto mesh = distributed::MeshDevice::create_unit_mesh(0);
46    distributed::MeshCommandQueue& cq = mesh->mesh_command_queue();
47
48    Program program = CreateProgram();
49    constexpr CoreCoord core = {0, 0};
50
51    // The whole LOGOS program runs on ONE baby RISC-V core (data-movement 0).
52    KernelHandle compute = CreateKernel(
53        program,
54        "{KERNEL_FILE}",
55        core,
56        DataMovementConfig{.processor = DataMovementProcessor::RISCV_0,
57                           .noc = NOC::RISCV_0_default});
58    SetRuntimeArgs(program, compute, core, {});
59
60    distributed::MeshWorkload workload;
61    workload.add_program(distributed::MeshCoordinateRange(mesh->shape()), std::move(program));
62    distributed::EnqueueMeshWorkload(cq, workload, /*blocking=*/true);
63    Finish(cq);
64
65    mesh->close();
66    return 0;
67}
68"#;
69
70/// CMake glue: builds the host against a built tt-metal checkout (`$TT_METAL_HOME`).
71/// The compute kernel is JIT-compiled from source by tt-metal at runtime, so it is
72/// only referenced by path, never compiled here.
73pub const TT_CMAKE_TEMPLATE: &str = r#"# Auto-generated by LOGOS codegen_tt.
74# Builds the single-Tensix-core host program against a built tt-metal SDK.
75# Requires TT_METAL_HOME to point at a built tt-metal checkout.
76cmake_minimum_required(VERSION 3.16)
77project(logos_tt LANGUAGES CXX)
78set(CMAKE_CXX_STANDARD 20)
79set(CMAKE_CXX_STANDARD_REQUIRED ON)
80if(NOT DEFINED ENV{TT_METAL_HOME})
81  message(FATAL_ERROR "TT_METAL_HOME is not set — point it at a built tt-metal SDK")
82endif()
83add_executable(logos_tt_host logos_tt_host.cpp)
84target_include_directories(logos_tt_host PRIVATE
85  $ENV{TT_METAL_HOME}
86  $ENV{TT_METAL_HOME}/tt_metal
87  $ENV{TT_METAL_HOME}/tt_metal/api)
88target_link_directories(logos_tt_host PRIVATE $ENV{TT_METAL_HOME}/build/lib)
89target_link_libraries(logos_tt_host PRIVATE tt_metal)
90# Kernel source (JIT-compiled by tt-metal at runtime): {KERNEL_FILE}
91"#;