Core concepts
The main building blocks
Pipeline
A Pipeline is the graph that executes your complete inference workflow.
You either:
- load it from a
.denkflowfile, or - build it manually from
.denkmodelfiles and utility nodes
A pipeline can be modified only before initialization.
- Python
- C / C++
# Load from export
pipeline = Pipeline.from_denkflow("model.denkflow", pat="YOUR-PAT")
# Or build manually
pipeline = Pipeline()
pipeline.add_image_resize_node(...)
// Load from export
DenkflowPipeline* pipeline = NULL;
denkflow_pipeline_from_denkflow(&pipeline, "model.denkflow", (void*)license_source);
Node
A Node is one processing step inside the pipeline, such as:
- image resize
- object detection
- classification
- OCR
- segmentation
- anomaly detection
Topic
A Topic is the connection name used to move tensors between producers and consumers.
The common naming convention is:
node_name/output_name
Tensor
A Tensor is a payload flowing through the graph.
Common tensor types include:
ImageTensorBoundingBoxTensorScalarTensorOcrTensorSegmentationMaskTensorInstanceSegmentationMaskTensor
Receiver
A Receiver subscribes to a topic and lets you wait for output data.
This is how you collect inference results after calling run().
- Python
- C / C++
receiver = pipeline.subscribe("filter/output")
# Then use the typed receive method that matches the topic's tensor type:
# receiver.receive_bounding_box_tensor()
DenkflowReceiverTensor* receiver = NULL;
denkflow_initialized_pipeline_subscribe(&receiver, initialized_pipeline, "filter/output");
Typical evaluation workflow
Most inference scripts follow this shape:
- Create or load a pipeline
- Initialize the pipeline
- Subscribe to one or more output topics
- Publish input tensors
- Call
run() - Receive and decode the result
- Python
- C / C++
pipeline = Pipeline.from_denkflow("model.denkflow", pat="PAT")
pipeline.initialize()
receiver = pipeline.subscribe("output/topic")
pipeline.publish_image_tensor("camera/image", ImageTensor.from_file("image.jpg"))
pipeline.run()
objects = receiver.receive_bounding_box_tensor().to_objects(0.5)
denkflow_pipeline_from_denkflow(&pipeline, "model.denkflow", (void*)license_source);
denkflow_initialize_pipeline(&initialized_pipeline, &pipeline);
denkflow_initialized_pipeline_subscribe(&receiver, initialized_pipeline, "output/topic");
denkflow_image_tensor_from_file(&image_tensor, "image.jpg");
denkflow_initialized_pipeline_publish_image_tensor(initialized_pipeline, "camera/image", &image_tensor);
denkflow_initialized_pipeline_run(initialized_pipeline, 8000);
denkflow_receiver_receive_bounding_box_tensor(&tensor, receiver);
denkflow_bounding_box_tensor_to_objects(&results, tensor, 0.5f);
.denkflow versus .denkmodel
.denkflow
Use .denkflow when:
- you want the simplest deployment path
- you want export-target-specific runtime configuration
- you want quantized deployment artifacts
.denkmodel
Use .denkmodel when:
- you want to assemble the graph yourself
- you want to choose or force runtime strings like
cuda,tensorrt,directml, oropenvinofrom Python or C/C++ - you want to combine multiple models in one hand-built pipeline
Execution providers and device IDs
Each inference node runs on an execution provider (cpu, cuda, tensorrt, directml, or openvino). Custom pipelines select it via execution_provider= (Python) or the C-API equivalent; exported .denkflow files carry the runtime intent chosen at export time and can be redirected per node before initialization.
For the full provider list, device-id semantics (e.g. OpenVINO -1/-2/>=0), and override rules, see Runtime and Device Selection.
Recommended production strategy
- Export a
.denkflowfile from the Vision AI Hub - Install the SDK for the target runtime and language
- Keep the SDK data directory persistent (default paths are in Configuration; in Docker, mount a host volume at that default path or at the path
DENKFLOW_DATA_DIRECTORYpoints to) - Deploy and benchmark on the actual target hardware