Skip to content

Commit 084e891

Browse files
authored
Merge pull request #2753 from lvyufeng/mtv2-cuda-backend-mvp
feat(mindtorch_v2): add CUDA backend MVP with explicit dispatch keys
2 parents ec2520e + 6dc8cfd commit 084e891

25 files changed

Lines changed: 1429 additions & 41 deletions
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
# MindTorch v2 CUDA Backend MVP Design
2+
3+
**Status:** Approved
4+
5+
**Goal:** Turn `mindtorch_v2` CUDA from a reserved device label into a real backend with working device APIs, storage, transfer, and tensor creation—without depending on any other framework.
6+
7+
**Scope:** This design covers the first usable CUDA backend milestone only. It does not attempt broad operator parity, full autograd parity, AMP, profiler support, or distributed support.
8+
9+
---
10+
11+
## Problem
12+
13+
`mindtorch_v2` already reserves a CUDA path in dispatch and device handling, but CUDA is not a real backend today:
14+
15+
- Dispatch registration maps `cuda` to placeholder keys in `src/mindtorch_v2/_dispatch/registration.py`.
16+
- Dispatch key construction recognizes CUDA tensors in `src/mindtorch_v2/_dispatch/keys.py`.
17+
- Tensor APIs still treat `.cuda()` as unsupported in current tests.
18+
19+
This means the mechanism is partially prepared, but there is no CUDA runtime layer, storage layer, or creation/transfer implementation behind it.
20+
21+
---
22+
23+
## Constraints
24+
25+
- Pure Python implementation.
26+
- No dependency on external deep learning frameworks.
27+
- Respect `mindtorch_v2` schema-first registration rules.
28+
- Keep the first phase small and mechanism-focused.
29+
- Use CUDA runtime primitives directly via Python FFI.
30+
31+
---
32+
33+
## Non-Goals
34+
35+
This MVP does not include:
36+
37+
- Broad math operator coverage.
38+
- Full Torch CUDA semantic parity.
39+
- Full autograd on CUDA.
40+
- AMP/autocast/GradScaler support.
41+
- CUDA profiler support.
42+
- NCCL/distributed support.
43+
44+
Those will become follow-on phases once backend fundamentals are stable.
45+
46+
---
47+
48+
## Recommended Approach
49+
50+
Use a layered CUDA backend built directly on `ctypes` bindings to `libcudart.so`.
51+
52+
The first phase should only establish:
53+
54+
1. CUDA runtime discovery and device management.
55+
2. GPU memory allocation/free and memory copy.
56+
3. A dedicated `CudaStorage` implementation.
57+
4. Tensor movement between CPU and CUDA.
58+
5. CUDA creation ops: `empty`, `zeros`, `ones`, `full`, `tensor`, `to`.
59+
60+
This is the smallest design that turns CUDA into a real device in the system.
61+
62+
---
63+
64+
## Architecture
65+
66+
### 1. Runtime Layer
67+
68+
Add `src/mindtorch_v2/_backends/cuda/runtime.py`.
69+
70+
Responsibilities:
71+
72+
- Load `libcudart.so` lazily.
73+
- Expose Python wrappers for:
74+
- `cudaGetDeviceCount`
75+
- `cudaGetDevice`
76+
- `cudaSetDevice`
77+
- `cudaMalloc`
78+
- `cudaFree`
79+
- `cudaMemcpy`
80+
- `cudaMemcpyAsync`
81+
- `cudaMemset`
82+
- `cudaDeviceSynchronize`
83+
- `cudaStreamCreate`
84+
- `cudaStreamDestroy`
85+
- `cudaStreamSynchronize`
86+
- `cudaEventCreate`
87+
- `cudaEventDestroy`
88+
- `cudaEventRecord`
89+
- `cudaEventSynchronize`
90+
- Raise clear Python exceptions from CUDA error codes.
91+
92+
This layer is intentionally small and should not include operator logic.
93+
94+
### 2. Storage Layer
95+
96+
Add `src/mindtorch_v2/_backends/cuda/storage.py`.
97+
98+
Responsibilities:
99+
100+
- Represent device-backed raw storage.
101+
- Own a CUDA pointer and its lifetime.
102+
- Track `nbytes`, `dtype`, and `device`.
103+
- Support conversion helpers for host/device copies.
104+
- Provide enough storage API compatibility for `Tensor` to work.
105+
106+
The initial storage type can remain simple: contiguous allocation only, no custom allocator, no pooling, no IPC.
107+
108+
### 3. Storage Factory Integration
109+
110+
Extend `src/mindtorch_v2/_storage.py`.
111+
112+
Responsibilities:
113+
114+
- Add CUDA storage factory helpers.
115+
- Support CPU numpy -> CUDA upload.
116+
- Support CUDA -> CPU download.
117+
- Route typed storage creation by device type.
118+
119+
This is the bridge between existing CPU/meta flows and the new CUDA flow.
120+
121+
### 4. Public CUDA API
122+
123+
Add `src/mindtorch_v2/cuda.py`.
124+
125+
Responsibilities:
126+
127+
- Mirror the shape of `src/mindtorch_v2/npu.py` where practical.
128+
- Expose:
129+
- `is_available`
130+
- `device_count`
131+
- `current_device`
132+
- `set_device`
133+
- `synchronize`
134+
- `Stream`
135+
- `Event`
136+
- `device` context manager
137+
138+
This gives users a stable entry point for CUDA backend discovery and control.
139+
140+
### 5. Tensor Transfer and Creation
141+
142+
Update:
143+
144+
- `src/mindtorch_v2/_tensor.py`
145+
- `src/mindtorch_v2/_creation.py`
146+
- `src/mindtorch_v2/_backends/cuda/creation.py`
147+
148+
Responsibilities:
149+
150+
- Make `Tensor.cuda()` call into `to("cuda")`.
151+
- Make `Tensor.to("cuda")` and `Tensor.to("cpu")` perform actual device transfer.
152+
- Support direct creation on CUDA for `tensor`, `empty`, `zeros`, `ones`, `full`.
153+
154+
For `ones` and `full`, the first version may use a temporary host buffer plus upload if that is simpler than adding a fill kernel immediately.
155+
156+
---
157+
158+
## Dispatch Strategy
159+
160+
Do not redesign dispatch in this phase.
161+
162+
Make CUDA a first-class dispatch backend in this PR.
163+
164+
Required dispatch changes:
165+
166+
- add `DispatchKey.CUDA`
167+
- add `DispatchKey.AutogradCUDA`
168+
- update dispatch priority and keyset construction
169+
- update registration helpers so `cuda` no longer maps to `PrivateUse1`
170+
- keep `PrivateUse1` reserved for actual private-use backends
171+
172+
This aligns the implementation with the requirement that CUDA must not be represented as `PrivateUse1`.
173+
174+
---
175+
176+
## Testing Strategy
177+
178+
Follow the repo rule: schema first, then contract tests, then backend wiring.
179+
180+
### Required mechanism tests
181+
182+
- `PYTHONPATH=src pytest -q tests/mindtorch_v2/contract/test_schema_registration_order.py`
183+
- `PYTHONPATH=src pytest -q tests/mindtorch_v2/contract/test_schema_coverage.py`
184+
185+
### New CUDA MVP tests
186+
187+
Add or update tests for:
188+
189+
- `torch.cuda.is_available()` style availability surface.
190+
- `mt.tensor(..., device="cuda")` creation.
191+
- `x.cuda()` success.
192+
- `x.to("cuda")` and `x.to("cpu")` round-trip correctness.
193+
- `zeros/ones/full/empty(..., device="cuda")` creation.
194+
- `current_device` / `set_device` behavior.
195+
196+
Tests should gracefully skip when CUDA runtime is unavailable.
197+
198+
---
199+
200+
## Risks
201+
202+
### Runtime loading risk
203+
204+
CUDA library names can differ across systems. The runtime layer should attempt a small set of common library names and fail gracefully.
205+
206+
### Lifetime management risk
207+
208+
Leaking device memory is easy when Python owns raw pointers. `CudaStorage` should centralize ownership and cleanup.
209+
210+
### Shape/stride risk
211+
212+
This MVP should avoid pretending to support advanced non-contiguous CUDA storage semantics before they are actually implemented.
213+
214+
### Scope creep risk
215+
216+
Do not add math kernels in this phase unless they are strictly required to support creation/transfer semantics.
217+
218+
---
219+
220+
## Success Criteria
221+
222+
The MVP is complete when all of the following are true:
223+
224+
- `mindtorch_v2` exposes a working `cuda` module.
225+
- CUDA availability can be queried without crashing on non-CUDA systems.
226+
- Tensors can be created on CUDA.
227+
- CPU <-> CUDA transfer works for supported dtypes.
228+
- `.cuda()` no longer fails as an unsupported reserved path.
229+
- CUDA backend changes respect schema-first and pass the required contract tests.
230+
231+
---
232+
233+
## Follow-On Phases
234+
235+
After this MVP, the next recommended phases are:
236+
237+
1. Pointwise math ops.
238+
2. Reductions.
239+
3. `matmul` and BLAS-backed operations.
240+
4. Convolution/pooling via cuDNN.
241+
5. Autograd correctness.
242+
6. AMP, profiler, and distributed support.
243+

0 commit comments

Comments
 (0)