How to mint real OpenZL frames and chunks for GPU decoder tests using the contrib/gpu/testkit utilities (frame_factory, multichunk_frame, frame_verifier), and how to extract a codec's encoded streams via reflection for differential GPU decode. USE when writing or reviewing GPU-decoder tests that need OpenZL-encoded fixtures.
npx skills add https://github.com/facebook/openzl --skill openzl-gpu-test-frames
contrib/gpu/testkit mints real OpenZL frames by driving the actual encoder, so every frame/chunk header and checksum is correct by construction — it never hand-serializes header bytes. Use it for all GPU-decoder test fixtures instead of crafting bytes by hand.
//openzl/dev/contrib/gpu/testkit:testkit (add to your cpp_unittest deps).openzl::gpu::testkit.frame_factory.h, frame_verifier.h, multichunk_frame.h.Always build your test Input with the C++ helpers (openzl/cpp/Input.hpp):
// numeric stream of 2-byte elements (e.g. bf16 bit patterns):
Input in = Input::refNumeric<uint16_t>(vals.data(), vals.size());
// or, untyped element width:
Input in = Input::refNumeric(buf, /*eltWidth=*/2, /*numElts=*/n);
// also: Input::refSerial(...), Input::refStruct<T>(...), Input::refString(...)
frame_factory.h// Core minter: applies CParams that DEFEAT the STORE backup (so a hand-picked
// codec is not silently replaced by raw STORE), selects startGraph, compresses.
std::string makeFrameWithGraph(Compressor&, GraphID startGraph, const Input&);
// Route a node's outputs all to STORE (keeps the node's codec in the frame).
std::string makeFrameNodeToStore(Compressor&, NodeID node, const Input&);
// Run a node and route each output to the matching successor graph.
std::string makeFrameNodeWithSuccessors(
Compressor&, NodeID node, std::initializer_list<GraphID> successors, const Input&);
// Single-output node chain: node[0] -> node[1] -> ... -> STORE.
std::string makeFrameChainToStore(
Compressor&, std::initializer_list<NodeID> chain, const Input&);
// Self-checks.
bool roundTrips(Compressor&, GraphID, const Input&);
bool decompressedEquals(const std::string& frame, const Input&);
Always pin the format version so you get chunk-capable (v21+) frames:
Compressor c;
c.setParameter(CParam::FormatVersion, ZL_MAX_FORMAT_VERSION);
Example — a single bitpack-of-numeric frame:
const std::vector<int32_t> ints = /* small-range values so bitpack engages */;
const Input in = Input::refNumeric<int32_t>(ints.data(), ints.size());
Compressor c; c.setParameter(CParam::FormatVersion, ZL_MAX_FORMAT_VERSION);
const std::string frame = makeFrameWithGraph(c, graphs::Bitpack{}(), in);
Example — a float_deconstruct frame:
const Input in = Input::refNumeric<uint16_t>(vals.data(), vals.size()); // bf16 bits
Compressor c; c.setParameter(CParam::FormatVersion, ZL_MAX_FORMAT_VERSION);
const std::string frame =
makeFrameNodeToStore(c, nodes::BFloat16Deconstruct::node, in);
frame_verifier.h// Standard codec wire IDs in the LAST chunk, in decode order (custom codecs skipped).
std::vector<uint32_t> standardCodecsInFrame(const std::string& frame);
// Exactly these codecs (multiset compare, order-independent).
bool frameHasExactlyCodecs(const std::string& frame, const std::vector<uint32_t>& expected);
// Per-chunk standard codec IDs; reports every chunk via decompression introspection.
std::vector<std::vector<uint32_t>> standardCodecsPerChunk(const std::string& frame);
standardCodecsInFrame and frameHasExactlyCodecs use the public reflection API, which only exposes the last chunk of a frame. For multi-chunk fixtures, use standardCodecsPerChunk: it drives the real decompression path with introspection hooks, disables codec fusion on its throwaway DCtx, and returns one inner vector per frame chunk. You do not need to re-mint slices just to verify per-chunk codec coverage.
multichunk_frame.hstruct ChunkSpec { size_t numElts; openzl::GraphID graph; };
std::string makeMultiChunkFrame(
Compressor&, std::initializer_list<ChunkSpec> chunks, const Input&);
// Non-owning view over a contiguous element slice (Serial/Numeric only).
Input sliceInput(const Input&, size_t eltOffset, size_t numElts);
Constraints: chunk numElts must sum to input.numElts(), and each chunk must clear ZL_MIN_CHUNK_SIZE = 32768 bytes of content (so "small" chunks can't be tiny — a bf16 chunk needs ≥ 16384 elts). makeMultiChunkFrame pins FormatVersion = ZL_MAX_FORMAT_VERSION.
> Need finer-grained segments than a 32 KB chunk? Frame chunks can't be smaller than ZL_MIN_CHUNK_SIZE. When a test needs many small, arbitrarily-sized runs, mint one frame and sliceInput its stream into as many pieces as you need rather than relying on frame chunks.
To feed a GPU decode kernel the real encoded bytes and compare against OpenZL's own decoder, decode the frame with the public reflection API (openzl/zl_reflection.h) and pull the codec's streams — the same reflection path frame_verifier uses for last-chunk codec inspection.
ZL_ReflectionCtx* rctx = ZL_ReflectionCtx_create();
ZL_ReflectionCtx_setCompressedFrame(rctx, frame.data(), frame.size()); // DECODES the frame
// find your codec among ZL_ReflectionCtx_getCodec_lastChunk(rctx, i) by ZL_CodecInfo_getCodecID
// streams: ZL_CodecInfo_getOutput(codec, i) -> ZL_DataInfo_getDataPtr/getContentSize
ZL_ReflectionCtx_free(rctx);
// CPU ground truth: DCtx().decompress(frame)
Gotchas that will bite you (learned the hard way):
ZL_CodecInfo_getOutput) are the decoder's inputs (the stored streams you feed the kernel); its *input* (ZL_CodecInfo_getInput) is the decoder's regenerated output — use it for nbElts.ZL_DataInfo_getType (ZL_Type_serial=1, ZL_Type_struct=2, ZL_Type_numeric=4, ZL_Type_string=8) to identify each stream. For float_deconstruct: struct = signFrac, serial = exponent.float_deconstruct (codec id 33) is shared by float32/bfloat16/float16; ZL_CodecInfo_getHeaderPtr does not reliably surface the element-type enum. Detect the variant by stream widths instead: signFrac eltWidth 3/1/2 and output eltWidth 4/2/2 for float32/bf16/float16.makeFrameNodeToStore inserts a convert_struct_to_serial (codec id 6) before STORE for any Struct output — expected; just find the codec you care about among the list.cpp_unittest(
name = "YourTest",
srcs = ["tests/YourTest.cpp"],
network_access = network_access_utils.none(),
deps = [
"fbsource//third-party/googletest:gtest",
"//openzl/dev/contrib/gpu/testkit:testkit",
"//openzl/dev/cpp:openzl_cpp",
],
)
If the test launches CUDA, run with sanitizers OFF (CUDA can't init under ASAN):
buck2 test @fbcode//mode/dev-nosan //openzl/dev/contrib/gpu/...:YourTest
Use when implementing any feature or bugfix, before writing implementation code
Use when implementing any feature or bugfix, before writing implementation code - write the test first, watch it fail, write minimal code to pass; ensures tests actually verify behavior by requiring failure first
Use when creating new skills, editing existing skills, or verifying skills work before deployment - applies TDD to process documentation by testing with subagents before writing, iterating until bulletproof against rationalization
Rules for writing and reviewing tests in the Remotion repository. Use whenever adding, editing, or reviewing tests, especially for Studio UI, rendering, CLI, server, media, and cross-package changes, to prefer complete integration workflows over narrow helper tests and implementation details.
Patterns and pitfalls for the ONNX domain Attention operator (opset 23/24) CUDA implementation. Use when modifying the dispatch cascade in core/providers/cuda/llm/attention.cc, writing mask/bias CUDA kernels, debugging attention test routing, or adding features to the ONNX Attention op. NOT for contrib domain MultiHeadAttention/GroupQueryAttention.
> Translates a HuggingFace model into a prefill-only AutoDeploy custom model using reference custom ops, validates with hierarchical equivalence tests.
Translates a HuggingFace model into a prefill-only AutoDeploy custom model using reference custom ops, validates with hierarchical equivalence tests.
Generates Angular 17+ standalone components, configures advanced routing with lazy loading and guards, implements NgRx state management, applies RxJS patterns, and optimizes bundle performance. Use when building Angular 17+ applications with standalone components or signals, setting up NgRx stores, establishing RxJS reactive patterns, performance tuning, or writing Angular tests for enterprise apps.
Take facebook/openzl-gpu-test-frames from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.