wafer-cli 0.2.1__py3-none-any.whl → 0.2.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wafer/GUIDE.md +57 -263
- wafer/analytics.py +307 -0
- wafer/auth.py +4 -2
- wafer/billing.py +233 -0
- wafer/cli.py +765 -49
- wafer/global_config.py +14 -3
- wafer/skills/wafer-guide/SKILL.md +116 -0
- wafer/wevin_cli.py +1 -0
- wafer/workspaces.py +7 -0
- {wafer_cli-0.2.1.dist-info → wafer_cli-0.2.3.dist-info}/METADATA +2 -1
- {wafer_cli-0.2.1.dist-info → wafer_cli-0.2.3.dist-info}/RECORD +14 -11
- {wafer_cli-0.2.1.dist-info → wafer_cli-0.2.3.dist-info}/WHEEL +0 -0
- {wafer_cli-0.2.1.dist-info → wafer_cli-0.2.3.dist-info}/entry_points.txt +0 -0
- {wafer_cli-0.2.1.dist-info → wafer_cli-0.2.3.dist-info}/top_level.txt +0 -0
wafer/global_config.py
CHANGED
|
@@ -67,9 +67,12 @@ class Preferences:
|
|
|
67
67
|
|
|
68
68
|
mode: "implicit" (default) = quiet output, use -v for status messages
|
|
69
69
|
"explicit" = verbose output, shows [wafer] status messages
|
|
70
|
+
analytics_enabled: True (default) = send anonymous usage analytics to PostHog
|
|
71
|
+
False = disable all analytics tracking
|
|
70
72
|
"""
|
|
71
73
|
|
|
72
74
|
mode: Literal["explicit", "implicit"] = "implicit"
|
|
75
|
+
analytics_enabled: bool = True
|
|
73
76
|
|
|
74
77
|
|
|
75
78
|
@dataclass(frozen=True)
|
|
@@ -148,7 +151,9 @@ def _parse_config_file(path: Path) -> GlobalConfig:
|
|
|
148
151
|
pref_data = data.get("preferences", {})
|
|
149
152
|
mode = pref_data.get("mode", "explicit")
|
|
150
153
|
assert mode in ("explicit", "implicit"), f"mode must be 'explicit' or 'implicit', got '{mode}'"
|
|
151
|
-
|
|
154
|
+
analytics_enabled = pref_data.get("analytics_enabled", True)
|
|
155
|
+
assert isinstance(analytics_enabled, bool), f"analytics_enabled must be true or false, got '{analytics_enabled}'"
|
|
156
|
+
preferences = Preferences(mode=mode, analytics_enabled=analytics_enabled)
|
|
152
157
|
|
|
153
158
|
# Parse defaults
|
|
154
159
|
defaults_data = data.get("defaults", {})
|
|
@@ -301,10 +306,16 @@ def save_global_config(config: GlobalConfig) -> None:
|
|
|
301
306
|
lines.append(f"{key} = {value}")
|
|
302
307
|
lines.append("")
|
|
303
308
|
|
|
304
|
-
# Preferences section (only if non-default)
|
|
309
|
+
# Preferences section (only if non-default values)
|
|
310
|
+
pref_lines = []
|
|
305
311
|
if config.preferences.mode != "implicit":
|
|
312
|
+
pref_lines.append(f'mode = "{config.preferences.mode}"')
|
|
313
|
+
if not config.preferences.analytics_enabled:
|
|
314
|
+
pref_lines.append("analytics_enabled = false")
|
|
315
|
+
|
|
316
|
+
if pref_lines:
|
|
306
317
|
lines.append("[preferences]")
|
|
307
|
-
lines.
|
|
318
|
+
lines.extend(pref_lines)
|
|
308
319
|
lines.append("")
|
|
309
320
|
|
|
310
321
|
# Defaults section (only if non-default values)
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wafer-guide
|
|
3
|
+
description: GPU kernel development with the Wafer CLI. Use when working on CUDA/HIP kernels, profiling GPU code, or optimizing kernel performance.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Wafer CLI
|
|
7
|
+
|
|
8
|
+
GPU development primitives for optimizing CUDA and HIP kernels.
|
|
9
|
+
|
|
10
|
+
## When to Use This Skill
|
|
11
|
+
|
|
12
|
+
Activate this skill when:
|
|
13
|
+
- Writing or optimizing CUDA/HIP kernels
|
|
14
|
+
- Profiling GPU code with NCU, NSYS, or ROCprof
|
|
15
|
+
- Evaluating kernel correctness and performance
|
|
16
|
+
- Looking up GPU programming documentation (CUDA, CUTLASS, HIP)
|
|
17
|
+
|
|
18
|
+
## Core Workflows
|
|
19
|
+
|
|
20
|
+
### 1. Documentation Lookup
|
|
21
|
+
|
|
22
|
+
Query indexed GPU documentation:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Download corpus (one-time)
|
|
26
|
+
wafer corpus download cuda
|
|
27
|
+
wafer corpus download cutlass
|
|
28
|
+
wafer corpus download hip
|
|
29
|
+
|
|
30
|
+
# Query documentation
|
|
31
|
+
wafer wevin -t ask-docs --corpus cuda "What is warp divergence?"
|
|
32
|
+
wafer wevin -t ask-docs --corpus cutlass "What is a TiledMma?"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 2. Trace Analysis
|
|
36
|
+
|
|
37
|
+
Analyze NCU, NSYS, or PyTorch profiler traces:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# AI-assisted analysis
|
|
41
|
+
wafer wevin -t trace-analyze --args trace=./profile.ncu-rep "Why is this kernel slow?"
|
|
42
|
+
|
|
43
|
+
# Direct trace queries (PyTorch/Perfetto JSON)
|
|
44
|
+
wafer nvidia perfetto query trace.json \
|
|
45
|
+
"SELECT name, dur/1e6 as ms FROM slice WHERE cat='kernel' ORDER BY dur DESC LIMIT 10"
|
|
46
|
+
|
|
47
|
+
# NCU/NSYS analysis
|
|
48
|
+
wafer nvidia ncu analyze profile.ncu-rep
|
|
49
|
+
wafer nvidia nsys analyze profile.nsys-rep
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 3. Kernel Evaluation
|
|
53
|
+
|
|
54
|
+
Test correctness and measure speedup against a reference:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Generate template files
|
|
58
|
+
wafer evaluate make-template ./my-kernel
|
|
59
|
+
# Creates: kernel.py, reference.py, test_cases.json
|
|
60
|
+
|
|
61
|
+
# Run evaluation on a configured target
|
|
62
|
+
wafer evaluate \
|
|
63
|
+
--impl ./my-kernel/kernel.py \
|
|
64
|
+
--reference ./my-kernel/reference.py \
|
|
65
|
+
--test-cases ./my-kernel/test_cases.json \
|
|
66
|
+
--target <target-name>
|
|
67
|
+
|
|
68
|
+
# With profiling
|
|
69
|
+
wafer evaluate ... --profile
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 4. AI-Assisted Optimization
|
|
73
|
+
|
|
74
|
+
Iteratively optimize a kernel with evaluation feedback:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
wafer wevin -t optimize-kernel \
|
|
78
|
+
--args kernel=./my_kernel.cu \
|
|
79
|
+
--args target=H100 \
|
|
80
|
+
"Optimize this GEMM for memory bandwidth"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 5. Remote Execution
|
|
84
|
+
|
|
85
|
+
Run on cloud GPU workspaces:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
wafer workspaces list
|
|
89
|
+
wafer workspaces create my-workspace --gpu H100
|
|
90
|
+
wafer workspaces exec <id> "python train.py"
|
|
91
|
+
wafer workspaces ssh <id>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Command Reference
|
|
95
|
+
|
|
96
|
+
| Command | Description |
|
|
97
|
+
|---------|-------------|
|
|
98
|
+
| `wafer corpus list\|download\|path` | Manage documentation corpora |
|
|
99
|
+
| `wafer evaluate` | Test kernel correctness/performance |
|
|
100
|
+
| `wafer nvidia ncu\|nsys\|perfetto` | NVIDIA profiling tools |
|
|
101
|
+
| `wafer amd isa\|rocprof-compute` | AMD profiling tools |
|
|
102
|
+
| `wafer workspaces` | Cloud GPU environments |
|
|
103
|
+
| `wafer wevin -t <template>` | AI-assisted workflows |
|
|
104
|
+
| `wafer config targets` | Configure GPU targets |
|
|
105
|
+
|
|
106
|
+
## Target Configuration
|
|
107
|
+
|
|
108
|
+
Targets define GPU access methods. Initialize with:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
wafer config targets init ssh # Your own GPU via SSH
|
|
112
|
+
wafer config targets init runpod # RunPod cloud GPUs
|
|
113
|
+
wafer config targets init digitalocean # DigitalOcean AMD GPUs
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Then use: `wafer evaluate --target <name> ...`
|
wafer/wevin_cli.py
CHANGED
wafer/workspaces.py
CHANGED
|
@@ -49,6 +49,13 @@ def _friendly_error(status_code: int, response_text: str, workspace_id: str) ->
|
|
|
49
49
|
if status_code == 401:
|
|
50
50
|
return "Not authenticated. Run: wafer login"
|
|
51
51
|
|
|
52
|
+
if status_code == 402:
|
|
53
|
+
return (
|
|
54
|
+
"Insufficient credits.\n"
|
|
55
|
+
" Check usage: wafer billing\n"
|
|
56
|
+
" Add credits: wafer billing topup"
|
|
57
|
+
)
|
|
58
|
+
|
|
52
59
|
if status_code == 404:
|
|
53
60
|
return (
|
|
54
61
|
f"Workspace '{workspace_id}' not found.\n"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wafer-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: CLI tool for running commands on remote GPUs and GPU kernel optimization agent
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Requires-Dist: typer>=0.12.0
|
|
@@ -8,6 +8,7 @@ Requires-Dist: trio>=0.24.0
|
|
|
8
8
|
Requires-Dist: trio-asyncio>=0.15.0
|
|
9
9
|
Requires-Dist: wafer-core>=0.1.0
|
|
10
10
|
Requires-Dist: perfetto>=0.16.0
|
|
11
|
+
Requires-Dist: posthog>=3.0.0
|
|
11
12
|
Provides-Extra: dev
|
|
12
13
|
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
13
14
|
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
wafer/GUIDE.md,sha256=
|
|
1
|
+
wafer/GUIDE.md,sha256=Z_jsSgHAS6bFa83VKhG9jxjUK1XpLjR1fEIKapDa_6g,3195
|
|
2
2
|
wafer/__init__.py,sha256=kBM_ONCpU6UUMBOH8Tmg4A88sNFnbaD59o61cJs-uYM,90
|
|
3
|
+
wafer/analytics.py,sha256=Xxw3bbY3XLgedSJPwzIOBJIjyycIiornWCpjoWbTKYU,8190
|
|
3
4
|
wafer/api_client.py,sha256=cPULiTxqOAYYSfDTNJgd-6Pqrt3IM4Gm9903U7yGIwY,6163
|
|
4
|
-
wafer/auth.py,sha256=
|
|
5
|
+
wafer/auth.py,sha256=ZLsXZ73GDLD8GL7Rij1ELtuLqyJ5EU_uPBUMPVKwExA,10703
|
|
5
6
|
wafer/autotuner.py,sha256=6gH0Ho7T58EFerMQcHQxshWe3DF4qU7fb5xthAh5SPM,44364
|
|
6
|
-
wafer/
|
|
7
|
+
wafer/billing.py,sha256=jbLB2lI4_9f2KD8uEFDi_ixLlowe5hasC0TIZJyIXRg,7163
|
|
8
|
+
wafer/cli.py,sha256=kscK-JBiAu0H7roMdcaZ_lT7xlgR6mUJ1nBruidUdsE,184745
|
|
7
9
|
wafer/config.py,sha256=h5Eo9_yfWqWGoPNdVQikI9GoZVUeysunSYiixf1mKcw,3411
|
|
8
10
|
wafer/corpus.py,sha256=yTF3UA5bOa8BII2fmcXf-3WsIsM5DX4etysv0AzVknE,8912
|
|
9
11
|
wafer/evaluate.py,sha256=7E1BqVl0um7kfU2_4FkXZrNc-PQJIHe09G1-L07PXmg,114971
|
|
10
|
-
wafer/global_config.py,sha256=
|
|
12
|
+
wafer/global_config.py,sha256=fhaR_RU3ufMksDmOohH1OLeQ0JT0SDW1hEip_zaP75k,11345
|
|
11
13
|
wafer/gpu_run.py,sha256=gUbzMsMPsw3UHcn00bI-zTSHrU8c2FEpDvbcsczlDPo,9557
|
|
12
14
|
wafer/inference.py,sha256=tZCO5i05FKY27ewis3CSBHFBeFbXY3xwj0DSjdoMY9s,4314
|
|
13
15
|
wafer/ncu_analyze.py,sha256=rAWzKQRZEY6E_CL3gAWUaW3uZ4kvQVZskVCPDpsFJuE,24633
|
|
@@ -17,14 +19,15 @@ wafer/rocprof_sdk.py,sha256=fAYCxpfJa5BZTTkIMBOXg4KsYK4i_wNOKrJJn1ZfypM,10086
|
|
|
17
19
|
wafer/rocprof_systems.py,sha256=4IWbMcbYk1x_8iS7P3FC_u5sgH6EXADCtR2lV9id80M,18629
|
|
18
20
|
wafer/targets.py,sha256=WE5TJgFPGtEIh7VaTQHZ4wB2t4kW0c5K8-UmQ_39Ock,10254
|
|
19
21
|
wafer/tracelens.py,sha256=g9ZIeFyNojZn4uTd3skPqIrRiL7aMJOz_-GOd3aiyy4,7998
|
|
20
|
-
wafer/wevin_cli.py,sha256=
|
|
21
|
-
wafer/workspaces.py,sha256=
|
|
22
|
+
wafer/wevin_cli.py,sha256=tuvHM_wsJ0qo4uUV8rj93vNBL7UgDIMY6f3YXCPf4lg,15821
|
|
23
|
+
wafer/workspaces.py,sha256=92LG1mtkzNz-ap3XzcqY6KnQ9SUCFG8VBIOUj1Who64,25757
|
|
24
|
+
wafer/skills/wafer-guide/SKILL.md,sha256=UfBeIe5GKFzOYcbPmcs8U2nrjbfr-jSMRwg0jQDBfb0,3058
|
|
22
25
|
wafer/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
26
|
wafer/templates/ask_docs.py,sha256=Lxs-faz9v5m4Qa4NjF2X_lE8KwM9ES9MNJkxo7ep56o,2256
|
|
24
27
|
wafer/templates/optimize_kernel.py,sha256=u6AL7Q3uttqlnBLzcoFdsiPq5lV2TV3bgqwCYYlK9gk,2357
|
|
25
28
|
wafer/templates/trace_analyze.py,sha256=XE1VqzVkIUsZbXF8EzQdDYgg-AZEYAOFpr6B_vnRELc,2880
|
|
26
|
-
wafer_cli-0.2.
|
|
27
|
-
wafer_cli-0.2.
|
|
28
|
-
wafer_cli-0.2.
|
|
29
|
-
wafer_cli-0.2.
|
|
30
|
-
wafer_cli-0.2.
|
|
29
|
+
wafer_cli-0.2.3.dist-info/METADATA,sha256=MKzRmMwc1zhKUVeu_NE4h5_17EFnX1bjLE4Jcox0AAk,559
|
|
30
|
+
wafer_cli-0.2.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
31
|
+
wafer_cli-0.2.3.dist-info/entry_points.txt,sha256=WqB7hB__WhtPY8y1cO2sZiUz7fCq6Ik-usAigpeFvWE,41
|
|
32
|
+
wafer_cli-0.2.3.dist-info/top_level.txt,sha256=2MK1IVMWfpLL8BZCQ3E9aG6L6L666gSA_teYlwan4fs,6
|
|
33
|
+
wafer_cli-0.2.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|