Skip to content

Refactor raw allocations + typed buffers (replace UniqueArray / introduce BufferStorage and ImageStorage) #3

Description

@akrivx

Context

Current ownership for 1D/2D allocations is handled via UniqueArray<T, Loc> (a std::unique_ptr<T[]> with CUDA deleters) plus helper factories (make_unique_array, make_unique_array2d). This mixes two concerns:

  1. Owning untyped storage returned by cudaMalloc* (bytes, no constructors/destructors).
  2. Presenting that storage as an "array of T".

For device/pinned allocations, constructors/destructors are never run, so UniqueArray<T, Loc> is only sound for "POD-like" T (std::is_standard_layout is insufficient for this: types can be standard-layout but still non-trivial). We need clearer semantics and constraints.

Goals

  1. Make the ownership layer explicitly byte-based (no implicit "array of T" promise for device/pinned).
  2. Keep BufferView<T, Loc> as the universal typed non-owning view.
  3. Kepp Buffer<T, Loc> as the boring RAII owner for Host/Pinned/Device, implemented on top of a small BufferStorage<Loc> (raw bytes).
  4. Move pitched/2D allocation ownership into a dedicated ImageStorage module, used by Image.

Proposed Changes

  • Introduce BufferStorage<Loc> (raw byte owner):
    • stores void* ptr + std::size_t nbytes
    • RAII free via:
      • Host: operator new/delete (aligned as needed)
      • Host-pinned: cudaMallocHost/cudaFreeHost
      • Device: cudaMalloc/cudaFree
    • Destructors must be noexcept; CUDA free errors handled by CUDA_CHECK_TERMINATE
  • Refactor Buffer<T, Loc>:
    • implemented as {BufferStorage<Loc> storage; std::size_t count;}
    • data() returns static_cast<T*>(storage.data())
    • add element constraint (e.g., BufferElement<T> = trivially copyable + trivially default destructible)
  • Remove UniqueArray and associated factories
  • Introduce ImageStorage<T, Loc> in a separate header (e.g. image_storage.hpp):
    • owns allocation for 2D pitched storage + metadata (pitch_bytes, height, width)
    • Device uses cudaMallocPitch; host/pinned uses contiguous or aligned-pitch allocation (TBD)
    • Image becomes a thin wrapper over ImageStorage + view/accessors.

Acceptance Criteria

  • Buffer<T, Loc> retains the same public surface (data/size/view/cview, move-only).
  • Buffers cannot be instantiated with non-POD-like element types (enforced at compile time).
  • Image no longer depends on make_unique_array2d; pitched ownership is centralised in ImageStorage.
  • Tests/examples updated accordingly and pass/work.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions