Skip to content

Commit 52da7cf

Browse files
[lang][nfc] Add stubs and docstrings to pointer and array types
Signed-off-by: Asher Mancinelli <amancinelli@nvidia.com>
1 parent 23e80ab commit 52da7cf

2 files changed

Lines changed: 117 additions & 59 deletions

File tree

experimental/cuda-lang/src/cuda/lang/_stub/core_api.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,30 @@ def shape(self): ...
4545
def strides(self): ...
4646

4747
@stub
48-
def get_base_pointer(self) -> "Pointer[T]": ...
48+
def get_base_pointer(self) -> "Pointer[T]":
49+
"""Retrieve the base pointer for this array."""
50+
...
4951

5052
@stub
51-
def get_element_pointer(self, indices: int | tuple[int, ...]) -> "Pointer[T]": ...
53+
def get_element_pointer(self, indices: int | tuple[int, ...]) -> "Pointer[T]":
54+
"""Retrieve a pointer to the array element accessed by ``indices``.
55+
Equivalent to &array[index] in CUDA C++, but valid for arrays of any
56+
rank."""
57+
...
5258

5359
@stub
54-
def __setitem__(self, indices: int | tuple[int, ...], value: T): ...
60+
def __setitem__(self, indices: int | tuple[int, ...], value: T):
61+
"""Assign ``value`` to index given by ``indices``.
62+
Equivalent to ``self.get_element_pointer(indices).store(value).
63+
"""
64+
...
5565

5666
@stub
57-
def __getitem__(self, indices: int | tuple[int, ...]) -> T: ...
67+
def __getitem__(self, indices: int | tuple[int, ...]) -> T:
68+
"""Retriev value given by ``indices``.
69+
Equivalent to ``self.get_element_pointer(indices).load().
70+
"""
71+
...
5872

5973

6074
@stub(host=True)

experimental/cuda-lang/src/cuda/lang/_stub/types.py

Lines changed: 99 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,51 @@ def __len__(self): ...
177177

178178

179179
class Pointer(Generic[T]):
180-
"""Typed address into a CUDA memory space with low-level load and store operations."""
180+
"""Address in a CUDA memory space.
181+
182+
A typed pointer identifies the data type at its address. An opaque pointer
183+
does not identify a data type. Pointer arithmetic and memory access require
184+
a typed pointer.
185+
Pointer offsets are given in element counts, not in bytes.
186+
"""
187+
188+
@stub
189+
def __add__(self, other):
190+
"""Return a pointer that is ``other`` elements after this pointer.
191+
192+
Args:
193+
other: Integral scalar that gives the element offset.
194+
"""
195+
196+
@stub
197+
def __sub__(self, other):
198+
"""Return a pointer that is ``other`` elements before this pointer.
199+
200+
Args:
201+
other: Integral scalar that gives the element offset.
202+
"""
203+
204+
@stub
205+
def __getitem__(self, index):
206+
"""Load one value at an element offset from this pointer.
207+
208+
``self[index]`` is equivalent to ``(self + index).load()``.
209+
210+
Args:
211+
index: Integral scalar that gives the element offset.
212+
"""
213+
214+
@stub
215+
def __setitem__(self, index, value):
216+
"""Store one value at an element offset from this pointer.
217+
218+
``self[index] = value`` is equivalent to
219+
``(self + index).store(value)``.
220+
221+
Args:
222+
index: Integral scalar that gives the element offset.
223+
value: Value to store.
224+
"""
181225

182226
@stub
183227
def load(
@@ -188,81 +232,81 @@ def load(
188232
volatile: bool = False,
189233
memory_order: MemoryOrder | None = None,
190234
) -> T | Vector[T]:
191-
"""
192-
Low-level API to read from memory.
235+
"""Load one or more consecutive values from this address.
236+
237+
This operation is valid only for a typed pointer.
193238
194239
Args:
195-
count: If count is provided, a vector will be returned.
196-
For best performance, vector loads should be aligned to the
197-
number of bytes in the vector.
198-
alignment: Inform the compiler that the address being loaded from
199-
is aligned to at least this many bytes.
200-
The user is responsible for ensuring aligned loads occur only
201-
on appropriately aligned pointers.
202-
If alignment is None, do not give the compiler any alignment
203-
hints.
204-
volatile: If True, the compiler will not modify the number of times
205-
this load is performed nor the order of execution with respect
206-
to other volatile operations.
207-
memory_order: When memory_order is specified, the load is atomic.
208-
If alignment is None, the natural alignment of the loaded type
209-
(its size in bytes) is used.
210-
Atomic loads require a pointee type with a bit width that
211-
is a power of two greater than or equal to one byte.
240+
count: Compile-time number of values to load. ``None`` and ``1``
241+
return a scalar. A value greater than ``1`` returns a vector.
242+
For best performance, align a vector load to the total size of
243+
the vector in bytes.
244+
alignment: Minimum byte alignment that the compiler can assume.
245+
The value must be a positive power of two. The address must
246+
have this alignment. If the value is ``None``, the compiler
247+
does not get an alignment hint. For an atomic load, the
248+
default is the natural alignment of the pointee data type.
249+
volatile: If ``True``, the compiler preserves this load and its
250+
order relative to other volatile operations.
251+
memory_order: Memory order for the load. ``None`` and
252+
``MemoryOrder.WEAK`` select a non-atomic load.
253+
``MemoryOrder.RELAXED`` and ``MemoryOrder.ACQUIRE`` select an
254+
atomic load. An atomic load must load one value. The pointee
255+
size must be a power-of-two number of bytes.
212256
"""
213257

214258
@stub
215259
def store(
216-
self,
217-
value: T | Vector[T],
218-
*,
219-
alignment: int | None = None,
220-
volatile: bool = False,
221-
memory_order: Literal[MemoryOrder.RELAXED,
222-
MemoryOrder.RELEASE, MemoryOrder.WEAK] | None = None,
260+
self,
261+
value: T | Vector[T],
262+
*,
263+
alignment: int | None = None,
264+
volatile: bool = False,
265+
memory_order: Literal[
266+
MemoryOrder.RELAXED, MemoryOrder.RELEASE, MemoryOrder.WEAK
267+
]
268+
| None = None,
223269
) -> None:
224-
"""
225-
Low-level API to store to memory.
270+
"""Store one or more consecutive values at this address.
271+
272+
This operation is valid only for a typed pointer. A scalar value stores
273+
one value. A vector stores all its elements in consecutive locations.
226274
227275
Args:
228-
value: Scalar or vector to be stored to the given address.
229-
alignment: Inform the compiler that the address being stored to
230-
is aligned to at least this many bytes.
231-
The user is responsible for ensuring aligned loads occur only
232-
on appropriately aligned pointers.
233-
If alignment is None, do not give the compiler any alignment
234-
hints.
235-
volatile: If True, the compiler will not modify the number of times
236-
this store is performed nor the order of execution with respect
237-
to other volatile operations.
238-
memory_order: When memory_order is specified, the store is atomic.
239-
If alignment is None, the natural alignment of the stored type
240-
(its size in bytes) is used.
241-
Atomic stores require a pointee type with a bit width that
242-
is a power of two greater than or equal to one byte.
243-
Only relaxed, release, and weak are valid memory orders on
244-
stores.
276+
value: Scalar or vector to store. The value must be compatible with
277+
the pointee data type.
278+
alignment: Minimum byte alignment that the compiler can assume.
279+
The value must be a positive power of two. The address must
280+
have this alignment. If the value is ``None``, the compiler
281+
does not get an alignment hint. For an atomic store, the
282+
default is the natural alignment of the pointee data type.
283+
volatile: If ``True``, the compiler preserves this store and its
284+
order relative to other volatile operations.
285+
memory_order: Memory order for the store. ``None`` and
286+
``MemoryOrder.WEAK`` select a non-atomic store.
287+
``MemoryOrder.RELAXED`` and ``MemoryOrder.RELEASE`` select an
288+
atomic store. An atomic store must store one value. The pointee
289+
size must be a power-of-two number of bytes.
245290
"""
246291

247292
@property
248293
@stub
249294
def opaque(self) -> bool:
250-
"""
251-
Whether the pointer is opaque, i.e. doesn't point to a value of a specific data type.
252-
This is a compile-time constant boolean.
295+
"""Whether the pointer has no pointee data type.
296+
297+
This value is a compile-time constant.
253298
"""
254299

255300
@property
256301
@stub
257302
def pointee_dtype(self) -> DType:
258-
"""
259-
Data type of the value that this pointer points to.
260-
Raises a compilation error if the pointer is opaque.
303+
"""Data type of the value at this address.
304+
305+
Access to this property causes a compilation error if the pointer is
306+
opaque.
261307
"""
262308

263309
@property
264310
@stub
265311
def memory_space(self) -> MemorySpace:
266-
"""
267-
Memory space of this pointer.
268-
"""
312+
"""CUDA memory space of this pointer."""

0 commit comments

Comments
 (0)