> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/holoscan/sdk-user-guide/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/holoscan/sdk-user-guide/_mcp/server.

# holoscan::HoloIpcCudaNativeBufferAdapterBase

> Shared CUDA IPC + holoipc lifecycle adapter core, parameterized on the holoipc transport.

```cpp showLineNumbers={false}
template <typename TransportType>
class HoloIpcCudaNativeBufferAdapterBase
```

Shared CUDA IPC + holoipc lifecycle adapter core, parameterized on the holoipc transport.

Owns all transport-independent logic: GPU info caching, CudaTensorDescriptor conversion, CUDA IPC export/import via GXF helpers, holoipc share\_pointer/acquire\_pointer lifecycle, DNBX (Descriptor Native Buffer eXport) wire-format encode/decode, pending-export tracking, and deferred destruction.

Subclasses provide only the initialize() signature and ipc::Context\<Transport> creation.

Threading: three threads access this object –

* GXF scheduler (export\_tensor, evict\_stale\_exports)
* sidecar dispatch (import\_tensor)
* IpcCore io\_context (handle\_last\_release callback) exports\_mutex\_ protects pending\_exports\_, lifecycle\_key\_to\_seq\_, released\_entries\_.

ExportEntry destruction must happen outside both exports\_mutex\_ and the io\_context thread because the ipc\_descriptor deleter takes IpcCore::mutex\_ and may re-enter the io\_context. The solution is deferred destruction: handle\_last\_release queues entries into released\_entries\_; the next export\_tensor call drains them on the worker thread, freeing GPU memory inline and moving ipc\_descriptors to a background thread.

```cpp showLineNumbers={false}
#include <holoscan/holoipc_cuda_native_buffer_adapter_base.hpp>
```

**Template parameters**

**Inherits from:** `holoscan::NativeBufferProtocolAdapter` (public)

***

## Constructors

### HoloIpcCudaNativeBufferAdapterBase \[#holoipccudanativebufferadapterbase]

#### Overload 1

```cpp showLineNumbers={false}
holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::HoloIpcCudaNativeBufferAdapterBase(
    std::string adapter_name
)
```

#### Copy (deleted)

```cpp showLineNumbers={false}
holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::HoloIpcCudaNativeBufferAdapterBase(
    const HoloIpcCudaNativeBufferAdapterBase &
) = delete
```

### Destructor \[#destructor]

### \~HoloIpcCudaNativeBufferAdapterBase

```cpp showLineNumbers={false}
holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::~HoloIpcCudaNativeBufferAdapterBase() override
```

***

## Assignment operators

### operator= \[#operator\_assign]

```cpp showLineNumbers={false}
HoloIpcCudaNativeBufferAdapterBase & holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::operator=(
    const HoloIpcCudaNativeBufferAdapterBase &
) = delete
```

***

## Methods

### shutdown \[#shutdown]

```cpp showLineNumbers={false}
void holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::shutdown()
```

### is\_initialized \[#isinitialized]

```cpp showLineNumbers={false}
bool holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::is_initialized() const override
```

### policy \[#policy]

```cpp showLineNumbers={false}
nvidia::gxf::NativeBufferPolicy holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::policy() const
```

### set\_acquire\_timeout \[#setacquiretimeout]

```cpp showLineNumbers={false}
void holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::set_acquire_timeout(
    std::chrono::milliseconds timeout
)
```

### set\_export\_ttl \[#setexportttl]

```cpp showLineNumbers={false}
void holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::set_export_ttl(
    std::chrono::milliseconds ttl
)
```

### set\_use\_eager\_acquire \[#setuseeageracquire]

```cpp showLineNumbers={false}
void holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::set_use_eager_acquire(
    bool enabled
)
```

### default\_protocol\_name \[#defaultprotocolname]

```cpp showLineNumbers={false}
const std::string & holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::default_protocol_name() const override
```

### supports\_protocol \[#supportsprotocol]

```cpp showLineNumbers={false}
bool holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::supports_protocol(
    const std::string &protocol_name
) const override
```

### can\_export\_tensor \[#canexporttensor]

```cpp showLineNumbers={false}
bool holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::can_export_tensor(
    const nvidia::gxf::Tensor &tensor
) const override
```

### descriptor\_format\_version \[#descriptorformatversion]

```cpp showLineNumbers={false}
uint8_t holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::descriptor_format_version() const override
```

### export\_tensor \[#exporttensor]

#### Overload 1

virtual

```cpp showLineNumbers={false}
nvidia::gxf::Expected<std::vector<uint8_t>> holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::export_tensor(
    void *device_ptr,
    const std::shared_ptr<void> &device_ptr_owner,
    const NativeTensorMetadata &tensor_info,
    const std::string &protocol_name,
    uint32_t sequence_num
) override
```

[NativeBufferProtocolAdapter](nativebufferprotocoladapter) interface: converts [NativeTensorMetadata](../structs/nativetensormetadata) to CudaTensorDescriptor and delegates to the CudaTensorDescriptor overload.

#### Export a GPU tensor for CUDA IPC transfer

```cpp showLineNumbers={false}
nvidia::gxf::Expected<std::vector<uint8_t>> holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::export_tensor(
    void *device_ptr,
    const std::shared_ptr<void> &device_ptr_owner,
    const nvidia::gxf::CudaTensorDescriptor &tensor_info,
    const std::string &device_uuid,
    int32_t device_id,
    uint32_t sequence_num
)
```

Export a GPU tensor for CUDA IPC transfer.

Steps:

1. Drain deferred-destroy entries from prior releases (see threading note above)
2. Call gxf::export\_cuda\_ipc\_descriptor() to get CudaIpcDescriptor + mem\_handle
3. Register with holoipc via share\_pointer() using pre-exported handle bytes
4. Encode into DNBX wire format (GXF descriptor + holoipc lifecycle metadata)
5. Track in pending\_exports\_ for lifecycle management

### import\_tensor\_generic \[#importtensorgeneric]

```cpp showLineNumbers={false}
nvidia::gxf::Expected<ImportedNativeTensor> holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::import_tensor_generic(
    const std::vector<uint8_t> &descriptor_bytes,
    const std::string &protocol_name,
    std::chrono::milliseconds timeout = std::chrono::milliseconds{0}
) override
```

[NativeBufferProtocolAdapter](nativebufferprotocoladapter) interface: delegates to import\_tensor() and converts the [NativeBufferHolder](#nativebufferholder) into a generic [ImportedNativeTensor](../structs/importednativetensor).

### import\_tensor \[#importtensor]

```cpp showLineNumbers={false}
nvidia::gxf::Expected<NativeBufferHolder> holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::import_tensor(
    const std::vector<uint8_t> &descriptor_bytes,
    std::chrono::milliseconds timeout = std::chrono::milliseconds{0}
)
```

Decode a DNBX payload and acquire the CUDA IPC mapping via holoipc.

In strict mode (default): sends ACQUIRED, waits for ACK, then opens handle. In eager mode: opens handle locally first, then sends ACQUIRED (no ACK wait). Returns an RAII [NativeBufferHolder](#nativebufferholder) whose destruction sends RELEASED.

### pending\_export\_count \[#pendingexportcount]

```cpp showLineNumbers={false}
size_t holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::pending_export_count() const override
```

### set\_on\_pending\_export\_count\_changed \[#setonpendingexportcountchanged]

```cpp showLineNumbers={false}
void holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::set_on_pending_export_count_changed(
    PendingExportCountChangedCallback callback
) override
```

### evict\_stale\_exports \[#evictstaleexports]

```cpp showLineNumbers={false}
size_t holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::evict_stale_exports(
    std::chrono::milliseconds max_age
)
```

### initialize\_common \[#initializecommon]

```cpp showLineNumbers={false}
nvidia::gxf::Expected<void> holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::initialize_common(
    std::shared_ptr<IpcContextType> ipc_context,
    nvidia::gxf::NativeBufferPolicy policy
)
```

Called by derived-class initialize() after creating the ipc::Context.

### append\_bytes \[#appendbytes]

```cpp showLineNumbers={false}
template <typename T>
static void holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::append_bytes(
    std::vector<uint8_t> &out,
    const T &value
)
```

### append\_buffer \[#appendbuffer]

```cpp showLineNumbers={false}
static void holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::append_buffer(
    std::vector<uint8_t> &out,
    const uint8_t *data,
    size_t sz
)
```

### encode\_exported\_tensor \[#encodeexportedtensor]

```cpp showLineNumbers={false}
static nvidia::gxf::Expected<std::vector<uint8_t>> holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::encode_exported_tensor(
    const nvidia::gxf::CudaIpcDescriptor &gxf_descriptor,
    const PointerDescriptorType &ipc_descriptor
)
```

Serialize GXF CudaIpcDescriptor + holoipc lifecycle metadata into DNBX wire format.

### ensure\_gpu\_info\_initialized \[#ensuregpuinfoinitialized]

```cpp showLineNumbers={false}
void holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::ensure_gpu_info_initialized()
```

### handle\_last\_release \[#handlelastrelease]

```cpp showLineNumbers={false}
void holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::handle_last_release(
    const ipc::Key &key
)
```

holoipc on\_last\_release callback (runs on io\_context thread).

Moves the released entry to released\_entries\_ for deferred destruction; must not destroy ExportEntry here (would deadlock the io\_context).

### evict\_stale\_exports\_locked \[#evictstaleexportslocked]

```cpp showLineNumbers={false}
size_t holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::evict_stale_exports_locked(
    std::chrono::milliseconds max_age,
    std::vector<ExportEntry> &deferred_destroy
)
```

Move exports older than max\_age into deferred\_destroy. Caller holds exports\_mutex\_.

### cleanup\_exports \[#cleanupexports]

```cpp showLineNumbers={false}
void holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::cleanup_exports(
    std::chrono::milliseconds shutdown_grace_period
)
```

Drain all pending exports during shutdown, waiting up to shutdown\_grace\_period for subscribers to send RELEASED before force-evicting.

***

## Static methods

### decode\_exported\_tensor \[#decodeexportedtensor]

#### Overload 1

```cpp showLineNumbers={false}
static nvidia::gxf::Expected<ExportedTensorDescriptor> holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::decode_exported_tensor(
    const std::vector<uint8_t> &descriptor_bytes
)
```

Parse DNBX wire format back into [ExportedTensorDescriptor](#exportedtensordescriptor).

Wire layout: magic | version | handle\_type | ipc\_version | hipc\_blob | key | reply\_topic

#### Single item

```cpp showLineNumbers={false}
static nvidia::gxf::Expected<ExportedTensorDescriptor> holoscan::HoloIpcCudaNativeBufferAdapterBase<TransportType>::decode_exported_tensor(
    const uint8_t *data,
    size_t size
)
```

***

## Types

### Typedefs

| Name                                | Definition                                       |
| ----------------------------------- | ------------------------------------------------ |
| `IpcContextType`                    | `ipc::Context< TransportType >`                  |
| `PointerDescriptorType`             | `typename IpcContextType::PointerDescriptorType` |
| `HandleType`                        | `typename IpcContextType::HandleType`            |
| `PendingExportCountChangedCallback` | `std::function< void(size_t)>`                   |

***

## Member variables

| Name                                      | Type                                          | Description |
| ----------------------------------------- | --------------------------------------------- | ----------- |
| `adapter_name_`                           | `std::string`                                 |             |
| `kExportedTensorMagic` static constexpr   | `uint32_t`                                    |             |
| `kExportedTensorVersion` static constexpr | `uint8_t`                                     |             |
| `kShutdownCleanupSleep` static constexpr  | `auto`                                        |             |
| `kDefaultShutdownGrace` static constexpr  | `auto`                                        |             |
| `ipc_context_`                            | `std::shared_ptr< IpcContextType >`           |             |
| `policy_`                                 | `nvidia::gxf::NativeBufferPolicy`             |             |
| `initialized_`                            | `bool`                                        |             |
| `gpu_device_uuid_`                        | `std::string`                                 |             |
| `gpu_device_id_`                          | `int32_t`                                     |             |
| `gpu_info_initialized_`                   | `bool`                                        |             |
| `acquire_timeout_`                        | `std::chrono::milliseconds`                   |             |
| `use_eager_acquire_`                      | `bool`                                        |             |
| `export_ttl_`                             | `std::chrono::milliseconds`                   |             |
| `pending_exports_`                        | `std::unordered_map< uint32_t, ExportEntry >` |             |
| `lifecycle_key_to_seq_`                   | `std::map< ipc::Key, uint32_t >`              |             |
| `released_entries_`                       | `std::vector< ExportEntry >`                  |             |
| `pending_export_count_changed_callback_`  | `PendingExportCountChangedCallback`           |             |
| `exports_mutex_`                          | `std::mutex`                                  |             |

***

## Inner classes

### NativeBufferHolder

```cpp showLineNumbers={false}
struct holoscan::HoloIpcCudaNativeBufferAdapterBase::NativeBufferHolder
```

RAII holder for a lifecycle-managed CUDA IPC mapping.

| Name             | Type                             | Description |
| ---------------- | -------------------------------- | ----------- |
| `descriptor`     | `nvidia::gxf::CudaIpcDescriptor` |             |
| `ipc_device_ptr` | `std::shared_ptr< void >`        |             |

### ExportedTensorDescriptor

```cpp showLineNumbers={false}
struct holoscan::HoloIpcCudaNativeBufferAdapterBase::ExportedTensorDescriptor
```

Decoded DNBX payload: GXF CUDA IPC descriptor + holoipc lifecycle metadata.

| Name                            | Type                             | Description |
| ------------------------------- | -------------------------------- | ----------- |
| `gxf_descriptor`                | `nvidia::gxf::CudaIpcDescriptor` |             |
| `lifecycle_key`                 | `std::vector< uint8_t >`         |             |
| `lifecycle_reply_to_topic_name` | `std::string`                    |             |
| `handle_type`                   | `int32_t`                        |             |
| `ipc_protocol_version`          | `std::string`                    |             |

### ExportEntry

```cpp showLineNumbers={false}
struct holoscan::HoloIpcCudaNativeBufferAdapterBase::ExportEntry
```

Tracks a single exported tensor for lifecycle management.

Holds the holoipc descriptor (controls RELEASED on drop), the GPU memory owner (prevents cudaFree while subscribers hold the mapping), and timing for TTL eviction.

| Name               | Type                                       | Description |
| ------------------ | ------------------------------------------ | ----------- |
| `ipc_descriptor`   | `std::shared_ptr< PointerDescriptorType >` |             |
| `device_ptr_owner` | `std::shared_ptr< void >`                  |             |
| `gxf_descriptor`   | `nvidia::gxf::CudaIpcDescriptor`           |             |
| `lifecycle_key`    | `ipc::Key`                                 |             |
| `export_time`      | `std::chrono::steady_clock::time_point`    |             |