Attribute Mapping#
Mapping an attribute gives application code direct access to ovrtx’s internal attribute buffer. This avoids a copy and is the right tool when CPU code, Warp, or CUDA kernels should write into ovrtx-owned memory.
The lifecycle is:
Map the attribute.
Write into the mapped tensor while the mapping is active.
Unmap the attribute, passing CUDA stream or event synchronization when GPU work wrote the data.
CPU Mapping#
with renderer.map_attribute(
["/World/Plane"], "omni:xform", dtype="float64", shape=(4, 4)
) as mapping:
matrices = np.from_dlpack(mapping.tensor).reshape(1, 4, 4)
matrices[0, 3, 0] = 10.0
ovrtx_mapping_desc_t mapping_desc{};
mapping_desc.device_type = kDLCPU;
mapping_desc.device_id = 0;
ovrtx_attribute_mapping_t mapping{};
ovrtx_result_t result = ovrtx_map_attribute(renderer_, &binding, mapping_desc, &mapping);
ASSERT_API_SUCCESS(result.status);
double* matrix = static_cast<double*>(mapping.dl.data);
matrix[0] = 1.0;
matrix[5] = 1.0;
matrix[10] = 1.0;
matrix[15] = 1.0;
matrix[12] = 15.0;
ovrtx_cuda_sync_t no_sync{};
ovrtx_enqueue_result_t eq = ovrtx_unmap_attribute(renderer_, mapping.map_handle, no_sync);
ASSERT_API_SUCCESS(eq.status);
docs_wait_no_errors(renderer_, eq.op_index);
CUDA Mapping#
Python can map attributes to CUDA memory for GPU-side writes. The example below uses Warp to operate on the mapped tensor.
mapping = renderer.map_attribute(
["/World/Plane"],
"omni:xform",
dtype="float64",
shape=(4, 4),
device=ovrtx.Device.CUDA,
)
tensor = wp.from_dlpack(mapping.tensor, dtype=wp.mat44d)
stream = wp.Stream(device=tensor.device)
wp.launch(_set_xform_translation_x, dim=1, inputs=[tensor, wp.float64(6.0)], stream=stream)
mapping.unmap(stream=stream.cuda_stream)
Explicit Unmap#
Context managers are preferred in Python, but explicit async unmap is available when the application needs to coordinate mapping lifetime manually.
mapping = renderer.map_attribute(["/World/Plane"], "omni:xform", dtype="float64", shape=(4, 4))
matrices = np.from_dlpack(mapping.tensor).reshape(1, 4, 4)
matrices[0, 3, 0] = 9.0
op = mapping.unmap_async()
assert op.wait() is True
Limits and Lifetime#
Array attributes such as
float3[] pointsare not mappable because their lengths can vary per prim. Use Attribute Reads and Writes or Attribute Bindings for array writes.The tensor returned by a mapping is valid only until unmap. Copy data if it must outlive the mapping.
For CUDA mappings, pass a stream or event on unmap so ovrtx knows when GPU writes are complete.
Do not pass CUDA sync objects for CPU mappings.
Multiple mappings can be outstanding; effects are applied in unmap order.