wafer-cli 0.2.29__py3-none-any.whl → 0.2.31__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/baseline.py +661 -0
- wafer/cli.py +41 -321
- wafer/evaluate.py +81 -143
- wafer/templates/optimize_kernel.py +4 -2
- {wafer_cli-0.2.29.dist-info → wafer_cli-0.2.31.dist-info}/METADATA +1 -1
- {wafer_cli-0.2.29.dist-info → wafer_cli-0.2.31.dist-info}/RECORD +9 -8
- {wafer_cli-0.2.29.dist-info → wafer_cli-0.2.31.dist-info}/WHEEL +0 -0
- {wafer_cli-0.2.29.dist-info → wafer_cli-0.2.31.dist-info}/entry_points.txt +0 -0
- {wafer_cli-0.2.29.dist-info → wafer_cli-0.2.31.dist-info}/top_level.txt +0 -0
wafer/evaluate.py
CHANGED
|
@@ -78,9 +78,10 @@ def _build_docker_run_command(
|
|
|
78
78
|
for cap in cap_add:
|
|
79
79
|
parts.extend(["--cap-add", cap])
|
|
80
80
|
|
|
81
|
-
# GPU access - use
|
|
81
|
+
# GPU access - use --runtime=nvidia alongside --gpus for compatibility
|
|
82
|
+
# with newer NVIDIA drivers (580+) where --gpus alone may not initialize CUDA
|
|
82
83
|
if gpus:
|
|
83
|
-
parts.extend(["--gpus", f"'{gpus}'"])
|
|
84
|
+
parts.extend(["--runtime=nvidia", "--gpus", f"'{gpus}'"])
|
|
84
85
|
|
|
85
86
|
# Volume mounts
|
|
86
87
|
if volumes:
|
|
@@ -379,18 +380,6 @@ def _build_docker_pip_install_cmd(target: BaremetalTarget | VMTarget) -> str:
|
|
|
379
380
|
return " && ".join(commands)
|
|
380
381
|
|
|
381
382
|
|
|
382
|
-
def _get_wafer_root() -> Path:
|
|
383
|
-
"""Get wafer monorepo root directory.
|
|
384
|
-
|
|
385
|
-
Walks up from this file to find the wafer repo root (contains apps/, packages/).
|
|
386
|
-
"""
|
|
387
|
-
current = Path(__file__).resolve()
|
|
388
|
-
for parent in [current] + list(current.parents):
|
|
389
|
-
if (parent / "apps").is_dir() and (parent / "packages").is_dir():
|
|
390
|
-
return parent
|
|
391
|
-
raise RuntimeError(f"Could not find wafer root from {__file__}")
|
|
392
|
-
|
|
393
|
-
|
|
394
383
|
async def run_evaluate_docker(
|
|
395
384
|
args: EvaluateArgs,
|
|
396
385
|
target: BaremetalTarget | VMTarget,
|
|
@@ -2033,54 +2022,13 @@ async def run_evaluate_runpod(
|
|
|
2033
2022
|
error_message=f"Failed to setup Python environment: {e}",
|
|
2034
2023
|
)
|
|
2035
2024
|
|
|
2036
|
-
#
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
await client.exec(f"mkdir -p {wafer_core_remote}")
|
|
2044
|
-
wafer_core_workspace = await client.expand_path(wafer_core_remote)
|
|
2045
|
-
|
|
2046
|
-
upload_result = await client.upload_files(
|
|
2047
|
-
str(wafer_core_path), wafer_core_workspace, recursive=True
|
|
2048
|
-
)
|
|
2049
|
-
|
|
2050
|
-
# Wide event logging for upload result
|
|
2051
|
-
upload_event = {
|
|
2052
|
-
"event": "wafer_core_upload",
|
|
2053
|
-
"target": target.name,
|
|
2054
|
-
"target_type": "runpod",
|
|
2055
|
-
"ssh_host": f"{client.user}@{client.host}:{client.port}",
|
|
2056
|
-
"local_path": str(wafer_core_path),
|
|
2057
|
-
"remote_path": wafer_core_workspace,
|
|
2058
|
-
"success": upload_result.success,
|
|
2059
|
-
"files_copied": upload_result.files_copied,
|
|
2060
|
-
"duration_seconds": upload_result.duration_seconds,
|
|
2061
|
-
"error_message": upload_result.error_message,
|
|
2062
|
-
}
|
|
2063
|
-
if upload_result.debug_info:
|
|
2064
|
-
upload_event["debug_info"] = upload_result.debug_info
|
|
2065
|
-
logger.info(json.dumps(upload_event))
|
|
2066
|
-
|
|
2067
|
-
# Fail fast if upload failed
|
|
2068
|
-
if not upload_result.success:
|
|
2069
|
-
print(f"ERROR: Upload failed: {upload_result.error_message}")
|
|
2070
|
-
if upload_result.debug_info:
|
|
2071
|
-
print(f"Debug info: {json.dumps(upload_result.debug_info, indent=2)}")
|
|
2072
|
-
return EvaluateResult(
|
|
2073
|
-
success=False,
|
|
2074
|
-
all_correct=False,
|
|
2075
|
-
correctness_score=0.0,
|
|
2076
|
-
geomean_speedup=0.0,
|
|
2077
|
-
passed_tests=0,
|
|
2078
|
-
total_tests=0,
|
|
2079
|
-
error_message=f"Failed to upload wafer-core: {upload_result.error_message}",
|
|
2080
|
-
)
|
|
2081
|
-
|
|
2082
|
-
print(f"Uploaded {upload_result.files_copied} files")
|
|
2083
|
-
except Exception as e:
|
|
2025
|
+
# Install wafer-core in remote venv
|
|
2026
|
+
print("Installing wafer-core...")
|
|
2027
|
+
install_result = await client.exec(
|
|
2028
|
+
f'export PATH="$HOME/.local/bin:$HOME/.cargo/bin:$PATH" && '
|
|
2029
|
+
f"uv pip install --python {python_exe} wafer-core"
|
|
2030
|
+
)
|
|
2031
|
+
if install_result.exit_code != 0:
|
|
2084
2032
|
return EvaluateResult(
|
|
2085
2033
|
success=False,
|
|
2086
2034
|
all_correct=False,
|
|
@@ -2088,7 +2036,7 @@ async def run_evaluate_runpod(
|
|
|
2088
2036
|
geomean_speedup=0.0,
|
|
2089
2037
|
passed_tests=0,
|
|
2090
2038
|
total_tests=0,
|
|
2091
|
-
error_message=f"Failed to
|
|
2039
|
+
error_message=f"Failed to install wafer-core: {install_result.stderr}",
|
|
2092
2040
|
)
|
|
2093
2041
|
|
|
2094
2042
|
# Select GPU (RunPod pods typically have GPU 0)
|
|
@@ -2229,11 +2177,18 @@ async def run_evaluate_runpod(
|
|
|
2229
2177
|
error_message=f"Evaluation timed out after {target.eval_timeout}s",
|
|
2230
2178
|
)
|
|
2231
2179
|
|
|
2232
|
-
#
|
|
2180
|
+
# Show output to user
|
|
2233
2181
|
stdout = result.stdout
|
|
2234
2182
|
stderr = result.stderr
|
|
2183
|
+
if stdout:
|
|
2184
|
+
print(stdout)
|
|
2235
2185
|
|
|
2236
2186
|
if result.exit_code != 0:
|
|
2187
|
+
error_parts = [f"Evaluation failed (exit code {result.exit_code}):"]
|
|
2188
|
+
if stdout:
|
|
2189
|
+
error_parts.append(f"stdout: {stdout}")
|
|
2190
|
+
if stderr:
|
|
2191
|
+
error_parts.append(f"stderr: {stderr}")
|
|
2237
2192
|
return EvaluateResult(
|
|
2238
2193
|
success=False,
|
|
2239
2194
|
all_correct=False,
|
|
@@ -2241,20 +2196,27 @@ async def run_evaluate_runpod(
|
|
|
2241
2196
|
geomean_speedup=0.0,
|
|
2242
2197
|
passed_tests=0,
|
|
2243
2198
|
total_tests=0,
|
|
2244
|
-
error_message=
|
|
2199
|
+
error_message="\n".join(error_parts),
|
|
2245
2200
|
)
|
|
2246
2201
|
|
|
2247
|
-
#
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2202
|
+
# Read results from results.json file written by evaluate module
|
|
2203
|
+
results_path = f"{run_path}/results.json"
|
|
2204
|
+
cat_result = await client.exec(f"cat {results_path}")
|
|
2205
|
+
|
|
2206
|
+
if cat_result.exit_code != 0:
|
|
2207
|
+
return EvaluateResult(
|
|
2208
|
+
success=False,
|
|
2209
|
+
all_correct=False,
|
|
2210
|
+
correctness_score=0.0,
|
|
2211
|
+
geomean_speedup=0.0,
|
|
2212
|
+
passed_tests=0,
|
|
2213
|
+
total_tests=0,
|
|
2214
|
+
error_message=f"Failed to read results: {cat_result.stderr}",
|
|
2215
|
+
)
|
|
2216
|
+
|
|
2217
|
+
try:
|
|
2218
|
+
results_data = json.loads(cat_result.stdout)
|
|
2219
|
+
except json.JSONDecodeError as e:
|
|
2258
2220
|
return EvaluateResult(
|
|
2259
2221
|
success=False,
|
|
2260
2222
|
all_correct=False,
|
|
@@ -2262,10 +2224,12 @@ async def run_evaluate_runpod(
|
|
|
2262
2224
|
geomean_speedup=0.0,
|
|
2263
2225
|
passed_tests=0,
|
|
2264
2226
|
total_tests=0,
|
|
2265
|
-
error_message=f"
|
|
2227
|
+
error_message=f"Invalid JSON in results: {e}",
|
|
2266
2228
|
)
|
|
2267
2229
|
|
|
2268
|
-
|
|
2230
|
+
# Extract backend results (same format as DigitalOcean/SSH path)
|
|
2231
|
+
backends = results_data.get("backends", [])
|
|
2232
|
+
if not backends:
|
|
2269
2233
|
return EvaluateResult(
|
|
2270
2234
|
success=False,
|
|
2271
2235
|
all_correct=False,
|
|
@@ -2273,18 +2237,20 @@ async def run_evaluate_runpod(
|
|
|
2273
2237
|
geomean_speedup=0.0,
|
|
2274
2238
|
passed_tests=0,
|
|
2275
2239
|
total_tests=0,
|
|
2276
|
-
error_message=
|
|
2240
|
+
error_message="No backend results found",
|
|
2277
2241
|
)
|
|
2278
2242
|
|
|
2279
|
-
|
|
2280
|
-
|
|
2243
|
+
backend = backends[0]
|
|
2244
|
+
correctness_tests = backend.get("correctness_tests", [])
|
|
2245
|
+
passed = sum(1 for t in correctness_tests if t.get("is_correct", False))
|
|
2246
|
+
total = len(correctness_tests)
|
|
2281
2247
|
correctness = passed / total if total > 0 else 0.0
|
|
2282
2248
|
|
|
2283
2249
|
return EvaluateResult(
|
|
2284
2250
|
success=True,
|
|
2285
|
-
all_correct=
|
|
2251
|
+
all_correct=backend.get("all_correct", False),
|
|
2286
2252
|
correctness_score=correctness,
|
|
2287
|
-
geomean_speedup=
|
|
2253
|
+
geomean_speedup=backend.get("geomean_speedup", 0.0),
|
|
2288
2254
|
passed_tests=passed,
|
|
2289
2255
|
total_tests=total,
|
|
2290
2256
|
)
|
|
@@ -2385,61 +2351,13 @@ async def run_evaluate_digitalocean(
|
|
|
2385
2351
|
error_message=f"Failed to setup Python environment: {e}",
|
|
2386
2352
|
)
|
|
2387
2353
|
|
|
2388
|
-
#
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
await client.exec(f"mkdir -p {wafer_core_remote}")
|
|
2396
|
-
wafer_core_workspace = await client.expand_path(wafer_core_remote)
|
|
2397
|
-
|
|
2398
|
-
# Use SFTP instead of rsync to avoid SSH subprocess timeout issues
|
|
2399
|
-
# (DigitalOcean may rate-limit new SSH connections)
|
|
2400
|
-
upload_result = await client.upload_files(
|
|
2401
|
-
str(wafer_core_path),
|
|
2402
|
-
wafer_core_workspace,
|
|
2403
|
-
recursive=True,
|
|
2404
|
-
use_sftp=True,
|
|
2405
|
-
)
|
|
2406
|
-
|
|
2407
|
-
# Wide event logging for upload result
|
|
2408
|
-
upload_event = {
|
|
2409
|
-
"event": "wafer_core_upload",
|
|
2410
|
-
"target": target.name,
|
|
2411
|
-
"target_type": "digitalocean",
|
|
2412
|
-
"ssh_host": f"{client.user}@{client.host}:{client.port}",
|
|
2413
|
-
"local_path": str(wafer_core_path),
|
|
2414
|
-
"remote_path": wafer_core_workspace,
|
|
2415
|
-
"success": upload_result.success,
|
|
2416
|
-
"files_copied": upload_result.files_copied,
|
|
2417
|
-
"duration_seconds": upload_result.duration_seconds,
|
|
2418
|
-
"error_message": upload_result.error_message,
|
|
2419
|
-
}
|
|
2420
|
-
if upload_result.debug_info:
|
|
2421
|
-
upload_event["debug_info"] = upload_result.debug_info
|
|
2422
|
-
logger.info(json.dumps(upload_event))
|
|
2423
|
-
|
|
2424
|
-
# Fail fast if upload failed
|
|
2425
|
-
if not upload_result.success:
|
|
2426
|
-
print(f"ERROR: Upload failed: {upload_result.error_message}")
|
|
2427
|
-
if upload_result.debug_info:
|
|
2428
|
-
print(
|
|
2429
|
-
f"Debug info: {json.dumps(upload_result.debug_info, indent=2)}"
|
|
2430
|
-
)
|
|
2431
|
-
return EvaluateResult(
|
|
2432
|
-
success=False,
|
|
2433
|
-
all_correct=False,
|
|
2434
|
-
correctness_score=0.0,
|
|
2435
|
-
geomean_speedup=0.0,
|
|
2436
|
-
passed_tests=0,
|
|
2437
|
-
total_tests=0,
|
|
2438
|
-
error_message=f"Failed to upload wafer-core: {upload_result.error_message}",
|
|
2439
|
-
)
|
|
2440
|
-
|
|
2441
|
-
print(f"Uploaded {upload_result.files_copied} files")
|
|
2442
|
-
except Exception as e:
|
|
2354
|
+
# Install wafer-core in remote venv
|
|
2355
|
+
print("Installing wafer-core...")
|
|
2356
|
+
install_result = await client.exec(
|
|
2357
|
+
f'export PATH="$HOME/.local/bin:$HOME/.cargo/bin:$PATH" && '
|
|
2358
|
+
f"uv pip install --python {python_exe} wafer-core"
|
|
2359
|
+
)
|
|
2360
|
+
if install_result.exit_code != 0:
|
|
2443
2361
|
return EvaluateResult(
|
|
2444
2362
|
success=False,
|
|
2445
2363
|
all_correct=False,
|
|
@@ -2447,7 +2365,7 @@ async def run_evaluate_digitalocean(
|
|
|
2447
2365
|
geomean_speedup=0.0,
|
|
2448
2366
|
passed_tests=0,
|
|
2449
2367
|
total_tests=0,
|
|
2450
|
-
error_message=f"Failed to
|
|
2368
|
+
error_message=f"Failed to install wafer-core: {install_result.stderr}",
|
|
2451
2369
|
)
|
|
2452
2370
|
|
|
2453
2371
|
# Select GPU (DigitalOcean droplets typically have GPU 0)
|
|
@@ -3242,15 +3160,35 @@ def main():
|
|
|
3242
3160
|
inputs = [x.cuda() if isinstance(x, torch.Tensor) else x for x in inputs]
|
|
3243
3161
|
|
|
3244
3162
|
if run_defense and defense_module is not None:
|
|
3245
|
-
# Use
|
|
3163
|
+
# Use extended defense suite (Makora taxonomy + CUDA-L2)
|
|
3246
3164
|
print("[KernelBench] Running defense checks on implementation...")
|
|
3247
|
-
|
|
3165
|
+
run_extended = defense_module.run_all_defenses_extended
|
|
3248
3166
|
time_with_defenses = defense_module.time_execution_with_defenses
|
|
3249
3167
|
|
|
3250
|
-
#
|
|
3251
|
-
|
|
3168
|
+
# Read source code for LLM adversarial evaluator
|
|
3169
|
+
_problem_code = None
|
|
3170
|
+
_kernel_code = None
|
|
3171
|
+
try:
|
|
3172
|
+
_problem_code = Path(args.reference).read_text()
|
|
3173
|
+
_kernel_code = Path(args.impl).read_text()
|
|
3174
|
+
except Exception:
|
|
3175
|
+
pass
|
|
3176
|
+
|
|
3177
|
+
# Input generator for caching/multi-input checks
|
|
3178
|
+
def _input_generator():
|
|
3179
|
+
_ins = get_inputs()
|
|
3180
|
+
return tuple(x.cuda() if isinstance(x, torch.Tensor) else x for x in _ins)
|
|
3181
|
+
|
|
3182
|
+
# Run all defense checks (original + extended)
|
|
3183
|
+
all_passed, defense_results, _ = run_extended(
|
|
3252
3184
|
lambda *x: new_model(*x),
|
|
3253
3185
|
*inputs,
|
|
3186
|
+
reference_fn=lambda *x: ref_model(*x),
|
|
3187
|
+
input_generator=_input_generator,
|
|
3188
|
+
test_shapes=[(128, 128), (256, 256), (512, 512)],
|
|
3189
|
+
check_precision_ulp=True,
|
|
3190
|
+
problem_code=_problem_code,
|
|
3191
|
+
kernel_code=_kernel_code,
|
|
3254
3192
|
)
|
|
3255
3193
|
results["defense_results"] = {
|
|
3256
3194
|
name: {"passed": passed, "message": msg}
|
|
@@ -35,7 +35,8 @@ Strategy:
|
|
|
35
35
|
Commands:
|
|
36
36
|
- `wafer evaluate --impl <file> --reference <ref> --test-cases <tests>` - Run evaluation
|
|
37
37
|
- `wafer evaluate --impl <file> --reference <ref> --test-cases <tests> --profile` - With NCU profiling
|
|
38
|
-
- `wafer
|
|
38
|
+
- `wafer workspaces exec -- <command>` - Run arbitrary commands on remote GPU
|
|
39
|
+
- `wafer targets exec <target> -- <command>` - Run commands on a configured target via SSH
|
|
39
40
|
|
|
40
41
|
Output:
|
|
41
42
|
- Summary of optimizations applied
|
|
@@ -48,7 +49,8 @@ IMPORTANT: Always verify correctness with wafer evaluate before claiming success
|
|
|
48
49
|
tools=["read", "write", "edit", "glob", "grep", "bash"],
|
|
49
50
|
bash_allowlist=[
|
|
50
51
|
"wafer evaluate",
|
|
51
|
-
"wafer
|
|
52
|
+
"wafer workspaces exec",
|
|
53
|
+
"wafer targets exec",
|
|
52
54
|
"wafer nvidia ncu",
|
|
53
55
|
"wafer nvidia nsys",
|
|
54
56
|
"wafer nvidia perfetto",
|
|
@@ -5,12 +5,13 @@ wafer/analytics.py,sha256=qLY6Z16usVHFD8TCv7XBuz7l47vXVdXk-qhOzA-hW_8,8179
|
|
|
5
5
|
wafer/api_client.py,sha256=i_Az2b2llC3DSW8yOL-BKqa7LSKuxOr8hSN40s-oQXY,6313
|
|
6
6
|
wafer/auth.py,sha256=dwss_se5P-FFc9IN38q4kh_dBrA6k-CguDBkivgcdj0,14003
|
|
7
7
|
wafer/autotuner.py,sha256=41WYP41pTDvMijv2h42vm89bcHtDMJXObDlWmn6xpFU,44416
|
|
8
|
+
wafer/baseline.py,sha256=OrGCAut_xtkH9Ogx4mMU5-94Q0oClIXqac94YRwqERY,21534
|
|
8
9
|
wafer/billing.py,sha256=hEEwtrtIsbPQ3lLJNcyTLMsapUbcuvcVW_e9_0SxzVo,7199
|
|
9
|
-
wafer/cli.py,sha256=
|
|
10
|
+
wafer/cli.py,sha256=9wpLZlrKC3_DtkYuNWH42H1x9gJJOkJ32X2bNECG0rY,273013
|
|
10
11
|
wafer/cli_instructions.py,sha256=bziUKDNDAXABVMvKPLEMXm-hFSD2TcFSh-FKRYa949k,4693
|
|
11
12
|
wafer/config.py,sha256=h5Eo9_yfWqWGoPNdVQikI9GoZVUeysunSYiixf1mKcw,3411
|
|
12
13
|
wafer/corpus.py,sha256=CY9T7wXENNDJxnrtI-XsQmXeptrFfKG4x-lngrc9_3s,24748
|
|
13
|
-
wafer/evaluate.py,sha256=
|
|
14
|
+
wafer/evaluate.py,sha256=i15PliAVI3W04_4eju46PBDdh2BwSToLME5n7yGu7dU,187355
|
|
14
15
|
wafer/global_config.py,sha256=iu1HbTDr1695tSeDG2NfkK7PiY7XD6vjCk37w1wHbgk,11920
|
|
15
16
|
wafer/gpu_run.py,sha256=TwqXy72T7f2I7e6n5WWod3xgxCPnDhU0BgLsB4CUoQY,9716
|
|
16
17
|
wafer/inference.py,sha256=tZCO5i05FKY27ewis3CSBHFBeFbXY3xwj0DSjdoMY9s,4314
|
|
@@ -36,12 +37,12 @@ wafer/workspaces.py,sha256=J-TXGwHXSZlzRWCew63KNvk6HLJ-zTSELRgzjryTkMk,35710
|
|
|
36
37
|
wafer/skills/wafer-guide/SKILL.md,sha256=UDsXCD5Kb-lDParKCTf2WkE3kodVs-rja8XeumSBO5U,3934
|
|
37
38
|
wafer/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
39
|
wafer/templates/ask_docs.py,sha256=15t1Aa4WBMwMox8XmFdzyosOZfBLMdXyaxo3GDb7nTE,2254
|
|
39
|
-
wafer/templates/optimize_kernel.py,sha256=
|
|
40
|
+
wafer/templates/optimize_kernel.py,sha256=Q4FA_8ECEegW_3DS51mkLCX6Vk1dcWWzY3A_RQ4NW8U,2576
|
|
40
41
|
wafer/templates/optimize_kernelbench.py,sha256=T3co9Y9eSLWDrZG66gwQVFMdnGVoyUQos-TxnMMBLL8,3747
|
|
41
42
|
wafer/templates/trace_analyze.py,sha256=B7CiRlsokERzBjLL-k49kGjpU2zlJZqzTE05xbRS1WI,2878
|
|
42
43
|
wafer/tests/test_eval_cli_parity.py,sha256=SGmaj2NGBZ7GdDF53bXsECvQbV21iHZw8YeL_MJOLk0,7206
|
|
43
|
-
wafer_cli-0.2.
|
|
44
|
-
wafer_cli-0.2.
|
|
45
|
-
wafer_cli-0.2.
|
|
46
|
-
wafer_cli-0.2.
|
|
47
|
-
wafer_cli-0.2.
|
|
44
|
+
wafer_cli-0.2.31.dist-info/METADATA,sha256=rrIOyDKT02oelCRNJTTdlCvidNgVXmNSlE2vXmRsa-U,2799
|
|
45
|
+
wafer_cli-0.2.31.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
46
|
+
wafer_cli-0.2.31.dist-info/entry_points.txt,sha256=WqB7hB__WhtPY8y1cO2sZiUz7fCq6Ik-usAigpeFvWE,41
|
|
47
|
+
wafer_cli-0.2.31.dist-info/top_level.txt,sha256=2MK1IVMWfpLL8BZCQ3E9aG6L6L666gSA_teYlwan4fs,6
|
|
48
|
+
wafer_cli-0.2.31.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|