OpenVINO S1 Embedded Controls Log
Date: 2026-06-15
This is the step-by-step record for S1 from coding-node-plan.md.
S1 Target
Confirm that ContinuousBatchingPipeline / SchedulerConfig controls are
reachable from the Contenox process.
Minimum proof:
enable_prefix_caching- KV precision
- cache size
- split-fuse / chunked prefill
- sparse attention controls
- perf metrics
Outcome
S1 is proven from Go/CGo with OpenVINO GenAI 2026.2.0.0.
The probe:
- constructs
ov::genai::ContinuousBatchingPipelinefrom a Go test through CGo; - applies
SchedulerConfigvalues for prefix caching, cache size, dynamic split-fuse, and XAttention sparse attention; - passes
KV_CACHE_PRECISION=f16; - generates one token;
- reads
PipelineMetrics; - verifies the report in a Go test.
Important caveat: the S1 probe keeps the GenAI pipeline alive for process
lifetime. Destroying ContinuousBatchingPipeline inside the CGo call corrupts
the Go test process after the report is returned. S1 does not solve production
lifecycle teardown yet; that is a follow-up before real provider wiring.
1. Confirmed Package Versions
The S1 run uses the existing S0 virtualenv under:
/home/naro/src/github.com/contenox/ov-s0/.venv
Installed or confirmed:
/home/naro/src/github.com/contenox/ov-s0/.venv/bin/pip install -q openvino-genai
/home/naro/src/github.com/contenox/ov-s0/.venv/bin/python - <<'PY'
import importlib.metadata as md
for pkg in ['openvino', 'openvino-genai', 'openvino-tokenizers']:
print(pkg, md.version(pkg))
PY
Result:
openvino 2026.2.0
openvino-genai 2026.2.0.0
openvino-tokenizers 2026.2.0.0
2. Located Runtime Libraries
The Python packages provide the shared libraries:
openvino:
/home/naro/src/github.com/contenox/ov-s0/.venv/lib/python3.12/site-packages/openvino
openvino_genai:
/home/naro/src/github.com/contenox/ov-s0/.venv/lib/python3.12/site-packages/openvino_genai
openvino_tokenizers:
/home/naro/src/github.com/contenox/ov-s0/.venv/lib/python3.12/site-packages/openvino_tokenizers
The GenAI wheel does not ship the public C++ headers needed for embedding, so the headers must come from the matching source tag.
3. Matched GenAI Headers To The Wheel
The local source checkout was:
/home/naro/src/github.com/openvinotoolkit/openvino.genai
It was on master, which was not safe to use against the 2026.2.0.0 wheel.
Fetching tags showed the matching release exists:
git -C /home/naro/src/github.com/openvinotoolkit/openvino.genai fetch --tags --force
git -C /home/naro/src/github.com/openvinotoolkit/openvino.genai show -s --format='%H %D %ci' 2026.2.0.0
Result:
adf73e80e66629730f976d44cad6c09cf978deca tag: 2026.2.0.0 2026-05-18 14:08:21 +0000
A detached worktree was created so the existing source checkout stays on
master:
git -C /home/naro/src/github.com/openvinotoolkit/openvino.genai \
worktree add --detach \
/home/naro/src/github.com/openvinotoolkit/openvino.genai-2026.2.0.0 \
2026.2.0.0
4. Inspected The Public C++ Control Surface
The release headers expose the S1 controls under:
/home/naro/src/github.com/openvinotoolkit/openvino.genai-2026.2.0.0/src/cpp/include/openvino/genai
Confirmed headers:
continuous_batching_pipeline.hppscheduler_config.hppsparse_attention.hppperf_metrics.hpp
Confirmed SchedulerConfig fields:
cache_sizenum_kv_blocksdynamic_split_fuseenable_prefix_cachinguse_sparse_attentionsparse_attention_config
Confirmed SparseAttentionConfig / XAttention controls:
SparseAttentionMode::XATTENTIONnum_last_dense_tokens_in_prefillxattention_thresholdxattention_block_sizexattention_stride
Confirmed ContinuousBatchingPipeline::get_metrics() returns pipeline metrics
including cache usage and cache size.
5. Proved The Controls Through Python First
A Python probe in the S0 virtualenv constructed both high-level and continuous batching GenAI pipelines with:
cfg.cache_size = 1
cfg.dynamic_split_fuse = True
cfg.enable_prefix_caching = True
cfg.use_sparse_attention = True
cfg.sparse_attention_config.mode = openvino_genai.SparseAttentionMode.XATTENTION
cfg.sparse_attention_config.num_last_dense_tokens_in_prefill = 10
cfg.sparse_attention_config.xattention_threshold = 0.9
cfg.sparse_attention_config.xattention_block_size = 128
cfg.sparse_attention_config.xattention_stride = 16
The pipeline was constructed with:
{"scheduler_config": cfg, "KV_CACHE_PRECISION": "f16"}
Result:
- OpenVINO logged the scheduler config with prefix caching, split-fuse, and XAttention enabled.
- OpenVINO logged
KV_CACHE_PRECISION: f16. ContinuousBatchingPipeline.get_metrics()returnedPipelineMetrics.generate(... max_new_tokens=1 ...)returned one result.
This proved the OpenVINO GenAI runtime accepts the controls, but not yet that Contenox can reach them through Go/CGo.
6. Found The Tokenizer Extension Requirement
The first embedded C++ attempt failed until this environment variable was set:
OPENVINO_TOKENIZERS_PATH_GENAI=/home/naro/src/github.com/contenox/ov-s0/.venv/lib/python3.12/site-packages/openvino_tokenizers/lib/libopenvino_tokenizers.so
This is required when using the wheel-provided GenAI library from an embedded C++/CGo process.
7. Proved The Same Call Shape In Standalone C++
Before debugging CGo, the same C++ call shape was compiled as a standalone binary with release-matched headers:
OV=/home/naro/src/github.com/contenox/ov-s0/.venv/lib/python3.12/site-packages/openvino
GENAI=/home/naro/src/github.com/contenox/ov-s0/.venv/lib/python3.12/site-packages/openvino_genai
TOKENIZERS=/home/naro/src/github.com/contenox/ov-s0/.venv/lib/python3.12/site-packages/openvino_tokenizers/lib
GENAI_SRC=/home/naro/src/github.com/openvinotoolkit/openvino.genai-2026.2.0.0
g++ -g -std=c++17 -I$OV/include -I$GENAI_SRC/src/cpp/include /tmp/s1_genai_probe.cpp \
-L$OV/libs -L$GENAI -L$TOKENIZERS \
-l:libopenvino_genai.so.2620 -l:libopenvino.so.2620 -l:libopenvino_tokenizers.so -lstdc++ \
-Wl,-rpath,$OV/libs -Wl,-rpath,$GENAI -Wl,-rpath,$TOKENIZERS \
-o /tmp/s1_genai_probe
LD_LIBRARY_PATH="$OV/libs:$GENAI:$TOKENIZERS" \
OPENVINO_TOKENIZERS_PATH_GENAI="$TOKENIZERS/libopenvino_tokenizers.so" \
/tmp/s1_genai_probe
Result:
phase config
phase construct
phase generate
PipelineMetrics { cache_usage: 0.03663, max_cache_usage: 0.03663, avg_cache_usage: 0.03663, cache_size_in_bytes: 1073479680 }
GenerationResultCount: 1
This proved the C++ API and wheel libraries work outside Go.
8. Added The Contenox S1 Probe
Files added under runtime/modelrepo/openvino/ovsession/:
s1_probe.hs1_probe.cpps1_controls.gos1_controls_test.go
Build tags:
//go:build openvino && openvino_genai
The C++ probe sets:
cfg.cache_size = 1;
cfg.dynamic_split_fuse = true;
cfg.enable_prefix_caching = true;
cfg.use_sparse_attention = true;
cfg.sparse_attention_config.mode = ov::genai::SparseAttentionMode::XATTENTION;
cfg.sparse_attention_config.num_last_dense_tokens_in_prefill = 10;
cfg.sparse_attention_config.xattention_threshold = 0.9f;
cfg.sparse_attention_config.xattention_block_size = 128;
cfg.sparse_attention_config.xattention_stride = 16;
It constructs:
ov::genai::ContinuousBatchingPipeline(
std::filesystem::path(model_dir),
cfg,
device,
ov::AnyMap{{"KV_CACHE_PRECISION", ov::element::f16}})
Then it generates one token, reads get_metrics(), and returns a text report to
Go.
9. Debugged The CGo Segfault
Initial CGo runs segfaulted after the C++ probe returned.
gdb showed crashes in Go runtime/test logging after the report was already
available, not inside the scheduler setup itself.
Changes tried:
- matching
2026.2.0.0headers instead ofmasterheaders; - C-allocated report/error buffers instead of Go-owned byte slices;
- direct
libopenvino_tokenizers.solinking with--no-as-needed.
Those did not fix teardown.
The passing change was to keep the probe ContinuousBatchingPipeline alive for
process lifetime instead of destroying it before returning from CGo. With that
change, Go can read the report and assert the required fields.
This is acceptable for the S1 control-surface proof, but it is not the final production lifecycle design.
10. Final S1 Verification Command
OV=/home/naro/src/github.com/contenox/ov-s0/.venv/lib/python3.12/site-packages/openvino
GENAI=/home/naro/src/github.com/contenox/ov-s0/.venv/lib/python3.12/site-packages/openvino_genai
TOKENIZERS=/home/naro/src/github.com/contenox/ov-s0/.venv/lib/python3.12/site-packages/openvino_tokenizers/lib
GENAI_SRC=/home/naro/src/github.com/openvinotoolkit/openvino.genai-2026.2.0.0
MODEL=/home/naro/src/github.com/contenox/ov-s0/models/qwen-coder-0.5b-int4
CGO_ENABLED=1 \
CGO_CXXFLAGS="-std=c++17 -I$OV/include -I$GENAI_SRC/src/cpp/include" \
CGO_LDFLAGS="-L$OV/libs -L$GENAI -L$TOKENIZERS -l:libopenvino_genai.so.2620 -l:libopenvino.so.2620 -lstdc++ -Wl,-rpath,$OV/libs -Wl,-rpath,$GENAI -Wl,-rpath,$TOKENIZERS" \
LD_LIBRARY_PATH="$OV/libs:$GENAI:$TOKENIZERS" \
OPENVINO_TOKENIZERS_PATH_GENAI="$TOKENIZERS/libopenvino_tokenizers.so" \
CONTENOX_OPENVINO_TEST_MODEL="$MODEL" \
CONTENOX_OPENVINO_TEST_DEVICE=CPU \
go test -tags 'openvino openvino_genai' \
-run TestSystem_OpenVINOGenAI_SchedulerControlsReachable \
-v ./runtime/modelrepo/openvino/ovsession
Result:
--- PASS: TestSystem_OpenVINOGenAI_SchedulerControlsReachable (1.68s)
PASS
ok github.com/contenox/runtime/runtime/modelrepo/openvino/ovsession 1.729s
The report contained:
cache_size: 1
dynamic_split_fuse: true
enable_prefix_caching: true
use_sparse_attention: true
sparseAttentionMode: XATTENTION
xattention_threshold: 0.9
xattention_block_size: 128
xattention_stride: 16
PipelineMetrics {
requests: 1
scheduled_requests: 1
cache_usage: 0.03663
max_cache_usage: 0.03663
avg_cache_usage: 0.03663
cache_size_in_bytes: 1073479680
}
GenerationResultCount: 1
11. Makefile Support
Makefile.openvino now has:
make -f Makefile.openvino test-s1
The target:
- installs
openvino-genai; - fetches GenAI tags;
- creates the matching
openvino.genai-2026.2.0.0worktree if needed; - sets
OPENVINO_TOKENIZERS_PATH_GENAI; - runs the
openvino openvino_genaitagged S1 test.
12. What Is Still Not Done
S1 is done as a control-surface proof.
Still open for the broader OpenVINO track:
- Production lifecycle handling for
ContinuousBatchingPipelineteardown from Go/CGo. - S0 feature map completion across GenAI C API, GenAI C++ API, OVMS-only controls, and our required shim surface.
- S3 hardware benchmark on the target Intel device.
- Provider-level chat/stream/prompt client wiring on top of the proven primitives.
- The common local-node benchmark report from
../../local-coding-node-goals.md, including warm suffix equivalence to cold full prompt, suffix-growth TTFT curve, snapshot save/restore timing, cancellation recovery, and cache eviction behavior.