DeviceArray Reference
Introduction
DeviceArray is a handle to a block of data that lives in GPU memory instead of CPU memory.
It is reference-counted, so the data stays alive as long as at least one handle to it exists.
This page describes the data layout: how each pixel or point of a DeviceArray is stored in memory, for every supported format.
If you run your own GPU code (a CUDA or OpenCL kernel, or a framework such as PyTorch, CuPy, or OpenCV) against the buffer, see DeviceArray — Stream, Queue and Context for how the SDK orders its work against yours and when a shared GPU context is required. For a task-oriented walkthrough with code samples, see GPU Access Tutorial.
Data Layout
Every DeviceArray<Format> stores its elements in row-major order with channels interleaved.
The channel count is determined by Format and never varies at runtime.
Whether the buffer is 1D, 2D, or 3D depends on the channel count of the format and whether the source is organized or unorganized.
Format catalog
Format |
Element type |
Channels |
Bytes / element |
Typical source |
|---|---|---|---|---|
|
|
3 |
12 |
|
|
|
4 |
16 |
|
|
|
1 |
4 |
|
|
|
1 |
4 |
|
|
|
3 |
12 |
|
|
|
4 |
4 |
|
|
|
4 |
16 |
|
|
|
3 |
3 |
|
Shape and stride rules
The shape depends on channel count and organization. Strides are in element counts (not bytes) and follow row-major C order.
Case |
Dimensions |
Shape |
Strides (elements) |
|---|---|---|---|
Organized, multi-channel |
3 |
|
|
Organized, single-channel |
2 |
|
|
Unorganized, multi-channel |
2 |
|
|
Unorganized, single-channel |
1 |
|
|
Use stridesInBytes() when the consumer framework wants byte strides.
Interleaved multi-channel formats
An organized multi-channel buffer such as DeviceArray<PointXYZ> from an image of height H and width W is one tightly packed block.
Each pixel contributes C consecutive elements before the next pixel begins.
There are no per-plane offsets and no padding between rows.
The following diagram illustrates a 2x3 PointXYZ buffer.
Each pixel (r, c) holds three floats X, Y, Z, laid out consecutively in memory.
Pixel grid (shape = [2, 3, 3]):
col 0 col 1 col 2
+----------------+----------------+----------------+
| X00 Y00 Z00 | X01 Y01 Z01 | X02 Y02 Z02 | row 0
+----------------+----------------+----------------+
| X10 Y10 Z10 | X11 Y11 Z11 | X12 Y12 Z12 | row 1
+----------------+----------------+----------------+
Flat memory (row-major, channel-interleaved):
offset (floats): 0 1 2 3 4 5 6 7 8 9 10 11 ...
+---+---+---+---+---+---+---+---+---+---+---+---+
|X00|Y00|Z00|X01|Y01|Z01|X02|Y02|Z02|X10|Y10|Z10|...
+---+---+---+---+---+---+---+---+---+---+---+---+
\_________/ \_________/ \_________/
pixel (0,0) pixel (0,1) pixel (0,2)
strides (elements): [W*C=9, C=3, 1]
strides (bytes) : [36, 12, 4]
The same layout applies to PointXYZW (4 channels), NormalXYZ (3), ColorRGBA / BGRA and their SRGB variants (4x uint8), ColorRGBAf (4x float), and ColorRGB / BGR (3x uint8).
Only the channel count and element type change.
Tip
PointXYZW exists so that each point is 16-byte aligned, which most GPU APIs and vector loads prefer.
ColorRGB / BGR at 3 bytes per pixel is not naturally aligned; prefer the 4-channel variants when the consumer benefits from alignment.
Planar single-channel formats
Formats with one channel (PointZ, SNR) have no channel axis.
An organized buffer is a plain 2D matrix.
Pixel grid (shape = [2, 3]):
col 0 col 1 col 2
+---------+---------+---------+
| Z00 | Z01 | Z02 | row 0
+---------+---------+---------+
| Z10 | Z11 | Z12 | row 1
+---------+---------+---------+
Flat memory (row-major):
offset: 0 1 2 3 4 5
+----+----+----+----+----+----+
|Z00 |Z01 |Z02 |Z10 |Z11 |Z12 |
+----+----+----+----+----+----+
strides (elements): [W=3, 1]
strides (bytes) : [12, 4] (float)
Unorganized point clouds
An unorganized PointCloud produces a flat list of N elements with no height.
Multi-channel formats collapse the row dimension and keep interleaved channels.
Single-channel formats collapse to plain 1D.
Unorganized PointXYZ (shape = [N, 3]):
offset (floats): 0 1 2 3 4 5 6 7 8 ...
+---+---+---+---+---+---+---+---+---+
|X0 |Y0 |Z0 |X1 |Y1 |Z1 |X2 |Y2 |Z2 |...
+---+---+---+---+---+---+---+---+---+
\_________/ \_________/ \_________/
point 0 point 1 point 2
strides (elements): [3, 1]
Unorganized SNR (shape = [N]):
offset (floats): 0 1 2 3 ...
+----+----+----+----+
|s0 |s1 |s2 |s3 |...
+----+----+----+----+
strides (elements): [1]
Reading the layout at runtime
The metadata accessors mirror the model above.
shape()returns astd::vector<int>of length 1, 2, or 3.strides()returns strides in element counts.stridesInBytes()returns strides in bytes.size()returns the number of logical elements (points or pixels, not channels).sizeInBytes()returns the total byte size of the buffer.backend()returnsComputeBackend::cudaorComputeBackend::opencl.
See Also
DeviceArray — Stream, Queue and Context for the stream / queue ordering and GPU context-sharing model, needed when running your own GPU code.
GPU Access Tutorial for end-to-end usage and framework integration samples.
Advanced: Data Access for how
DeviceArrayfits into the wider camera API surface.