Skip to main content

DetessCast

Experimental C++20 API, package version 0.1.0. Link SimaKernels::a65_detesscast. Shared requests and metadata admission are available through simaai/kernels/ops/detesscast.h and SimaKernels::detesscast. The caller contract below describes supported behavior; implementation notes describe this release, not a stable dispatch or binary ABI promise.

Header: simaai/kernels/a65/detesscast.h (A65/detesscast/backend.h). Typed request: ops::detesscast::Request.

Contract​

simaai/kernels/a65/detesscast.h (A65/detesscast/backend.h) provides checked, synchronous MLA-tiled BF16 → FP32 or BF16 execution. FP16 is deliberately unsupported on both ports. Quantized MLA output belongs to DetessDequant, not this operation.

PropertySupported contract
PortsExactly one input and one output; both specs are explicit.
ShapesEqual logical shape and rank, 1–6 dimensions. Empty tensors are valid; scalars are rejected. No implicit folding or padding of logical axes.
InputBFloat16, MlaTiled or MlaCBlocked, 16-byte-aligned host pointer.
OutputFloat32 or BFloat16, Contiguous or admitted Strided, scalar-aligned pointer (4 or 2 bytes). Strides are nonnegative, scalar-aligned, positive for nonunit axes, and pass a sorted-span nonoverlap proof.
MappingExplicit D/H/W/C logical-axis mapping; C is required. Unmapped axes are independent outer dimensions. Compact or padded-to-16 channel storage.
ParametersEmpty Params; dtype and layout are authoritative. No scale, rounding selector, JSON or ConfigManager.
Buffer sizesPreparation derives the physical tiled input span and full addressed output span, including stride holes. Each submitted view must provide at least that capacity.
AliasingAccessed input/output ranges must not overlap. Adjacent views and extra unused capacity are allowed.
LifetimeBorrowed CPU views, valid and accessible until synchronous return. Runtime owns allocation, mapping and coherency.

The input follows the explicit MlaTiled (include/simaai/kernels/tensor.h) contract used by native CastTess: each pixel has a low-byte channel plane followed by a high-byte channel plane. Padded channels participate in both planes. Tiles use actual boundary extents and 16-byte-aligned spans. Channel tiles precede D/H/W tiles; outer slices retain logical row-major order.

Padded channels and alignment gaps are ignored, not checked for zero, copied to output or rewritten. Logical channel counts—not stored padded counts—determine the output shape. The producer must use this exact physical contract; other layout names alone do not establish compatibility.

Compiler channel-block input​

MlaCBlocked{{tile_h, tile_w, tile_c}} admits ranks 3–6 with trailing H/W/C axes. Earlier axes are independent HWC volumes. Each channel slice is padded independently to 16; output contains only logical elements, with caller-selected strides. This representation is not interchangeable with pixel-major MlaTiled.

For a tile with P = actual_h * actual_w pixels, local channel c and local pixel p, the low-byte offset is:

32 * ((c / 16) * P + p) + c % 16
high-byte offset = low-byte offset + 16

Integer division is used. The fused reader traverses channel blocks and converts only valid lanes directly into the final output. It uses the same numerical core as the pixel-major path; no full-size repacking tensor or extra numerical pass is introduced. Existing MlaTiled routes retain their optimized dispatch. Depth tiling or nontrailing H/W/C mappings are not implied by this layout.

Parameters​

Params is empty; output dtype and layout select the supported conversion.

Numerical behavior​

  • BF16 → BF16: every 16-bit word is preserved.
  • BF16 → FP32: each word becomes the upper 16 bits of a binary32 word; its lower 16 bits are zero. This is exact expansion, not FP32 arithmetic.
  • Both paths preserve signed zero, infinities, subnormals, NaN sign/payload and signaling/quiet status. They do not perform floating-point operations or change FP control or exception flags. Later arithmetic on signaling NaNs can still raise exceptions.
  • DetessCast does not recover precision lost when an earlier CastTess rounded FP32 to BF16.

C++ call​

The call below checks the shared request, selects A65 execution with prepare(metadata) and executes with caller-supplied storage. The A65 check_inference() convenience function performs those first two steps together. The native EV74 boundary accepts the same request and numerical contract through Runtime.

Place the includes and namespace aliases at file scope; the remaining statements belong in a simaai::kernels::Status-returning caller function. input_views and output_views are caller-supplied arrays of ConstHostBuffer and HostBuffer in port order, with accessible capacities and alignment from the checked plan. Keep their storage alive until synchronous execution returns.

#include <simaai/kernels/a65/detesscast.h>
#include <array>

namespace k = simaai::kernels;
namespace dc = k::a65::detesscast;
namespace op = k::ops::detesscast;

k::MlaTiled layout;
layout.axes = {-1, -1, 0, 1}; // Logical shape is [W, C].
layout.tile_shape = {1, 1, 2, 3};
const std::array inputs{
k::TensorSpec{{2, 3}, k::DType::BFloat16, layout}};
const std::array outputs{
k::TensorSpec{{2, 3}, k::DType::Float32, k::Contiguous{}}};
auto prepared = op::check_inference(
{inputs, outputs, {}});
if (const auto *error = std::get_if<k::Error>(&prepared)) return *error;
const auto plan = dc::prepare(std::get<op::Plan>(prepared));

return dc::execute(plan, input_views, output_views);

For a pitched [2, 3] FP32 result, replace the output layout with k::Strided{{16, 4}}. The required addressed span is 28 bytes, not 24; the four-byte hole between rows stays untouched. This changes storage only, not logical indexing or BF16 reconstruction.

See the correctness tests (A65/detesscast/tests/correctness.cpp) for concrete storage, independent expected results and failure cases.

See calling kernels for the shared lifecycle.

Memory and lifecycle​

check_inference() checks port count, dtype, logical shapes, output stride alignment/nonoverlap, layout mapping, tile extents and storage overflow. It returns an owning, fixed-size plan with at most 16 full/boundary tile classes, not a list of jobs proportional to tensor size. Invalid requests cannot construct an executable plan.

Every execute() checks the actual view arity, capacities, null pointers, alignment, address-range overflow and overlap before any output write. Pointer accessibility and allocation lifetime remain the caller's responsibility. The plan is immutable and reusable across invocations and concurrent calls using separate output buffers. Empty tensors require zero storage and permit null views.

Implementation notes​

On A65, contiguous channel runs use NEON byte-plane unpacking and integer shifts. Complete 16-channel blocks interleave low and high byte planes directly; shorter blocks and scalar tails retain their own bounded loads. Reconstruction preserves all BF16 bit patterns and never treats padding as logical channels. Compact C=1/2/3 rows have cross-pixel vector paths where the dense width stride permits them. Nonunit channel strides use direct scalar reconstruction; contiguous channel runs retain vector unpacking even when rows are pitched. Other axis mappings and tails have direct scalar paths. Stride holes are never initialized or overwritten. Output is written directly: no full-tensor staging, heap allocation, worker threads or caller workspace is needed.

Preparation caches a C-only traversal flag in the fixed-size plan. It is selected for one or more channel tiles with contiguous output channels, one outer slice and unit actual spatial extents. Unit logical axes can be mapped spatial axes or unmapped outer axes. When two or more full channel tiles have no alignment gap between their byte-plane pairs (storage_bytes == 2 * stored_channels), execution passes them to one row conversion instead of calling it per tile. The dense row stride is the logical channel count times the output scalar size. Internal channel padding remains skipped; tiles separated by alignment gaps retain the per-tile traversal. The final tile is always converted separately with its own byte planes, logical extent and bounded tail. This reduces repeated dispatch and setup without changing reconstruction or reading across a tile's byte planes.

Tests and qualification​

The default build includes a65_detesscast_contract and a65_detesscast_benchmark. See build and test for host and DevKit execution.

The independent correctness suite is in A65/detesscast/tests/correctness.cpp (A65/detesscast/tests/correctness.cpp). Guard-page tests cover C=8, C=17 and C=32 tile widths, both output dtypes and channel padding modes, full and partial final tiles, and every channel-axis position at ranks one through six with mapped or unmapped unit axes. Input padding is poisoned and the input mapping is read-only during execution. A focused channel-batch matrix also covers compact and padded widths from one to 64 channels, including physical alignment gaps, empty tensors and batch-boundary tails. Physical-family tests cover scalar stepping, row pitches, physical permutations, outer dimensions and scalar-aligned base phases. Compiler CBlock16 tests cover strided channels and channel-block tails. Exact-capacity rejection and protected pages verify addressed-span bounds; poisoned output holes must remain untouched. See build and test for commands and the distinction between host development checks, A65 measurements and baseline qualification.