Skip to content

Commit 279f90c

Browse files
committed
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
1 parent 2facdb6 commit 279f90c

1 file changed

Lines changed: 77 additions & 0 deletions

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Buffer.fill() Redesign Proposal
2+
3+
**Issue**: [#1345 - Revisit `Buffer.fill()`](https://github.com/NVIDIA/cuda-python/issues/1345)
4+
**Author**: Andy Jost
5+
**Date**: December 10, 2025
6+
7+
## Background
8+
9+
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.
10+
11+
## Proposed API
12+
13+
```python
14+
def fill(self, value, *, stream: Stream | GraphBuilder):
15+
"""Fill buffer with a repeating byte pattern.
16+
17+
Parameters
18+
----------
19+
value : int or buffer-protocol object
20+
- int: Must be in range [0, 256). Converted to 1 byte.
21+
- buffer-protocol object: Must be 1, 2, or 4 bytes.
22+
stream : Stream | GraphBuilder
23+
Stream for the asynchronous fill operation.
24+
25+
Raises
26+
------
27+
TypeError
28+
If value is not an int and does not support the buffer protocol.
29+
ValueError
30+
If value byte length is not 1, 2, or 4.
31+
If buffer size is not divisible by value byte length.
32+
OverflowError
33+
If int value is outside [0, 256).
34+
"""
35+
```
36+
37+
## Implementation
38+
39+
```python
40+
def get_fill_pattern(value):
41+
if isinstance(value, int):
42+
return value.to_bytes(1, 'little') # Raises OverflowError if not in [0, 256)
43+
mv = memoryview(value)
44+
return mv.tobytes()
45+
46+
pattern = get_fill_pattern(value)
47+
L = len(pattern)
48+
if L not in (1, 2, 4):
49+
raise ValueError(f"value must be 1, 2, or 4 bytes, got {L}")
50+
if buffer_size % L != 0:
51+
raise ValueError(f"buffer size ({buffer_size}) must be divisible by {L}")
52+
53+
# Call appropriate cuMemsetD{8,16,32}Async based on L
54+
```
55+
56+
## Examples
57+
58+
```python
59+
# Byte fill (1 byte)
60+
buffer.fill(0, stream=stream) # Zero memory
61+
buffer.fill(0xFF, stream=stream) # Fill with 0xFF
62+
63+
# Multi-byte fill via numpy scalars
64+
buffer.fill(np.uint16(0x1234), stream=stream) # 2-byte pattern
65+
buffer.fill(np.float32(1.0), stream=stream) # 4-byte pattern
66+
67+
# Raw bytes
68+
buffer.fill(b'\xDE\xAD\xBE\xEF', stream=stream) # 4-byte pattern
69+
```
70+
71+
## Changes from Current API
72+
73+
| Current | Proposed |
74+
|---------|----------|
75+
| `fill(value, width, *, stream)` | `fill(value, *, stream)` |
76+
| Explicit `width` parameter | Width inferred from value |
77+
| Only accepts `int` | Accepts `int` or buffer-protocol objects |

0 commit comments

Comments
 (0)