3D visionExplainer

GPU point cloud memory layout: shapes, strides and alignment

Understand GPU point cloud memory layout with worked byte-stride calculations, organized versus unorganized shapes, and checks for alignment errors.

LumaSpec Vision10 min read Share on LinkedIn

On this page 10 sections
  1. 01Start with the memory contract, not the pointer
  2. 02Identify organized grids and unorganized lists
  3. 03Convert stride units explicitly
  4. 04Work through an address calculation
  5. 05Treat alignment and channel meaning separately
  6. 06Validate indexing with a deliberately distinctive buffer
  7. 07Separate storage errors from geometry and lifetime errors
  8. 08Choose acquisition and processing hardware independently
  9. 09Use a short acceptance checklist
  10. 10Questions

A GPU pointer tells you where a point cloud starts, not how to read it. Incorrect assumptions about scalar types, channel order or row pitch can turn valid measurements into scrambled coordinates without causing an obvious access error. This explainer is for developers connecting depth acquisition to custom GPU processing. You will learn how to describe the buffer, calculate addresses and validate indexing before applying filters or measurements.

Start with the memory contract, not the pointer

GPU point cloud memory layout is the agreement between the producer writing a buffer and the consumer reading it. Obtain that agreement from documented format information and runtime metadata. Do not infer it from a screenshot, a familiar format name or the apparent size of an allocation.

Record these fields before processing:

  • Device and memory backend: where the allocation can legally be accessed.
  • Scalar type: floating-point or integer, including its storage width.
  • Channel meaning and order: XYZ, depth, normals, color or another documented arrangement.
  • Shape: the length of each logical axis.
  • Strides: the distance between adjacent entries along each axis, with explicit units.
  • Accessible extent: how much storage the view is allowed to address.
  • Ownership and readiness: what keeps the allocation alive and when its contents become readable.

Distinguish a scalar from a point record. A float32 XYZ point contains three scalars, occupying 12 bytes when tightly packed. An API's element count might mean points, pixels or scalars; check its definition rather than multiplying by a guessed channel count.

This article focuses on interpreting storage. For the separate task of passing device storage into a model, use feeding GPU tensors to a vision model without a CPU round trip.

Identify organized grids and unorganized lists

An organized cloud retains a rectangular sampling grid. A location has both a row and a column, often corresponding to a depth-image pixel. Invalid measurements can remain in that grid as documented sentinel values or validity flags.

An unorganized cloud is a list of points. It has a point count but no inherent image width or height. Removing invalid points commonly creates this representation, although the exact behavior depends on the producer.

The following table shows common logical views for interleaved storage. These are examples, not guarantees about any camera or SDK.

Representation Example scalar type Logical shape Tight strides in scalars
Organized XYZ float32 [H, W, 3] [W × 3, 3, 1]
Organized depth float32 [H, W] [W, 1]
Unorganized XYZ float32 [N, 3] [3, 1]
Unorganized depth values float32 [N] [1]
Organized RGBA color uint8 [H, W, 4] [W × 4, 4, 1]

Some interfaces retain a singleton channel axis, while others omit it. A depth buffer described as [H, W, 1] may contain the same values as [H, W], but the consumer must accept the declared dimensionality.

Flattening an organized cloud without removing or reordering entries can preserve correspondence through an index calculation. Compacting it cannot preserve that correspondence implicitly. Keep an index map when later processing must return to image coordinates.

If the source grid itself has changed size, investigate depth image resolution and decimation before treating the discrepancy as a stride error.

Convert stride units explicitly

A stride measures how far an address advances when one index increases. Some interfaces express that distance in bytes. Others express it in scalar elements. A record stride can use yet another convention, so label every value.

For an interleaved view with nonnegative byte strides, addressing follows:

address(r, c, k) = base + r × Srow + c × Spoint + k × Schannel byte stride = scalar-element stride × bytes per scalar

Here, r is the row, c the column and k the channel. The base address must refer to the start of the view, which may differ from the start of its underlying allocation.

For tightly packed float32 XYZ data, the channel stride is 4 bytes and the point stride is 12 bytes. The row stride is the width multiplied by 12 bytes. Those relationships cease to apply when the producer inserts padding or exposes a sliced view.

A common failure is supplying scalar-element strides to a consumer expecting byte strides. For float32, that makes each address increment four times smaller than intended. The reverse mistake makes increments four times larger and can move reads outside the view.

For positive dimensions and nonnegative strides, the addressed span is:

required span = (H − 1) × Srow + (W − 1) × Spoint + (C − 1) × Schannel + bytes per scalar

Compare this span with the accessible extent beginning at the view's base. It measures the storage range touched, not the number of meaningful data bytes. Empty dimensions, negative strides and overlapping views require separate handling under the consumer's documented rules.

Work through an address calculation

Consider a synthetic organized XYZ cloud with height 480, width 640 and float32 coordinates. Assume interleaved channels and no padding. These are application example values, not product specifications.

The tight layout is:

shape = [480, 640, 3] scalar-element strides = [640 × 3, 3, 1] = [1920, 3, 1] byte strides = [7680, 12, 4] payload = 480 × 640 × 3 × 4 = 3,686,400 bytes

To read Z at row 17, column 23, select channel index 2:

byte offset = 17 × 7680 + 23 × 12 + 2 × 4 = 130,560 + 276 + 8 = 130,844 bytes

Now suppose runtime metadata reports a row pitch of 8192 bytes. The shape is unchanged, but the row stride is different:

byte offset = 17 × 8192 + 23 × 12 + 2 × 4 = 139,264 + 276 + 8 = 139,548 bytes

Using the tight formula would read 8704 bytes before the intended location. Checking only the first row would miss this mistake because the row term is zero there.

Test the first point of the second row, an interior point and the final valid point. Together, those checks exercise row pitch, point spacing, channel selection and bounds. A successful read at the base address proves very little.

Treat alignment and channel meaning separately

Packed XYZ and padded coordinate records can look similar while requiring different indexing. Three float32 coordinates occupy 12 bytes when packed. Four float32 lanes occupy 16 bytes, but the fourth lane's meaning must come from the format definition.

It might contain a homogeneous coordinate, padding or another field. Do not divide coordinates by it, initialize it or treat it as confidence without documentation.

Alignment belongs to addresses, not names. With an appropriately aligned base and a 16-byte record stride, successive records can maintain 16-byte alignment. A 12-byte stride does not maintain that alignment for every point. A row pitch or subview offset can also change the alignment of later accesses.

Likewise, a compiler-defined vector or structure may have padding that differs from the incoming buffer. Check its size, alignment and field offsets before using it to interpret external storage. Matching field names is insufficient.

A wider record is not automatically faster. Four float32 lanes transfer 16 bytes rather than 12 bytes per point, adding about 33% to coordinate storage. Whether aligned vector access offsets that increase depends on the kernel, hardware and memory-access pattern.

Color needs the same discipline. RGBA and BGRA can have identical dimensions and storage sizes but different channel meanings. Linear and nonlinear color encodings may also share a layout. The distinction is explained separately in linear RGB versus sRGB for images and point clouds.

Validate indexing with a deliberately distinctive buffer

Real clouds often contain smooth surfaces, repeated values and invalid regions. Such data can hide incorrect indexing. Start with a small synthetic buffer whose expected coordinates are unmistakable.

  1. Define a test grid with 3 rows, 5 columns and XYZ channels. Use the same scalar type as the intended processing path.
  2. Assign X = 1000 + 100 × row + 10 × column, then assign Y = X + 1 and Z = X + 2.
  3. Read the metadata supplied to the consumer. Confirm shape, stride units, channel order and accessible extent.
  4. Run a minimal kernel that reads selected coordinates into a small diagnostic output. Avoid filtering, transforms and reductions at this stage.
  5. Compare that output with an independently indexed host reference. Copying a few diagnostic values is sufficient; a full-frame transfer is unnecessary.
  6. Repeat with padded rows or an offset view if the production interface can produce them. Verify rejection if your consumer supports only contiguous storage.

At row 1, column 2, the expected coordinates are X = 1120, Y = 1121 and Z = 1122. Reading neighboring values immediately suggests a channel or point-stride problem. Errors that first appear after the row boundary suggest row-pitch handling.

Also test documented invalid values. A point containing a non-finite coordinate must not silently become a valid origin point through an unrelated conversion. Keep validity handling separate from address calculation so each can be verified independently.

Separate storage errors from geometry and lifetime errors

Correct memory layout does not establish coordinate units, axis directions or the reference frame. A correctly read cloud can still be mirrored, rotated or scaled incorrectly by downstream assumptions.

Use transforming point clouds between optical and camera frames when indexing is correct but orientation is wrong. If a depth value is numerically plausible yet produces incorrect distances, inspect the unit conversion before changing strides.

Resizing or aligning depth and texture images can also change pixel-to-ray relationships. The relevant issue is calibration, as covered in intrinsic parameter conversion for depth and texture images.

Finally, a valid layout can describe storage that is no longer safe to access. Retain the documented owner, honor producer-consumer synchronization and stop using a buffer after its permitted lifetime ends. Intermittent corruption after acquisition stops belongs in the investigation described by managing GPU buffers when a camera closes, not in a channel-order workaround.

Choose acquisition and processing hardware independently

The memory contract should be an integration acceptance criterion when selecting 3D sensors. Start with the camera finder, then request the acquisition interface documentation for each candidate. Confirm which outputs are available and how their storage is described.

The MV-DLS300P-04 is cataloged as a stereo / structured-light camera. Its listing does not establish a GPU-resident point-cloud interface or a particular memory layout.

3D sensorsHikrobot MV-DLS300P-04 Laser galvanometer stereo cameraMV-DLS300P-04
Type
Stereo / structured light
$16,579.00 · quotedView and quote

The MV-DPS200P-02 is a projected structured-light camera. Apply the same interface checks before choosing it for a custom processing pipeline.

3D sensorsHikrobot MV-DPS200P-02 Projected structured-light 3D cameraMV-DPS200P-02
Type
Stereo / structured light
$8,829.00 · quotedView and quote

For vision controllers, check the documented acquisition interfaces and processing requirements separately. The category name alone does not establish GPU availability, device-buffer export or compatibility with a particular compute backend.

Neither sensor type nor controller connectivity proves that a proposed device-memory handoff will work. Obtain documentation from the manufacturer or its authorized distributor, and validate the intended acquisition-to-processing path before committing to hardware.

Use a short acceptance checklist

Before deploying the processing stage, confirm:

  • Scalar width and channel order are explicit, rather than inferred from buffer size.
  • Shape reflects a grid or list correctly, including any singleton axes.
  • Every stride has a declared unit and matches the consumer's convention.
  • The required address span fits inside the accessible view.
  • Base offsets, row padding and record alignment are handled or explicitly rejected.
  • Invalid samples and any compaction index map retain their documented meaning.
  • Ownership and synchronization remain valid through the final consumer operation.
  • A small independent reference agrees at row boundaries and the final point.

Tight interleaved storage is a useful special case, not a universal default. When an interface supplies reliable stride metadata, use it. When a consumer requires contiguous storage, perform an explicit supported conversion rather than describing padded memory as contiguous.

For help assessing an acquisition interface before ordering, send the required output format, dimensions, processing backend and representative metadata through application support. Those details make the hardware discussion concrete without assuming a memory layout that the catalog does not promise.

Questions

How do I know whether point cloud strides use bytes or elements?

Check the API's documented stride convention and the consumer's expected units. For scalar-element strides, multiply by the scalar storage width to obtain bytes. A float32 scalar occupies 4 bytes, so a point stride of three scalar elements becomes 12 bytes. Do not apply that conversion to values already expressed in bytes.

Can I reshape an organized point cloud into a point list?

Only when the view preserves the expected ordering, channel arrangement and storage continuity. Padding or a permutation may require a strided view or an explicit copy. If invalid points have been removed, reshaping cannot recover their original image positions without an accompanying index map.

Is a four-lane coordinate record always better than packed XYZ?

No. The extra lane may provide useful alignment, but it also increases storage and transfer volume. Performance depends on the consumer's access pattern, compiler representation and GPU architecture. Benchmark a correct implementation first, and never assume the fourth lane contains a usable coordinate or validity flag.

Why does the first row look correct while later rows are corrupted?

The first row does not exercise the row-stride term in the address calculation. If you assumed tight packing but the producer padded each row, the error begins at the next row. Read the reported pitch and compare a few locations on both sides of a row boundary.

Does correct memory layout guarantee correct measurement units and axes?

No. Memory layout describes how values occupy storage, not their physical interpretation. Coordinate units, handedness, reference frames and calibration require separate documentation. Verify those after the raw values match an independently indexed reference, so a geometry correction does not hide an addressing mistake.