Skip to content

Architecture

torch_tvarant follows the standard PyTorch PrivateUse1 out-of-tree backend pattern.

┌─────────────────────────────────────────────────────────┐
│  Python: torch_tvarant / torch.device("tvarant")        │
│  torch_tvarant.compiler (FX fusion + torch.compile)     │
└──────────────────────────┬──────────────────────────────┘
                           │
┌──────────────────────────▼──────────────────────────────┐
│  ATen dispatch (PrivateUse1)                            │
│  csrc/aten/Ops.cpp, LlmOps.cpp, CustomOps.cpp           │
└──────────────────────────┬──────────────────────────────┘
                           │
┌──────────────────────────▼──────────────────────────────┐
│  TvarantRuntime (abstract)                              │
│  csrc/runtime/TvarantRuntime.h                          │
├─────────────────────┬───────────────────────────────────┤
│  CpuSimRuntime      │  OpenCLRuntime                    │
│  (host memory)      │  (cl_mem buffers)                 │
└─────────┬───────────┴───────────────┬───────────────────┘
          │                           │
┌─────────▼───────────┐   ┌───────────▼───────────────────┐
│  HostKernels        │   │  OpenCL .cl kernels           │
│  csrc/kernels/host/ │   │  csrc/kernels/opencl/         │
└─────────────────────┘   │  + JIT codegen (csrc/jit/)    │
                          └───────────────────────────────┘

Runtime selection

At import time, initialize_runtime() reads TVARANT_BACKEND:

Value Runtime Memory
sim (default) CpuSimRuntime Host-accessible aligned buffers
opencl / fpga OpenCLRuntime OpenCL device buffers

Kernel launch model

All ops build a LaunchParams struct and call runtime().launch():

LaunchParams p;
p.kernel = "gemm_bias_act_kernel";
p.src0 = a.data_ptr();
p.src1 = b.data_ptr();
p.src2 = bias_ptr;
p.dst = out.data_ptr();
p.m = m; p.n = n; p.k = k;
p.act = act_id;  // 0=none, 1=relu, 2=silu
runtime().launch(p);

The sim runtime dispatches to C++ host functions; OpenCL enqueues NDRange kernels with local_work_size = 32 (Tvarant SIMT width).

JIT layer

Pointwise fusion uses an SSA IR (csrc/jit/Jit.h):

  • Sim: interpret program in a single host loop
  • OpenCL: codegen OpenCL C → clBuildProgram → cache by program hash

GEMM fusion (gemm_bias_act) is a hand-written kernel, not JIT-generated.

CPU fallback

Unregistered ATen ops fall back to CPU via cpu_fallback in Ops.cpp. This keeps models running but may hurt performance — register native ops for hot paths.

File map

Path Role
csrc/Module.cpp pybind11 module, device API
csrc/runtime/Allocator.cpp PyTorch allocator integration
csrc/aten/Ops.cpp Core tensor ops
csrc/aten/LlmOps.cpp LLM-specific ATen ops
csrc/aten/CustomOps.cpp tvarant.* custom ops
csrc/jit/Jit.cpp Pointwise IR + OpenCL codegen
torch_tvarant/compiler.py FX graph fusion passes