Skip to main content

Native CastTess boundary

Use simaai/kernels/ops/casttess.h for the shared tensor contract and simaai/kernels/ev74/casttess.h for the host codec. Link SimaKernels::casttess. These host targets do not require MetaWare, ConfigManager, JSON, GStreamer or Core private headers.

Contract​

The authoritative CastTess contract applies to both backends. Explicit input and output specifications have the same logical shape, with one through six axes. Rank-zero scalars are unsupported. Empty tensors need zero storage and produce no numerical device invocation.

Input dtypeInput layoutOutput
FP32Contiguous or admitted byte stridesMlaTiled BF16
IEEE FP16Contiguous or admitted byte stridesMlaTiled BF16
BF16Contiguous or admitted byte stridesBit-preserving MlaTiled BF16

Input strides must be nonnegative, scalar-aligned and conservatively provable as nonoverlapping; a zero stride is admitted only for an extent of at most one. Output is neither an arbitrary strided tensor nor MlaCBlocked. Relabeling a buffer does not convert between those layouts.

Parameters​

Params is empty. Dtype selects conversion; output MlaTiled metadata specifies axis mapping, tile extents and Compact or PadTo16 channels. There is no model name, input JSON, hidden quantization parameter or caller-selected fast-path enum.

Numerical behavior​

Conversion happens before packing into the final byte planes:

  1. FP32: apply the existing Cast unsigned-bit rule, (bits + 0x7fff + ((bits >> 16) & 1)) >> 16, with 32-bit wraparound. This rule also governs NaNs: it is not NaN canonicalization.
  2. FP16: exact bit-domain conversion with nearest-even BF16 rounding. Preserve signed zeros, subnormals and infinities. Quiet NaNs while preserving sign and the high payload bits. Normal, subnormal and special-value paths have the same semantics as A65 CastTess.
  3. BF16: preserve all 16 input bits, including NaN payloads.
  4. Write each pixel's low channel bytes, then its high channel bytes. Write zero for required channel padding and the trailing padding of every physical tile.

Integer SIMD/scalar operations implement these conversions; the native path does not depend on the host floating-point environment or introduce FP32 arithmetic for BF16 tessellation. Fusion removes an intermediate converted tensor, not a rounding boundary or required output padding.

C++ call​

The A65 call shows tensor specification and shared metadata preparation. For EV placement, hand that typed request to an EV74 Executor configured with a verified transport, then submit retained input/output buffer views. The hardware argument alone does not configure a transport. Follow the connection recipe in the matching Runtime package's docs/linux-cvu.md. For its Linux CVU adapter, enable Options::probe_casttess only for matching firmware, then pass the connected transport in ExecutorOptions::ev74. Runtime's synchronous convenience method only submits and waits. Do not pass CPU pointers as EV bus addresses.

The host codec exposes this lower-level sequence for a transport integrator:

ops::casttess::check_inference(request)
→ ev74::casttess::check_inference(plan)
→ encode_relocatable(plan)
→ retained DMA-BUF bindings and driver relocations
→ native capability-verified asynchronous submission
→ confirmed retirement and coherency completion

Alternatively, bind(plan, invocation, input_region, output_region) produces a per-call descriptor for already resolved EV-visible regions. The checked plan and template must agree. Callers do not need a separate optional check_input(); preparation and binding make these checks part of the call lifecycle.

Place the includes and namespace aliases at file scope; the remaining statements belong in a simaai::kernels::Status-returning caller function. It checks metadata and encodes a relocatable descriptor, not EV74 computation. Runtime must map actual buffers, bind addresses and retain inputs, outputs and any workspace until confirmed device completion.

#include <array>
#include <simaai/kernels/ev74/casttess.h>
#include <simaai/kernels/ops/casttess.h>

namespace k = simaai::kernels;
namespace op = k::ops::casttess;
namespace ev = k::ev74::casttess;
k::MlaTiled tiled;
tiled.axes = {-1, -1, 0, 1}; // Shape [W,C], with an explicit channel axis.
tiled.tile_shape = {1, 1, 2, 3};
const std::array inputs{k::TensorSpec{{2, 3}, k::DType::Float32}};
const std::array outputs{k::TensorSpec{{2, 3}, k::DType::BFloat16, tiled}};
const op::Request request{inputs, outputs, op::Params{}};
auto checked = op::check_inference(request);
if (const auto *error = std::get_if<k::Error>(&checked)) return *error;
const auto &plan = std::get<op::Plan>(checked);
auto encoded = ev::encode_relocatable(plan);
if (const auto *error = std::get_if<k::Error>(&encoded)) return *error;
// Encoding leaves device addresses unbound; no device work has run.
return {};

See the host contract tests (EV74/casttess/tests/correctness.cpp) and device fixture (EV74/casttess/tests/runtime_e2e.cpp) for binding and execution coverage.

Memory and lifecycle​

The kernel computes physical output storage from tile boundaries, channel padding and 16-byte tile alignment. Logical elements × two is not generally the output capacity. Input addresses need scalar alignment; output addresses need 16-byte alignment. Accessed input/output spans must not overlap.

The MLA layout contract defines outer axes and C,D,H,W tile traversal. Actual boundary extents are stored rather than padded logical dimensions. Within each tile, pixels follow D,H,W order and use separate low/high BF16 channel-byte planes. Required padding is zero on every call, even when a previously larger output allocation is reused. Input holes and capacity beyond the required output span remain untouched.

Runtime owns allocation, mapping, descriptor upload, coherency and lifetime. Submission acceptance is not retirement. Retain tensor storage, descriptors and mapping leases until confirmed numerical completion; a timeout is not permission to free them. No whole-tensor scratch, CPU packing or Runtime preclear is needed.

Implementation notes​

Native descriptor and platform composition​

simaai_kernels_ev74_casttess_v1 consumes a 216-byte version-1 little-endian payload. Fields encode conversion, rank, logical sizes, input byte strides, physical storage spans and the output axis/tile/channel mapping. Address slots at offsets 24/32 are 64-bit wire values constrained to EV's 32-bit address domain. The descriptor is not a C++ object and contains no per-tile job list.

Host metadata admission rejects invalid requests early. The native entry also validates descriptor integrity, shape/stride/layout arithmetic, physical spans, alignment and patched addresses before dispatch. These checks protect the device boundary; they do not move configuration parsing into the kernel.

Runtime's native-only transport epoch-2 composition assigns route 48 (0x30) and probes this exact capability after transport discovery. Dispatcher instrumentation uses private 0xF0, absent from production. Missing capability fails closed; there is no hidden A65 fallback or reinterpretation of unmatched payloads.

Bounded local work and parallel ownership​

The native entry derives at most 16 full/boundary tile classes and fixed weighted suffix tables. This bounds preparation/control metadata independently of tensor size. Cached dtype-specific kernel handles avoid repeated handle creation. The first task in a worker's range is decoded from the weighted tables. Subsequent tiles advance C,D,H,W coordinates with carry; crossing an outer slice uses the general decoder again. Checked wire/control arithmetic stays 64-bit. Reachable panel offsets and tile coordinates use 32-bit arithmetic after native admission proves that both nonempty spans fit the device address domain. Unused singleton strides remain valid even when their metadata exceeds 32 bits. Worker-range partitioning and the physical-block fallback retain some wide arithmetic. CPU0 handles a single task. Parallel requests launch the complete configured ring, capped at four workers; workers without an assigned task return. This avoids treating a partial physical CPU ring as a dense logical range while preserving physical CPU IDs for VCCM/DMA ownership.

Work is split into bounded linear D,H,W pixel bands and channel panels, not one allocation or host submission per physical tile. Each worker has two local source/output slots: 16 KiB source plus 8 KiB output per slot, 48 KiB total. Panels hold at most 4,096 conversion elements; a large tile is processed in multiple panels rather than requiring tile-sized VCCM.

  • Contiguous channels use source DMA. Pitched pixel rows can use 2D DMA. BF16 single-channel tails also use exact-width 2D gathering for strided rows of 16–63 pixels when their complete band contains at least 64 pixels and the source pitch fits the 16-bit DMA range. Each transfer reads exactly two bytes per pixel into the existing compact input slot. Shorter rows/bands retain scalar gathering, and rows already meeting the normal 128-byte threshold retain the normal DMA path. This changes movement, not BF16 payloads, compact SIMD packing, Pad16 initialization or task ownership. The BF16 instantiation is isolated from FP32/FP16 to keep their instruction bodies unchanged. For channel-subtiled images with at most 64 source channels and contiguous C, bounded power-of-two bands can stage complete source pixels. FP32/FP16 require adjacent pixels along W. BF16 also permits pixel padding when its byte stride satisfies 2 * source_channels <= stride_W <= INT32_MAX. Each staged band contains at most 4,096 source elements. The packer selects the task's channels locally. This trades repeated logical input bytes across channel tiles for fewer small DMA descriptors; it does not change output ownership.

    For a padded BF16 pixel row, 2D DMA copies 2 * source_channels bytes per pixel with source pitch stride_W and compact destination pitch 2 * source_channels. A transfer stops at the current W segment; the worker then advances through H/D using the admitted strides. Pixel padding and row holes are not included in the transfer width, and the final pixel is read only through its last logical channel. Rows below the normal DMA threshold retain scalar reads of those same logical channels. No extra source capacity or speculative read beyond the admitted input span is required.

    For BF16, a metadata-selected worker packs byte planes directly from these staged complete pixels, without first compacting a channel subtile. Its entry checks every tile class: regular bands rather than physical-block fallback, one channel panel, bounded full-channel staging, and stored channel planes divisible by sixteen. Other physical plane widths retain the general implementation, including compact small-channel SIMD packing. A one-channel Pad16 tail inserts its payload into two zero vectors. Other partial Pad16 planes clear only their final owned sixteen-byte blocks before writing valid tail lanes, without extending stores beyond the row. It preserves all BF16 payload bits and zeroes owned padding; other layouts and dtypes retain their existing workers. The worker shares task and DMA source with the general implementation but compiles separately to isolate register and stack usage. The local transpose helper also has a scalar/pointer outlined interface; no vector-valued helper ABI crosses these boundaries.

  • A whole-panel H-contiguous path stages C,D,W,H order with 2D DMA, converts sequential values to BF16 in place in the source slot, and transposes locally into the final byte planes. Each complete sixteen-channel group uses a native local halfword gather, then writes the low and high byte vectors separately. Fewer than sixteen remaining channels use scalar reads; padding is initialized independently. The gathers neither reinterpret BF16 as FP16 nor change conversion rounding. It requires a single regular panel, H extent greater than one, scalar-width H stride, a signed-representable W pitch and at least 128 input bytes. Partial panels and irregular layouts retain the general gather path. There is no additional tensor-sized or per-worker scratch allocation.

  • SIMD packing handles 16-channel vectors and compact one-to-four-channel pixel batches. A one-channel PadTo16 tail writes two zero-initialized byte vectors with the converted value inserted in lane zero. Scalar tails preserve the same conversion rules.

  • Large channel planes divisible by 16 can split into disjoint channel panels. Regular bands use a pixel-count multiple of 8 / gcd(stored_channels, 8), so each task owns whole 16-byte output blocks. The final task includes tile alignment padding in its local output before writing. Giant compact planes not divisible by 16, or channel counts whose aligned band cannot fit a local slot, use aligned 4 KiB physical-output blocks instead. This avoids separate workers writing unaligned pieces of the same plane. The fallback can convert an element twice, once per byte plane; it trades redundant bounded work for explicit output ownership.

  • Required padding belongs to the writing task. There is no separate whole-output clearing pass.

Input completion precedes conversion. Output completion precedes reuse of that output slot. All pending output DMA completes before the numerical entry returns. These are correctness and working-set properties, not evidence of a speedup or uniform latency across every input/output address phase.

Current performance limits​

The fast paths are layout-specific, not a claim of uniform latency. Small calls can be dominated by Runtime submission/completion. Irregular strided inputs and multi-panel H-contiguous tiles still use gathers; staged channel subtiles may read some source values more than once. Required padding and physical-output traffic remain real costs. Compare retained-buffer address phases, all worker counts and fallback neighbors before changing panel sizes or choosing assembly.

Report host CPU time per operation separately from wall latency. Faster device execution may increase CPU percentage without increasing CPU cost. These paths keep packing on EV74 and preserve asynchronous Runtime submission and blocking completion; they do not add A65 per-tile work or busy polling. Correctness alone does not imply lower latency than A65 or another device implementation.

Tests and qualification​

Host tests cover shared admission, native encoding/decoding and mocked dispatch. They do not execute EV SIMD/DMA. The private device target uses the approved CMake/MetaWare environment; successful compilation is not a simulator run or hardware qualification.

Runtime's single casttess_cvu_e2e fixture has an independent conversion/layout oracle, including a literal small-byte golden. Its catalogue contains 900 generated combinations (300 per dtype), 99 explicit large-panel/spatial-tile cases, 30 H-contiguous eligibility/boundary cases, three empty cases and four exhaustive FP16/BF16 input-bit sweeps across ordinary and H-contiguous paths. Four strided BF16 tail cases cross W/H/D and outer boundaries, mixing short scalar rows and exact-width DMA rows with compact and Pad16 outputs. It checks full physical output including padding, guards, input holes, repeated calls and dirty output reuse. Correctness under one, two, three and four workers and the uninstrumented complete operation suites are separate device acceptance steps.

Latency runs by default: 18 ordinary cases and 48 retained input/output address phase cases, with process CPU accounting. Reference/setup work is outside timing. Only the established paired median policy gates latency; p95/max remain diagnostic. Keep raw results outside the source repository. This page describes the implementation and fixtures, not a claim that unrecorded device or latency qualification has passed.

Use casttess_cvu_e2e --correctness-only for an explicitly scoped correctness rerun. Running it without options continues to include all latency cases.

Shared bounded readers and final storage​

The private reader chooses an eligible physical rectangle before the small-work cutoff, so a short source row does not force a whole-job scalar path when several rows fit a useful bounded panel. Final BF16 byte-plane packing stays fused with conversion. Private traversal and weighted tile tasks retain every compressed edge, outer coordinate, padding byte and DMA-event retirement requirement.