Repository navigation
Description
Summary
Add non-owning immutable and mutable contiguous views over DeviceBuffer<T> and allow them to be passed directly through generated typed kernel launchers.
Possible host-side types:
DeviceSlice<'a, T>
DeviceSliceMut<'a, T>The views should lower to the existing slice ABI:
adjusted device pointer + view element count
No new allocation, copy, or ownership transfer is required.
Motivation
A single device allocation often contains several logical vectors, rows, tiles, or temporary regions. Today, operating on one contiguous subrange generally requires either:
- allocating another
DeviceBuffer; - copying the region;
- launching the kernel;
- copying the result back;
or introducing downstream wrapper/descriptors and custom kernel parameter types.
Constructing an owning DeviceBuffer from an interior pointer is not safe because it could free an interior address or cause double ownership of the allocation.
The desired usage is:
let mut buffer = DeviceBuffer::<f32>::zeroed(&stream, rows * cols)?;
let mut row = buffer.slice_mut(start..start + cols)?;
module.scale(
&stream,
&prepared,
&mut row,
2.0,
)?;The subview should borrow the original allocation, expose the adjusted pointer and subview length, and never free memory.
Proposed API
impl<T> DeviceBuffer<T> {
pub fn slice<R>(
&self,
range: R,
) -> Result<DeviceSlice<'_, T>, DeviceSliceError>
where
R: RangeBounds<usize>;
pub fn slice_mut<R>(
&mut self,
range: R,
) -> Result<DeviceSliceMut<'_, T>, DeviceSliceError>
where
R: RangeBounds<usize>;
}Suggested view operations:
DeviceSlice::cu_deviceptr
DeviceSlice::len
DeviceSlice::is_empty
DeviceSlice::split_at
DeviceSliceMut::cu_deviceptr
DeviceSliceMut::len
DeviceSliceMut::is_empty
DeviceSliceMut::split_at_mut
DeviceSliceMut::into_sharedAn immutable view may be Copy/Clone.
A mutable view must not be Copy or Clone, and operations producing multiple mutable views must prove that the resulting regions are disjoint.
Typed launcher integration
Generated launchers should accept borrowed views anywhere the corresponding kernel parameter uses the standard slice ABI.
For example:
#[kernel]
fn read(input: &[f32]) {
// ...
}should accept either a full DeviceBuffer<f32> or a DeviceSlice<f32>.
Likewise, writable slice-like kernel parameters should accept DeviceSliceMut<T>.
The existing slice ABI can be generalized behind public argument traits such as:
KernelSliceArg
KernelSliceArgMutso both owned buffers and borrowed subviews expose:
device pointer + element count
without allocation or copying.
Generated launch-contract checks using .len() must evaluate the subview length, not the parent allocation length.
Safety requirements
- Validate range bounds.
- Check element-to-byte offset multiplication.
- Check device-pointer addition.
- Views must never free the underlying allocation.
- Views must not outlive the parent
DeviceBuffer. - Mutable views must retain exclusive borrowing semantics.
- Mutable splits must produce disjoint regions.
- Empty ranges must be representable safely.
- The parent allocation must keep its CUDA context alive while views exist.
- Async behavior should retain the same safety guarantees as launching with a full
DeviceBuffer.
Scope
This feature is limited to contiguous host-side borrowing and typed launcher integration.
It does not require:
- strided or tensor views;
- device-side Rust subslicing;
- changes to
DisjointSliceindexing; - an owning constructor from an interior pointer;
- new CUDA allocation primitives;
- reductions or concatenation helpers.
Acceptance criteria
A complete solution should allow, without allocation or copying:
- creating an immutable contiguous subview of
DeviceBuffer<T>; - creating an exclusive mutable contiguous subview;
- splitting a mutable view into proven-disjoint regions;
- passing immutable views to kernels declared with standard immutable slice parameters;
- passing mutable views to kernels declared with standard writable slice-like parameters;
- using the subview length in generated launch validation.
Activity
uurl commentedon Aug 20, 2026
Duplicate of #968. I opened PR #1081 implementing the requested borrowed DeviceBuffer subviews and typed-launch integration.
DeviceBuffersubviews for typed kernel launches #968