Implementation:NVIDIA DALI C API V2 Data Objects
| Knowledge Sources | |
|---|---|
| Domains | Data_Pipeline, C_API |
| Last Updated | 2026-02-08 16:00 GMT |
Overview
The C API v2 data objects implementation provides C-callable functions for creating, manipulating, and querying DALI Tensor and TensorList objects with reference-counted lifecycle management.
Description
This file implements the C API v2 functions for managing DALI data objects (daliTensor_h and daliTensorList_h). It belongs to the dali::c_api namespace within NVIDIA DALI and serves as the bridge between the C function interface and the internal C++ ITensor and ITensorList abstract interfaces defined in the corresponding header.
The file contains factory methods (ITensor::Create, ITensorList::Create) that instantiate typed wrappers around DALI's internal Tensor<Backend> and TensorList<Backend> objects based on the requested buffer placement (CPU/GPU, pinned/unpinned). Every C function follows a consistent error handling pattern using DALI_PROLOG() and DALI_EPILOG() macros that translate C++ exceptions into daliResult_t error codes.
The Tensor API provides operations for creation, reference counting (IncRef/DecRef), resizing, buffer attachment with custom deleters, shape/type/layout/stream queries and mutations, descriptor retrieval, source info management, and byte-size queries. The TensorList API mirrors these operations plus additional multi-sample operations: attaching contiguous buffers with sample offsets, attaching individual samples with per-sample deleters, viewing a uniform TensorList as a single Tensor, and copying data out to external buffers.
Usage
Use these functions when working with DALI data objects from C code or from language bindings that cannot directly use C++ classes. Typical scenarios include: creating tensor lists to feed as pipeline inputs, extracting and inspecting pipeline outputs, attaching externally allocated GPU memory buffers with custom deleters, and copying output data to framework-specific memory layouts.
Code Reference
Source Location
- Repository: NVIDIA_DALI
- File: dali/c_api_2/data_objects.cc
- Lines: 1-487
Signature
// Tensor functions
daliResult_t daliTensorCreate(daliTensor_h *out, daliBufferPlacement_t placement);
daliResult_t daliTensorIncRef(daliTensor_h t, int *new_ref);
daliResult_t daliTensorDecRef(daliTensor_h t, int *new_ref);
daliResult_t daliTensorRefCount(daliTensor_h t, int *ref);
daliResult_t daliTensorAttachBuffer(daliTensor_h tensor, int ndim, const int64_t *shape,
daliDataType_t dtype, const char *layout,
void *data, daliDeleter_t deleter);
daliResult_t daliTensorResize(daliTensor_h tensor, int ndim, const int64_t *shape,
daliDataType_t dtype, const char *layout);
daliResult_t daliTensorGetDesc(daliTensor_h tensor, daliTensorDesc_t *out_desc);
daliResult_t daliTensorGetShape(daliTensor_h tensor, int *out_ndim, const int64_t **out_shape);
// TensorList functions
daliResult_t daliTensorListCreate(daliTensorList_h *out, daliBufferPlacement_t placement);
daliResult_t daliTensorListIncRef(daliTensorList_h tl, int *new_ref);
daliResult_t daliTensorListDecRef(daliTensorList_h tl, int *new_ref);
daliResult_t daliTensorListAttachBuffer(daliTensorList_h tl, int num_samples, int ndim,
const int64_t *shapes, daliDataType_t dtype,
const char *layout, void *data,
const ptrdiff_t *sample_offsets, daliDeleter_t deleter);
daliResult_t daliTensorListAttachSamples(daliTensorList_h tl, int num_samples, int ndim,
daliDataType_t dtype, const char *layout,
const daliTensorDesc_t *samples,
const daliDeleter_t *sample_deleters);
daliResult_t daliTensorListResize(daliTensorList_h tl, int num_samples, int ndim,
const int64_t *shapes, daliDataType_t dtype, const char *layout);
daliResult_t daliTensorListViewAsTensor(daliTensorList_h tl, daliTensor_h *out_tensor);
daliResult_t daliTensorListCopyOut(daliTensorList_h tl, void *dst_buffer,
daliBufferPlacement_t dst_placement,
const cudaStream_t *stream, daliCopyFlags_t flags);
Import
#include "dali/c_api_2/data_objects.h"
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| placement | daliBufferPlacement_t | Yes | Specifies device type (CPU/GPU), pinned flag, and device ID |
| ndim | int | Yes | Number of dimensions for tensor shape |
| shape/shapes | const int64_t * | Yes | Shape data (single tensor or flattened for tensor list) |
| dtype | daliDataType_t | Yes | Data type (e.g., DALI_UINT8, DALI_FLOAT32) |
| layout | const char * | No | Tensor layout string (e.g., "HWC"), NULL to preserve/clear |
| data | void * | No | External data buffer pointer for AttachBuffer |
| deleter | daliDeleter_t | No | Custom deleter for externally attached buffers |
Outputs
| Name | Type | Description |
|---|---|---|
| daliResult_t | enum | DALI_SUCCESS or error code (DALI_ERROR_INVALID_ARGUMENT, etc.) |
| out / out_tensor | handle pointer | Newly created Tensor or TensorList handle |
| out_desc | daliTensorDesc_t * | Tensor descriptor with data pointer, shape, dtype, layout |
| new_ref | int * | Updated reference count after Inc/Dec operations |
Usage Examples
Create and Resize a TensorList
#include "dali/dali.h"
daliBufferPlacement_t placement{};
placement.device_type = DALI_STORAGE_CPU;
placement.pinned = true;
daliTensorList_h tl = nullptr;
daliResult_t r = daliTensorListCreate(&tl, placement);
assert(r == DALI_SUCCESS);
int64_t shapes[] = {480, 640, 3, 600, 800, 3};
r = daliTensorListResize(tl, 2, 3, shapes, DALI_UINT8, "HWC");
assert(r == DALI_SUCCESS);
// Query the shape
int num_samples, ndim;
const int64_t *shape_data;
daliTensorListGetShape(tl, &num_samples, &ndim, &shape_data);
// num_samples == 2, ndim == 3
// Release
int ref;
daliTensorListDecRef(tl, &ref); // ref == 0, object destroyed
Attach External Buffer with Custom Deleter
daliDeleter_t deleter{};
deleter.deleter_ctx = my_context;
deleter.delete_buffer = [](void *ctx, void *data, const cudaStream_t *stream) {
my_free(ctx, data);
};
deleter.destroy_context = [](void *ctx) {
delete static_cast<MyContext*>(ctx);
};
int64_t shapes[] = {1080, 1920, 3};
daliTensorAttachBuffer(tensor, 3, shapes, DALI_FLOAT32, "HWC",
gpu_data_ptr, deleter);