From 279f90c2d06c3fca862018ec69e9031c090f9959 Mon Sep 17 00:00:00 2001 From: Andy Jost Date: Wed, 10 Dec 2025 12:29:56 -0800 Subject: [PATCH] Add design proposal for Buffer.fill() redesign Design document addressing feedback from PR #1318 that was prematurely merged. Proposes Option C (Hybrid Approach): - Buffer.fill() infers width from value type (int, numpy scalar, bytes) - StridedMemoryView.fill() uses view's dtype for width/signedness - Removes explicit width parameter Related to #1345 --- cuda_core/docs/design/buffer-fill-redesign.md | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 cuda_core/docs/design/buffer-fill-redesign.md diff --git a/cuda_core/docs/design/buffer-fill-redesign.md b/cuda_core/docs/design/buffer-fill-redesign.md new file mode 100644 index 00000000000..f1f7bfb3108 --- /dev/null +++ b/cuda_core/docs/design/buffer-fill-redesign.md @@ -0,0 +1,77 @@ +# Buffer.fill() Redesign Proposal + +**Issue**: [#1345 - Revisit `Buffer.fill()`](https://github.com/NVIDIA/cuda-python/issues/1345) +**Author**: Andy Jost +**Date**: December 10, 2025 + +## Background + +PR #1318 implemented `Buffer.fill(value, width, *, stream)` but was merged before review feedback was addressed. This document proposes a simplified API based on that feedback. + +## Proposed API + +```python +def fill(self, value, *, stream: Stream | GraphBuilder): + """Fill buffer with a repeating byte pattern. + + Parameters + ---------- + value : int or buffer-protocol object + - int: Must be in range [0, 256). Converted to 1 byte. + - buffer-protocol object: Must be 1, 2, or 4 bytes. + stream : Stream | GraphBuilder + Stream for the asynchronous fill operation. + + Raises + ------ + TypeError + If value is not an int and does not support the buffer protocol. + ValueError + If value byte length is not 1, 2, or 4. + If buffer size is not divisible by value byte length. + OverflowError + If int value is outside [0, 256). + """ +``` + +## Implementation + +```python +def get_fill_pattern(value): + if isinstance(value, int): + return value.to_bytes(1, 'little') # Raises OverflowError if not in [0, 256) + mv = memoryview(value) + return mv.tobytes() + +pattern = get_fill_pattern(value) +L = len(pattern) +if L not in (1, 2, 4): + raise ValueError(f"value must be 1, 2, or 4 bytes, got {L}") +if buffer_size % L != 0: + raise ValueError(f"buffer size ({buffer_size}) must be divisible by {L}") + +# Call appropriate cuMemsetD{8,16,32}Async based on L +``` + +## Examples + +```python +# Byte fill (1 byte) +buffer.fill(0, stream=stream) # Zero memory +buffer.fill(0xFF, stream=stream) # Fill with 0xFF + +# Multi-byte fill via numpy scalars +buffer.fill(np.uint16(0x1234), stream=stream) # 2-byte pattern +buffer.fill(np.float32(1.0), stream=stream) # 4-byte pattern + +# Raw bytes +buffer.fill(b'\xDE\xAD\xBE\xEF', stream=stream) # 4-byte pattern +``` + +## Changes from Current API + +| Current | Proposed | +|---------|----------| +| `fill(value, width, *, stream)` | `fill(value, *, stream)` | +| Explicit `width` parameter | Width inferred from value | +| Only accepts `int` | Accepts `int` or buffer-protocol objects |