Repository navigation
Releases
Tesseract Core 1.1.0
Tesseract Core 1.1.0, the RTL and its Alveo U200 card image.
Core capability 1.0. tsr_u200_k4.xclbin.xz is attached; xz -d tsr_u200_k4.xclbin.xz gives tsr_u200_k4.xclbin.
The image needs the platform xilinx_u200_gen3x16_xdma_2_202110_1 and XRT 2.18. See
docs/getting-started.md to load it.
Run it with Tesseract Basis 1.2.0 or later; an older Basis refuses the kernel's chb<c> arguments.
With the dual weight stream, decode runs 1.31 to 1.37 times as fast as on Core 1.0.0 for the seven models of the README table (Gemma 4 26B-A4B Q8_0 13.32 tokens/s, Qwen3.8 27B Q8_0 2.11 tokens/s). The numbers and their conditions are in docs/performance.md.
| Item | Value |
|---|---|
sha256 of tsr_u200_k4.xclbin |
628559646594efde3dc04e40ef79db01f4bc2659d6c5242d3b80ac1b819eb9cc |
sha256 of tsr_u200_k4.xclbin.xz |
f4bdbdd7e6ad7475a758368d25296b36106f8768b8f8a2350e0b539d91bcac16 |
| UUID | c2920184-1184-3844-f252-4c1789b48b2a |
| Clocks | core 200 MHz, RISC-V control core 100 MHz |
CAPS |
0x10121 (vector unit, attention, Gated DeltaNet, dual weight stream) |
Added
- The dual weight stream of the MVM unit (
MVM_DUAL, docs/rtl-mvm.md §15). A cluster reads its rows as two weight streams at once, in lockstep, each through its own front end, and the gather has a second row assembler per cluster. It applies to a weight MVM with T ≤T_MAX/ 2. Results and the memory layout do not change, only timing. - A read-only second memory port per channel on the core and on the kernel (
m_axi_chb<c>, with the argumentschb<c>), each with its own read-only AXI4 bridge.PERF_CH_RD_BEATScounts the beats of both ports. CAPSbit 16MVM_DUAL, andADAPTER_CTRLbit 1DUAL_DIS, which turns the dual weight stream off at run time.CAPSdoes not change with it.- Benches for the dual weight stream: the MVM unit, its back end and the MAC lanes, the core against the simulator, the read-only bridge and the kernel.
- A bandwidth link with two compute units on every DDR bank (
hw/u200/bw/bw2x200.cfg,hw/u200/bw/measure_bw2.sh, andTSR_BW_CFGandTSR_BW_OUTofbuild_bw_xclbin.sh).
Changed
- The Pblock plan of the K4 image. The AXI bridges of channels 1 and 2 with their read-only bridges and the central gather receiver are in the SLR1 Pblock. The row assemblers of stream B are in the Pblock of their cluster.
- The link hook clears the
DONT_PARTITIONmark that the link flow sets on the kernel, before placement.
Tesseract Basis 1.2.0
Tesseract Basis 1.2.0, the firmware SDK and the host side.
Basis ABI 1. Runs on Tesseract Core 1.1.0 and 1.0.0 (capability 1.0); the card image is attached to the core-v1.1.0 release. The op list has 21 kinds. Core 1.1.0 needs this release or a later one.
See docs/getting-started.md to build and run it.
Added
TSR_MVM_DUAL(default 1) controls the dual weight stream of a core withCAPSbit 16MVM_DUAL, the feature of Tesseract Core 1.1.0.TSR_MVM_DUAL=0turns it off: the xrt transport writesADAPTER_CTRLbit 1DUAL_DISat bind (sw/transport/tsr_kdev.cpp), and thesimtransport runs its cycle model with one stream. Output bits do not change, only timing.- The xrt transport accepts the kernel arguments
chb<c>(offset 0x100 + 8c), the read-only port of the second weight stream of channel c. It checks that a kernel has one for every channel or none, and that each uses the memory bank ofch<c>(chb_by_slotinsw/transport/tsr_transport_xrt.cpp). A Basis before 1.2.0 refuses a kernel that has them. - The simulator models
CAPSbit 16: with the run-time enable on, a weight MVM with T ≤ T_MAX / 2 reads two weight streams per channel (docs/rtl-mvm.md§15.7).TSR_SIM_CARD=k4dualis the card image (k4full) with the feature,TSR_SIM_MVM_DUALsets (1) or clears (0) the bit, andTSR_SIM_MEM_RATEbounds the memory rate in weight beats per cycle and channel. Thesimtransport has the bit only withTSR_SIM_CARD=k4dualorTSR_SIM_MVM_DUAL=1, andTSR_SIM_VU=0keeps it. Results do not change. tsr_versions_strprintsMVM_DUALamong theCAPSnames (Tesseract Core 1.0 (VU ATT GDN MVM_DUAL)for the release image), and so dotsr-selftestand the llama.cpp device list. The generated headers haveCAPS_MVM_DUALandADAPTER_CTRL_DUAL_DIS(sw/ctrl/include/tsr/mmio.hpp).tsr_bw --cu NAME[,NAME]drives one named compute unit of a bandwidth image that has several (hw/u200/bw/bw2x200.cfg), or two at once. Two units read the same banks at the same time, in read mode only, and the tool reports per bank the read rate of each unit and their sum (sw/tools/tsr_bw.cpp).tsr-topshows theMEM BWmeter, the read rate of all DDR channels as a share of what the DRAM gives, and a second line in the time series box for the device memory in use. The three meters share one row from 96 columns and take two rows on a narrower terminal.
Changed
tsr-toptakes the stream limit of its DDR panel and of--json(rates.ddr.stream_limit_gbs,pct_stream) as two beats of 64 B per core cycle and channel on a core withCAPSbit 16, the dual weight stream. The new keyrates.ddr.streamsgives the number of weight streams of a cluster. Counted with one beat, the read rate of such a core came out above 100 % of the limit.- Matching a launch trace to a device ignores
CAPS.MVM_DUAL, since the bit changes timing only: traces made on a core without the bit replay on a core with it and the reverse (tsr-trace-replay --device,tsr-selftest --traces). - The profile report page (
sw/tools/prof) is a profiler window: toolbar, launch tree, timeline with a row per unit, and a bottom pane with Summary, Records, Graph and Details tabs.capture_card.shdefaults tobuild/u200/k4/tsr_u200_k4.xclbin, the image thathw/u200/build_xclbin.sh k4writes, and no longer replays the first-ATTPV trace unlessWARM=1.
Fixed
tsr-mtpruns targets without recurrent layers (Gemma 4): it asks for rollback snapshots only when the target is recurrent or hybrid.tsr_mon_readtries for 200 ms and gives the CPU away while the writer stays stopped inside an update. It made 100,000 tries without a pause and returned -3 when none found the page consistent. The ctesttransport_mon, whose writer never pauses, failed now and then for that reason. The test now counts a give-up (-3) apart from a torn page and ends on a number of consistent reads.- The capacity probe of the xrt transport and the capacity check of
tsr-selftestno longer fail on a block that cannot be read. The shell's DDR4 controllers use ECC, and a block that was not written since the xclbin was loaded can hold no valid ECC word: its read fails until it is written. The probe read both blocks of a pair before it wrote them, so the open stopped withcapacity probe ... cannot read the buffer, and the failed read moved the transport tostagedDMA. The newkdev::mem_try_readreads bytes that may never have been written. A block it cannot read is taken as never written: the test writes it, it holds zeros afterward, and one line on stderr names it. The DMA mode stays as it was. - The ctest
tools_top_identityreads PERF after every launch (TSR_MON_PERF_MS=0). With the default interval of 100 ms it failed on a quiet host: the run of the tiny model ended before the first read after the attach was due, and the record it left held no PERF counts.
Tesseract Core 1.0.0
Tesseract Core 1.0.0, the RTL and its Alveo U200 card image.
Core capability 1.0. tsr_u200_k4.xclbin.xz is attached; xz -d tsr_u200_k4.xclbin.xz gives tsr_u200_k4.xclbin.
The image needs the platform xilinx_u200_gen3x16_xdma_2_202110_1 and XRT 2.18. See
docs/getting-started.md to load it
and Tesseract Basis 1.0.0 for the software that runs on it.
| Item | Value |
|---|---|
sha256 of tsr_u200_k4.xclbin |
944ea2b59a436c7e7a60b9915d499e6a501cbefd1673c5ac2ca6fdd6d0f7a5f9 |
sha256 of tsr_u200_k4.xclbin.xz |
42931b8d17574a07033c91c846a64410263c8c41590ce13fba0c215ab1cdcab1 |
| UUID | 7f5e7240-e3e6-de7a-55aa-42fc777c128d |
| Clocks | core 200 MHz, RISC-V control core 100 MHz |
CAPS |
0x121 (vector unit, attention, Gated DeltaNet) |
Added
- Four MVM clusters of 128 MAC lanes, each streaming Q8_0 or Q4_K weights from its own DDR4 channel.
- The 4 MiB scratchpad, the DMA with KV cache stores, and QACT.
- The vector unit, with the attention modes and the fused Gated DeltaNet op.
- The RISC-V control core (Ibex RV32IMC) with its ITCM and DTCM, the issue path with one queue per unit, and the
debug module. - The XRT platform adapter and the U200 kernel tops.
Tesseract Basis 1.1.0
Tesseract Basis 1.1.0, the firmware SDK and the host side.
Basis ABI 1. Runs on Tesseract Core 1.0.0 (capability 1.0); the card image is attached to the core-v1.0.0 release.
See docs/getting-started.md to build and run it.
Added
- Transport hooks for a channel buffer that is larger than the memory behind it:
kdev::buf_bytesandkdev::detect_capacity. Their defaults keepch_bytes, so the simulated kinds do not change. The xrt kind measures the capacity at open (detect_ch_capacity).tsr_mon_cap_readandtsr_mon_cap_writerecord it per card intsr-cap-<bdf>, so an attach open andtsr-topuse what an owner open measured. tsr-selftestchecks the channel capacity: distinct patterns at 0 and at P for every power of two P below the buffer, and the transport's channel size must equal the capacity found. Its memory checks wrote and read back at the same address and could not see a wrap.
Changed
- The nominal core clock of the transport and the tools is 200 MHz, the core clock of the release image, instead of 276.3 MHz. The simulated kinds count device time at it, so a timeout of the same length covers 28 percent fewer core cycles. On xrt the PERF summary takes the clock that the driver reports in sysfs (
kdev::core_clock_hz), and the clock fitted fromDBG_MTIMEonce the session is long enough.tsr_perf_summary.core_hz_fittedsays which one it is: 0 nominal, 1 fitted, 2 platform (TSR_CORE_HZ_*).tsr-selftestreports the PONG DURATION at that clock.tsr-top,tsr-profand the profile report fall back to 200 MHz where no card clock is known. Results do not change. tsr-topshows the device memory in use against the card's DDR as the MEMORY meter. The DDR bar in the header and the bandwidth meter and series are gone.
Fixed
- The xrt transport measures the capacity of each channel at open. The U200 card holds 8 GiB per channel, but the shell's memory topology says 16 GB per bank, so addresses above 8 GiB wrapped and a model of more than about 8 GiB per channel overwrote its own weights. The heap, the KV placement, the range checks and the monitor record now use the measured size,
TSR_XRT_CH_GIBabove it is refused, and a model that does not fit stops withWEIGHT heap full.TSR_ATTACHwrites nothing and takes the capacity that an owner open recorded intsr-cap-<bdf>.tsr-topshows 32 GiB for the card also when no process owns it. - Models that share KV between layers (Gemma 4 E4B) no longer abort in prefill at a large ubatch: the backend copies the K indices that ggml-alloc overwrites before a sharing layer's FLASH_ATTN (SW-89).
Tesseract Basis 1.0.0
Tesseract Basis 1.0.0, the firmware SDK and the host side.
Basis ABI 1. Runs on Tesseract Core 1.0.0 (capability 1.0); the card image is attached to the core-v1.0.0 release. The op list has 21 kinds.
See docs/getting-started.md to build and run it.
Added
- MoE kinds MOE_ROUTE (0x1E) and MUL_MAT_ID (0x1F) at numerics revision 1. MOE_ROUTE takes the softmax of the router logits, selects the k largest (ties to the smaller index, NaN first) and renormalizes their weights. MUL_MAT_ID runs a MUL_MAT per (token, slot) against the expert named by an id in DRAM, with an optional per-expert output scale.
- Gated DeltaNet kinds SOFTPLUS (0x2D), SSM_CONV (0x2E) and GATED_DELTA_NET (0x2F), composed from existing VU operations and the DMA. UNARY accepts func 5, SIGMOID, at revision 1.
- GATED_DELTA_NET revision 2 (SW-78): with
CAPSbit 8 and S_v of 64 or more, each head and token runs the VU's fused GDN op. Other devices and shapes keep revision 1's bits. - Optional kinds MUL_MAT_SCALE and MUL_MAT_SOFTCAP at revision 1, and capability-gated FAST attention score and probability slots. MUL_MAT, FLASH_ATTN and Basis ABI 1 keep their contracts.
- ggml-tesseract lowers the MoE graphs of Gemma 4 26B-A4B and Qwen3-30B-A3B (SW-77) and the Gated DeltaNet layers of Qwen3.5 and Qwen3.8, with the recurrent-state caches as device windows.
- GATED_DELTA_NET reads and writes its state on the cache cell when every sequence keeps its cell (SW-82).
TSR_GDN_CELL=0turns it off. - Multi-token prediction with rollback snapshots (SW-83, SW-85): a context with
n_rs_seq= K lowers to chains of K = 1 records and CPY records of window rows. The pinned llama.cpp drafter runs unchanged (SW-86). - Weight matrices that do not fit one planner tile (the output head) are stored in 2, 4 or 8 row blocks with one MUL_MAT record per block (SW-88).
TSR_HEAD_SPLIT=0keeps them whole. - The PyTorch backend runs on the Basis firmware:
tesseract_torch.QuantLinearand the optesseract::linear_blockstake ggml Q8_0 and Q4_K blocks without conversion (SW-81). - Tools:
tsr-mtp,tsr-top(live monitor, SW-87), the profile report (TSR_DUMP_PLAN,sw/tools/prof/prof_report.py, SW-84),sw/tools/trw_vs_sim.py,klcheck --verify-k. The backend hookggml_backend_tesseract_counters. - Variables:
TSR_SIM_VU=0(a core without VU and attention,CAPS0),TSR_SIM_GDN,TSR_SIM_CARDandTSR_SIM_VU_TIMINGfor thesimtransport;TSR_DUMP_RE,TSR_DUMP_DIR,TSR_OPL_PROF,TSR_OPL_KINDSandTSR_MON.TSR_STATSprints the units' busy cycles.
Changed
- The ITCM budget of the firmware image is 96 KiB instead of 80 KiB (SW-75, amends SW-38).
- The simulator's cycle models follow the RTL (SW-80): VU lanes and latencies, QACT, stores and MVM fill. Results do not change, only cycle counts.
TSR_SIM_LOGtakes aw,prefix (the words of every push).trw dumpoftsr-dbgreads a ring that an earlier process wrote.
Fixed
- A MOE_ROUTE of more than 64 tokens (several tiles) runs on the device (SW-76). Gemma 4 26B-A4B and Qwen3-30B-A3B prefill at the default
-ub 512. - klcheck writes the four M-RoPE position streams in its embedding path, so its embd and floor runs equal the token path.