Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:NVIDIA DALI C API V2 Data Objects Header

From Leeroopedia


Knowledge Sources
Domains Data_Pipeline, C_API
Last Updated 2026-02-08 16:00 GMT

Overview

The C API v2 data objects header defines the abstract interfaces ITensor and ITensorList, along with their backend-specific wrapper implementations TensorWrapper and TensorListWrapper.

Description

This header file is the core type definition for DALI's C API v2 data object layer. It belongs to the dali::c_api namespace and defines the inheritance hierarchy that bridges C-style opaque handles to DALI's internal C++ tensor types. The file declares two abstract interface classes and their template implementations.

ITensor inherits from both _DALITensor (the C handle base) and RefCountedObject (for intrusive reference counting). It declares pure virtual methods for all tensor operations: Resize, AttachBuffer, GetBufferPlacement, Get/SetLayout, Get/SetStream, GetReadyEvent, GetDesc, GetShape, GetByteSize, GetDType, Get/SetSourceInfo, and CopyOut. The ITensorList interface mirrors this pattern with additional multi-sample operations like AttachSamples, GetTensorDesc, and ViewAsTensor.

The template classes TensorWrapper<Backend> and TensorListWrapper<Backend> provide the concrete implementations, each holding a std::shared_ptr to the underlying Tensor<Backend> or TensorList<Backend>. The wrappers handle all validation, type conversion, and memory management. The BufferDeleter struct adapts the C-style daliDeleter_t callback into a C++ callable for use with std::shared_ptr custom deleters. Factory functions Wrap() create RefCountedPtr-managed wrapper instances, and Unwrap<Backend>() methods provide access to the underlying DALI objects.

Usage

Include this header when implementing C API v2 functions that operate on Tensor or TensorList handles, or when writing internal code that needs to convert between C API handles and native DALI tensor types. The Unwrap<Backend>() method is particularly useful for passing data objects to Pipeline methods that expect native DALI types.

Code Reference

Source Location

Signature

namespace dali::c_api {

constexpr mm::memory_kind_id GetMemoryKind(const daliBufferPlacement_t &placement);

class ITensor : public _DALITensor, public RefCountedObject {
 public:
  virtual void Resize(int ndim, const int64_t *shape, daliDataType_t dtype, const char *layout) = 0;
  virtual void AttachBuffer(int ndim, const int64_t *shape, daliDataType_t dtype,
                            const char *layout, void *data, daliDeleter_t deleter) = 0;
  virtual daliBufferPlacement_t GetBufferPlacement() const = 0;
  virtual daliTensorDesc_t GetDesc() const = 0;
  virtual const TensorShape<> &GetShape() const & = 0;
  virtual size_t GetByteSize() const = 0;
  virtual daliDataType_t GetDType() const = 0;
  template <typename Backend> const std::shared_ptr<Tensor<Backend>> &Unwrap() const &;
  static RefCountedPtr<ITensor> Create(daliBufferPlacement_t placement);
};

class ITensorList : public _DALITensorList, public RefCountedObject {
 public:
  virtual void Resize(int num_samples, int ndim, const int64_t *shapes,
                      daliDataType_t dtype, const char *layout) = 0;
  virtual void AttachBuffer(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) = 0;
  virtual void AttachSamples(int num_samples, int ndim, daliDataType_t dtype,
                             const char *layout, const daliTensorDesc_t *samples,
                             const daliDeleter_t *sample_deleters) = 0;
  virtual RefCountedPtr<ITensor> ViewAsTensor() const = 0;
  template <typename Backend> const std::shared_ptr<TensorList<Backend>> &Unwrap() const &;
  static RefCountedPtr<ITensorList> Create(daliBufferPlacement_t placement);
};

template <typename Backend>
class TensorWrapper : public ITensor { ... };

template <typename Backend>
class TensorListWrapper : public ITensorList { ... };

struct BufferDeleter {
  daliDeleter_t deleter;
  AccessOrder deletion_order;
  void operator()(void *data);
};

}  // namespace dali::c_api

Import

#include "dali/c_api_2/data_objects.h"

I/O Contract

Inputs

Name Type Required Description
Backend template parameter CPUBackend or GPUBackend Yes Determines internal storage backend
placement daliBufferPlacement_t Yes Device type, device ID, and pinned flag for buffer creation
shape/shapes const int64_t * Yes Tensor dimensions data
dtype daliDataType_t Yes Element data type
deleter daliDeleter_t No Custom deleter with context, buffer deletion, and context destruction callbacks

Outputs

Name Type Description
RefCountedPtr<ITensor> Smart pointer Reference-counted tensor wrapper with initial refcount of 1
RefCountedPtr<ITensorList> Smart pointer Reference-counted tensor list wrapper with initial refcount of 1
daliTensorDesc_t struct Descriptor containing data pointer, shape, ndim, dtype, layout
daliBufferPlacement_t struct Buffer placement info (device type, device ID, pinned)

Usage Examples

Internal Usage: Creating and Unwrapping a TensorList

#include "dali/c_api_2/data_objects.h"

using namespace dali::c_api;

// Create a CPU tensor list
daliBufferPlacement_t placement{DALI_STORAGE_CPU, 0, false};
auto tl = ITensorList::Create(placement);

// Resize with 2 samples
int64_t shapes[] = {480, 640, 3, 600, 800, 3};
tl->Resize(2, 3, shapes, DALI_UINT8, "HWC");

// Access the underlying DALI TensorList
auto &native_tl = *tl->Unwrap<CPUBackend>();
// native_tl is a TensorList<CPUBackend>&

Attaching External Memory with BufferDeleter

// BufferDeleter bridges C-style deleters to std::shared_ptr
daliDeleter_t c_deleter{};
c_deleter.deleter_ctx = my_ctx;
c_deleter.delete_buffer = my_free_fn;
c_deleter.destroy_context = my_ctx_destroy;

BufferDeleter bd{c_deleter, AccessOrder::host()};
// bd can be used as a std::shared_ptr custom deleter:
auto buffer = std::shared_ptr<void>(data_ptr, bd);

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment