Output Handling Patterns
| Field | Value |
|---|---|
| Difficulty | Intermediate |
| Estimated Read Time | 10-15 minutes |
| Labels | output, patterns, sink |
Concept
This tutorial focuses on output interpretation patterns: how to reliably inspect what came back from a run and decide what your application should do next.
Before you optimize throughput or add complex graph logic, you need a stable way to classify outputs (kind, tensor presence, field count) and validate output contracts. This chapter provides that baseline pattern.
What this chapter demonstrates:
- Building a minimal sync run path.
- Reading
Sampleoutput summary (kind, tensor, fields). - Validating output shape/rank assumptions before downstream use.
Use-case guidance:
- New model integration: verify output rank and tensor presence first.
- Mixed output types: branch behavior by
SampleKindand field structure. - Production robustness: fail fast when output shape contracts are unexpectedly empty.
Reference:
Learning Process
- Build a deterministic sync session with explicit input/output nodes.
- Execute one run and summarize output structure (
kind, tensor, fields). - Validate output contract assumptions (non-empty tensor shape/rank).
- Confirm run health through
CHECK,SIGNATURE, and[OK].
Run
NEAT_EXTRAS_ROOT=<sima-neat-*-Linux-extras>
cd $NEAT_EXTRAS_ROOT/lib/sima-neat/tutorials
./tutorial_v2_010_output_handling_patterns
Code
tutorials/010_output_handling_patterns/output_handling_patterns.cpp
// Inspect a Sample returned by a Session: kind, tensor, fields, rank.
//
// Usage:
// tutorial_v2_010_output_handling_patterns
#include "neat.h"
#include <opencv2/core.hpp>
#include <iostream>
#include <stdexcept>
int main() {
try {
cv::Mat rgb(120, 160, CV_8UC3, cv::Scalar(110, 40, 30));
if (!rgb.isContinuous())
rgb = rgb.clone();
// CORE LOGIC
simaai::neat::Session session;
simaai::neat::InputOptions in;
in.format = "RGB";
in.width = rgb.cols;
in.height = rgb.rows;
in.depth = rgb.channels();
session.add(simaai::neat::nodes::Input(in));
session.add(simaai::neat::nodes::Output());
auto run = session.build(rgb, simaai::neat::RunMode::Sync);
// push_and_pull is the one-frame synchronous shortcut; Sample has .kind,
// .tensor (optional), .fields (named sub-tensors for bundles).
simaai::neat::Sample out = run.push_and_pull(rgb, /*timeout_ms=*/1000);
std::cout << "kind=" << static_cast<int>(out.kind)
<< " has_tensor=" << (out.tensor.has_value() ? "yes" : "no")
<< " fields=" << out.fields.size() << "\n";
if (!out.tensor.has_value())
throw std::runtime_error("expected tensor output");
if (out.tensor->shape.empty())
throw std::runtime_error("output tensor shape is empty");
std::cout << "rank=" << out.tensor->shape.size() << "\n";
std::cout << "[OK] 010_output_handling_patterns\n";
return 0;
} catch (const std::exception& e) {
std::cerr << "[FAIL] " << e.what() << "\n";
return 1;
}
}