Conduit Node Basics¶
You can skip this section, if you are concerned with sending raw float/double arrays.
Before transmitting data via Melissa, users need to understand how Conduit manages data structures.
Conduit organizes information into a dynamic, hierarchical tree layout called a Node. A Node can contain metadata, continuous numerical memory arrays, or complex nested structures. Instead of requiring you to flatten or serialize your simulation buffers into arbitrary byte arrays before transmission, Melissa consumes these native tree structures directly.
C++¶
In C++, a conduit::Node operates like a dynamic object where paths are delimited using forward slashes (/).
#include <conduit/conduit.hpp>
#include <vector>
void create_sample_node() {
// 1. Instantiation
conduit::Node simulation_data;
// 2. Hierarchical Assignment
// You can write scalars directly to dynamic paths.
simulation_data["metadata/val"] = 42;
simulation_data["metadata/field_type"] = "fluid_velocity";
// 3. Zero-Copy Pointer Association
// For large simulation arrays, use 'set_external' to bind the
// memory buffer by reference rather than copying it.
std::vector<double> temperature_mesh = {23.5, 24.1, 26.8, 29.2, 21.0};
simulation_data["mesh/temperature"].set_external(temperature_mesh.data(),
temperature_mesh.size());
// 4. Structural Schema Inspection
// .schema().print() shows the datatype and layout of the memory structure.
simulation_data.schema().print();
// 5. Dynamic Explicit Extraction
// When reading fields back, use strict type-casting methods.
int extracted_id = simulation_data["metadata/val"].to_int();
}
Python¶
In Python, the conduit.Node wrapper matches the C++ behavior closely, allowing interaction using standard dictionary keys and seamless conversion from NumPy arrays.
import conduit
import numpy as np
def create_sample_node_py():
# 1. Instantiation
simulation_data = conduit.Node()
# 2. Hierarchical Assignment
simulation_data["metadata/val"] = 42
simulation_data["metadata/field_type"] = "fluid_velocity"
# 3. NumPy Array Association
# Assigning a NumPy array to a node retains a zero-copy view of the
# underlying buffer under the hood.
temperature_mesh = np.array([23.5, 24.1, 26.8, 29.2, 21.0], dtype=np.float64)
simulation_data["mesh/temperature"].set_external(temperature_mesh)
# 4. Schema Inspection
# Displays the data hierarchy definition.
print(simulation_data.schema())
# 5. Extraction
# Extracts Python native types or raw views from paths.
extracted_id = simulation_data["metadata/val"].to_int()
Dangling Pointers with set_external()
import conduit
import numpy as np
n = conduit.Node()
x = np.ones(10)
# 'x' stays in scope, keeping the raw C-buffer alive.
n["a/b/good_ref"].set_external(x)
# the temporary array is garbage-collected
# immediately on the next line
# leaving a C-pointer to freed memory.
n["a/b/bad_ref"].set_external(np.ones(10))
# deep-copies the values into C++ owned memory.
n["a/b/good_ref2"].set(np.ones(10))
x += 14
print(n)
print(n.info())
Output
a:
b:
good_ref: [15.0, 15.0, 15.0, ..., 15.0, 15.0]
bad_ref: [1.39875217480978e-315, 1.39875699689048e-315, 1.0, ..., 1.0, 0.0]
good_ref2: [1.0, 1.0, 1.0, ..., 1.0, 1.0]
mem_spaces:
0x10dfe990:
path: "a/b/good_ref"
type: "external"
0x10dff0e0:
path: "a/b/bad_ref"
type: "external"
0x10dff340:
path: "a/b/good_ref2"
type: "allocated"
bytes: 80
allocator_id: 0
total_bytes_allocated: 80
total_bytes_mmaped: 0
total_bytes_compact: 240
total_strided_bytes: 240
It is recommended users go through Conduit documentation.
When to Use a Conduit Blueprint Mesh
A Conduit Blueprint mesh is useful when you want to send more than just the simulation values. It packages the mesh coordinates, topology, field data, and simulation information into a single self describing format, making it easy for visualization and analysis tools to understand the data without any extra information. This is especially helpful for debugging simulations, visualizing results in tools like ParaView or Ascent, or sharing data between different applications. If your workflow only needs the raw field values, such as training a surrogate model, then sending a simple array is usually enough and using a Blueprint mesh may not provide much additional benefit.
The repository contains example notebooks demonstrating how to create strucutred/unstructured conduit nodes for visualization of meshes:
- examples/conduit_complex_mesh_struct.ipynb
- examples/conduit_complex_mesh_unstruct.ipynb