Skip to main content

Session Build And Run

FieldValue
DifficultyBeginner
Estimated Read Time5 minutes
Labelssession, build, run, pipeline

Concept

This tutorial introduces Session, the runtime composition entry point in NEAT.

A Session is where you define pipeline structure by adding nodes and node groups in order. It is not a one-off inference call; it is a reusable runtime graph definition that can be built once and executed many times.

build(...) turns that definition into a runnable Run handle. In practice, build(...) is the transition from "graph description" to "executable runtime":

  • Resolves the added nodes/groups into a concrete pipeline.
  • Validates input/output contracts for the selected input type.
  • Configures runtime behavior (for example sync vs async run mode and output memory policy).
  • Returns a Run object that executes push/pull calls.

For the programming model behind this chapter, see:

Learning Process

  1. Create a minimal Session with explicit input and output nodes.
  2. Build the session with a concrete sample input to materialize a runnable pipeline.
  3. Execute one deterministic sync run to verify output contract behavior.
  4. Read validation checkpoints (CHECK, SIGNATURE, [OK]) to confirm the runtime path.

Run

NEAT_EXTRAS_ROOT=<sima-neat-*-Linux-extras>
cd $NEAT_EXTRAS_ROOT/lib/sima-neat/tutorials
./tutorial_v2_003_session_build_and_run

Code

tutorials/003_session_build_and_run/session_build_and_run.cpp
// Build a minimal Session (Input -> Output), run a frame, read the tensor rank.
//
// Usage:
// tutorial_v2_003_session_build_and_run [--width <w>] [--height <h>]

#include "neat.h"

#include <opencv2/core.hpp>

#include <iostream>
#include <stdexcept>
#include <string>

namespace {

bool get_arg(int argc, char** argv, const std::string& key, std::string& out) {
for (int i = 1; i + 1 < argc; ++i) {
if (key == argv[i]) {
out = argv[i + 1];
return true;
}
}
return false;
}

int parse_int_arg(int argc, char** argv, const std::string& key, int def) {
std::string value;
if (!get_arg(argc, argv, key, value))
return def;
return std::stoi(value);
}

} // namespace

int main(int argc, char** argv) {
try {
const int width = parse_int_arg(argc, argv, "--width", 320);
const int height = parse_int_arg(argc, argv, "--height", 240);

cv::Mat input(height, width, CV_8UC3, cv::Scalar(30, 60, 90));
if (!input.isContinuous())
input = input.clone();

// CORE LOGIC
// Compose a Session from Input and Output nodes, then build+run one frame.
simaai::neat::Session session;

simaai::neat::InputOptions in;
in.format = "RGB";
in.width = width;
in.height = height;
in.depth = 3;
in.is_live = false;
in.do_timestamp = true;

session.add(simaai::neat::nodes::Input(in));
session.add(simaai::neat::nodes::Output());

simaai::neat::RunOptions run_opt;
run_opt.output_memory = simaai::neat::OutputMemory::Owned;

auto run = session.build(input, simaai::neat::RunMode::Sync, run_opt);
auto sample = run.push_and_pull(input, /*timeout_ms=*/1000);

if (!sample.tensor.has_value())
throw std::runtime_error("missing tensor output");
std::cout << "tensor_rank=" << sample.tensor->shape.size() << "\n";
std::cout << "[OK] 003_session_build_and_run\n";
return 0;
} catch (const std::exception& e) {
std::cerr << "[FAIL] " << e.what() << "\n";
return 1;
}
}

Source