Set Up a C/C++ Project#
ovstage exposes a pure C API. A C/C++ consumer includes
<ovstage/ovstage.h> for the data plane, adds ovstage’s include/ directory
to its include path, and links the ovstage shared library.
Note
The examples build standalone with CMake against the released ovstage package
using find_package(ovstage) (refer to examples/c/cmake/ovstage.cmake). ovstage
is pre-release; if the pinned package cannot be fetched, the public package is
not published yet. Refer to Getting Started in C.
Headers#
Include |
Provides |
|---|---|
|
The data-plane API, |
|
The path-dictionary functions (interning tokens, building path lists). Include these directly to call them. |
|
The |
Build Wiring#
The public examples wire up ovstage with a small CMake helper,
examples/c/cmake/ovstage.cmake:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../cmake")
include(ovstage)
ovstage_fetch() # find_package(ovstage), else fetch the release
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE ovstage::ovstage)
ovstage_setup_runtime(myapp) # rpath (Linux) / package bin/ on PATH (Windows)
Linking ovstage::ovstage brings in the public include/ tree, so
#include <ovstage/ovstage.h> resolves with no extra include paths. Then follow
the minimal example’s lifecycle: create → get path dictionary → intern / build
path list → query → write → advance write floor → read → release. Refer to
Application Flow.
Diagnostics Caveat#
ovstage_get_error_string and ovstage_get_last_op_error are
vtable-dispatched and need a live ovstage_instance_t*. Before
ovstage_create_instance returns, you can only print the numeric status code
or use the free function ovstage_get_last_error() (refer to
Error Handling and Diagnostics).
Static Loader Package Root#
When linking ovstage::ovstage_static, pass the package bin/ directory via
ovstage_config_entry_binary_package_root_path() to ovstage_initialize()
before any other ovstage_* call. The path may include
OVX_CONFIG_EXECUTABLE_DIR_TOKEN ("${executable_dir}"), which the
loader substitutes with the absolute directory of the running executable — for
example, when the package lives at <exe_dir>/ovstage/bin:
ovstage_config_entry_t entries[] = {
ovstage_config_entry_binary_package_root_path(
literal_to_ovx_string(OVX_CONFIG_EXECUTABLE_DIR_TOKEN "/ovstage/bin")),
};
ovstage_config_t config = { entries, 1 };
ovstage_initialize(&config);
Minimal Program#
// Write one float per prim into the "temperature" column (UPSERT creates
// the prims on first write), seal it by advancing the write floor to
// ordinal 1, then read the column back.
float values[] = { 1.0f, 2.0f, 3.0f };
int64_t shape[] = { 3 };
int64_t strides[] = { 1 };
DLTensor tensor{};
tensor.data = values;
tensor.device = { kDLCPU, 0 };
tensor.ndim = 1;
tensor.dtype = { kDLFloat, 32, 1 }; // {code, bits, lanes}
tensor.shape = shape;
tensor.strides = strides;
ovstage_write_data_t write{};
write.tensors = &tensor;
write.tensor_count = 1;
write.is_array = false;
ovstage_enqueue_result_t enq =
ovstage_write_attribute(stage, query, attrArg, /*ordinal*/ 1, write, OVSTAGE_PRIM_MODE_UPSERT);
waitOp(stage, enq, "write_attribute");
ovstage_write_floor_desc_t writeFloor{};
writeFloor.ordinal = 1;
writeFloor.scope = OVSTAGE_SCOPE_ALL;
enq = ovstage_advance_write_floor(stage, &writeFloor);
waitOp(stage, enq, "advance_write_floor");
ovstage_ordinal_range_t range{};
range.end_ordinal = 1;
range.has_start_ordinal = false;
ovstage_read_handle_t read = OVSTAGE_INVALID_READ_HANDLE;
enq = ovstage_read_attributes(stage, query, &attr, 1, range, &read);
waitOp(stage, enq, "read_attributes");
ovstage_read_group_t group{};
status = ovstage_fetch_read_next(stage, read, OVSTAGE_TIMEOUT_INFINITE, &group);
check(stage, status, "fetch_read_next");
if (group.data.tensor_count != 1 || !group.data.tensors[0].data)
{
std::fprintf(stderr, "unexpected read layout\n");
return EXIT_FAILURE;
}
const float* out = static_cast<const float*>(group.data.tensors[0].data);
std::printf("read back ordinal %llu: %.1f %.1f %.1f\n", (unsigned long long)group.ordinal, out[0], out[1], out[2]);
ovstage_release_group(stage, &group); // the tensor data is only valid until the group is released
Where to Go Next#
Getting Started in C — build and run the minimal example.
C API Reference — the full C API reference.
Application Flow — the end-to-end lifecycle.