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:

  1. Map the attribute.

  2. Write into the mapped tensor while the mapping is active.

  3. 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[] points are 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.