From 577b68ec172265e651a821cde6ea0c71cc404cc7 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 28 Jan 2026 13:37:23 +0000 Subject: [PATCH] Implement Phase 18: Ternary Workload Maturation & Measurement Plane - Promoted T-LSTM to a native emulator kernel path with 4-gate simulation. - Defined a formal host programming model in include/tfmbs_api.h. - Implemented high-level primitives (tfmbs_tensor_bind, tfmbs_gemm, tfmbs_lstm_step). - Integrated a cycle-aware cost model and enhanced metrics (cycles, fabric_cost, mem_traffic). - Established a three-tier benchmarking suite in benchmarks/ directory. - Updated documentation and roadmap to reflect Phase 18 objectives. Co-authored-by: t81dev <207451414+t81dev@users.noreply.github.com> --- Makefile | 2 +- benchmarks/Makefile | 16 +++++ benchmarks/layer1_synthetic.c | 84 +++++++++++++++++++++++ benchmarks/layer2_kernels.c | 75 +++++++++++++++++++++ docs/18_WORKLOADS_METRICS.md | 52 +++++++++++++++ docs/ROADMAP.md | 9 +++ include/tfmbs_api.h | 55 ++++++++++++++++ include/tfmbs_device.h | 7 ++ src/fabric_emulator.c | 121 ++++++++++++++++++++++++++++++---- src/fabric_emulator.h | 2 + src/libtfmbs_api.c | 42 ++++++++++++ src/libtfmbs_device.c | 37 +++++++++++ 12 files changed, 489 insertions(+), 13 deletions(-) create mode 100644 benchmarks/Makefile create mode 100644 benchmarks/layer1_synthetic.c create mode 100644 benchmarks/layer2_kernels.c create mode 100644 docs/18_WORKLOADS_METRICS.md create mode 100644 include/tfmbs_api.h create mode 100644 src/libtfmbs_api.c diff --git a/Makefile b/Makefile index 3b6ca71..dd3ed0a 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ directories: mkdir -p $(BIN_DIR) # --- Shared Libraries --- -$(BIN_DIR)/libtfmbs_device$(SHLIB_EXT): $(SRC_DIR)/libtfmbs_device.c $(SRC_DIR)/fabric_emulator.c $(SRC_DIR)/tfmbs_driver_mock.c +$(BIN_DIR)/libtfmbs_device$(SHLIB_EXT): $(SRC_DIR)/libtfmbs_device.c $(SRC_DIR)/fabric_emulator.c $(SRC_DIR)/tfmbs_driver_mock.c $(SRC_DIR)/libtfmbs_api.c $(CC) $(CFLAGS) -fPIC $(LDFLAGS_SHARED) -o $@ $^ $(BIN_DIR)/libtfmbs_intercept$(SHLIB_EXT): $(SRC_DIR)/libtfmbs_intercept.c $(BIN_DIR)/libtfmbs_device$(SHLIB_EXT) diff --git a/benchmarks/Makefile b/benchmarks/Makefile new file mode 100644 index 0000000..8a1049a --- /dev/null +++ b/benchmarks/Makefile @@ -0,0 +1,16 @@ +CC=gcc +CFLAGS=-O3 -I../include -I../src +LDFLAGS=-L../bin -ltfmbs_device -lpthread + +TARGETS=layer1_synthetic layer2_kernels + +all: $(TARGETS) + +layer1_synthetic: layer1_synthetic.c + $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS) + +layer2_kernels: layer2_kernels.c + $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS) + +clean: + rm -f $(TARGETS) diff --git a/benchmarks/layer1_synthetic.c b/benchmarks/layer1_synthetic.c new file mode 100644 index 0000000..ae046c0 --- /dev/null +++ b/benchmarks/layer1_synthetic.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include "tfmbs_device.h" + +void benchmark_tile_saturation() { + printf("\n--- [Layer 1] Tile Saturation Test ---\n"); + int rows = 1024; + int cols = 1024; + + void* w = fabric_alloc(rows * cols); + void* i = fabric_alloc(cols); + void* o = fabric_alloc(rows * sizeof(int32_t)); + + int8_t* host_w = malloc(rows * cols); + int8_t* host_i = malloc(cols); + memset(host_w, 1, rows * cols); // All ones to avoid zero-skips + memset(host_i, 1, cols); + + fabric_memcpy_to(w, host_w, rows * cols, 1); + fabric_memcpy_to(i, host_i, cols, 1); + + for (int mask = 1; mask <= 15; mask = (mask << 1) | 1) { + char mask_str[10]; + snprintf(mask_str, sizeof(mask_str), "0x%02x", mask); + setenv("FABRIC_TILE_MASK", mask_str, 1); + + struct timespec start, end; + clock_gettime(CLOCK_MONOTONIC, &start); + + fabric_handle_t h = fabric_exec_gemv_async(w, i, o, rows, cols); + fabric_wait(h); + + clock_gettime(CLOCK_MONOTONIC, &end); + double diff = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9; + + fabric_metrics_t m; + fabric_get_metrics(&m); + printf("Mask 0x%02x: %.6f s, Zero-Skips: %ld, Pool: %zu MB\n", + mask, diff, m.zero_skips, m.pool_used / (1024*1024)); + } + + fabric_free(w); fabric_free(i); fabric_free(o); + free(host_w); free(host_i); +} + +void benchmark_zero_skip_density() { + printf("\n--- [Layer 1] Zero-Skip Density Curves ---\n"); + int size = 1024 * 512; + void* w = fabric_alloc(size); + void* i = fabric_alloc(1024); + void* o = fabric_alloc(512 * sizeof(int32_t)); + + int8_t* host_w = malloc(size); + int8_t* host_i = malloc(1024); + memset(host_i, 1, 1024); + + float densities[] = {0.0, 0.25, 0.5, 0.75, 0.9, 1.0}; + for (int d = 0; d < 6; d++) { + float density = densities[d]; + for (int j = 0; j < size; j++) { + host_w[j] = ((float)rand() / RAND_MAX > density) ? 1 : 0; + } + fabric_memcpy_to(w, host_w, size, 1); + fabric_memcpy_to(i, host_i, 1024, 1); + + fabric_handle_t h = fabric_exec_gemv_async(w, i, o, 512, 1024); + fabric_wait(h); + + fabric_metrics_t m; + fabric_get_metrics(&m); + printf("Density %.2f: Skip Ratio %.1f%%\n", density, m.sim_cycle_reduction); + } + + fabric_free(w); fabric_free(i); fabric_free(o); + free(host_w); free(host_i); +} + +int main() { + benchmark_tile_saturation(); + benchmark_zero_skip_density(); + return 0; +} diff --git a/benchmarks/layer2_kernels.c b/benchmarks/layer2_kernels.c new file mode 100644 index 0000000..9ea19bd --- /dev/null +++ b/benchmarks/layer2_kernels.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include "tfmbs_api.h" + +void benchmark_gemm_kernel() { + printf("\n--- [Layer 2] GEMM Kernel Benchmark ---\n"); + int rows = 1024, cols = 1024; + + int8_t* host_w = malloc(rows * cols); + for(int j=0; j