Skip to content

Commit ba643ce

Browse files
KenJones-Modularmodularbot
authored andcommitted
[puzzles] Fix the uv install path and the sanitizer harness import
Installing the GPU Puzzles with uv works again, and puzzles that use the out-of-bounds canary now run through the uv tasks and the compute-sanitizer tasks instead of failing at import. MODULAR_ORIG_COMMIT_REV_ID: d0e05670772bf8805629df62c719f30991e3e9d6
1 parent f80ad6b commit ba643ce

4 files changed

Lines changed: 73 additions & 45 deletions

File tree

‎.gitignore‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,7 @@ solutions/p16/p16_optimized
4747
*.ncu-rep
4848
*.qdrep
4949
*.sqlite
50-
*.txt
50+
# Profiler reports redirected to text, where `clean-profiles` looks for them.
51+
/*.txt
52+
/problems/**/*.txt
5153
**/p*/p*_profiler

‎pyproject.toml‎

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[build-system]
2-
requires = ["setuptools>=84.0.0"]
2+
requires = ["setuptools>=61"]
33
build-backend = "setuptools.build_meta"
44

55
[project]
@@ -10,12 +10,12 @@ requires-python = ">=3.10,<3.13"
1010
dependencies = [
1111
# Pinned to the release the book targets. Bump both with the release-branch
1212
# channel edit in `pixi.toml`; they must not drift apart again.
13-
"mojo==1.0.0",
14-
"max==26.5.0",
13+
"mojo==1.1.0",
14+
"max==26.6.0",
1515
"poethepoet>=0.34.0",
1616
"scipy>=1.15.3",
1717
# Matches the version `pixi.toml` pins and the suite is tested against.
18-
"torch==2.14.0",
18+
"torch==2.7.1",
1919
]
2020

2121
[project.optional-dependencies]
@@ -52,39 +52,39 @@ pytorch-triton-rocm = [
5252
[tool.poe.tasks]
5353
tests = "bash solutions/run.sh"
5454

55-
p01 = "mojo problems/p01/p01.mojo"
55+
p01 = "mojo -I . problems/p01/p01.mojo"
5656

57-
p02 = "mojo problems/p02/p02.mojo"
57+
p02 = "mojo -I . problems/p02/p02.mojo"
5858

59-
p03 = "mojo problems/p03/p03.mojo"
59+
p03 = "mojo -I . problems/p03/p03.mojo"
6060

61-
p04 = "mojo problems/p04/p04.mojo"
62-
p04_tile_tensor = "mojo problems/p04/p04_tile_tensor.mojo"
61+
p04 = "mojo -I . problems/p04/p04.mojo"
62+
p04_tile_tensor = "mojo -I . problems/p04/p04_tile_tensor.mojo"
6363
tile_tensor_intro = "mojo book/src/puzzle_04/intro.mojo"
6464

65-
p05 = "mojo problems/p05/p05.mojo"
65+
p05 = "mojo -I . problems/p05/p05.mojo"
6666

67-
p06 = "mojo problems/p06/p06.mojo"
67+
p06 = "mojo -I . problems/p06/p06.mojo"
6868

69-
p07 = "mojo problems/p07/p07.mojo"
69+
p07 = "mojo -I . problems/p07/p07.mojo"
7070

71-
p08 = "mojo problems/p08/p08.mojo"
71+
p08 = "mojo -I . problems/p08/p08.mojo"
7272

7373
p09 = "mojo problems/p09/p09.mojo"
7474

7575
p10 = "mojo problems/p10/p10.mojo"
7676

77-
p11 = "mojo problems/p11/p11.mojo"
77+
p11 = "mojo -I . problems/p11/p11.mojo"
7878

79-
p12 = "mojo problems/p12/p12.mojo"
79+
p12 = "mojo -I . problems/p12/p12.mojo"
8080

81-
p13 = "mojo problems/p13/p13.mojo"
81+
p13 = "mojo -I . problems/p13/p13.mojo"
8282

83-
p14 = "mojo problems/p14/p14.mojo"
83+
p14 = "mojo -I . problems/p14/p14.mojo"
8484

85-
p15 = "mojo problems/p15/p15.mojo"
85+
p15 = "mojo -I . problems/p15/p15.mojo"
8686

87-
p16 = "bash solutions/gate.sh p16 mojo problems/p16/p16.mojo"
87+
p16 = "bash solutions/gate.sh p16 mojo -I . problems/p16/p16.mojo"
8888

8989
p17 = [
9090
{ cmd = "mojo package problems/p17/op -o problems/p17/op.mojoc" },
@@ -103,35 +103,35 @@ p19 = [
103103

104104
p20 = "python problems/p20/p20.py"
105105

106-
p21 = "python problems/p21/p21.py"
106+
p21 = { cmd = "python problems/p21/p21.py", env = { PYTHONPATH = "." } }
107107

108-
p22 = "bash solutions/gate.sh p22 python problems/p22/p22.py"
108+
p22 = { cmd = "bash solutions/gate.sh p22 python problems/p22/p22.py", env = { PYTHONPATH = "." } }
109109

110-
p23 = "mojo problems/p23/p23.mojo"
110+
p23 = "mojo -I . problems/p23/p23.mojo"
111111

112-
p24 = "mojo problems/p24/p24.mojo"
112+
p24 = "mojo -I . problems/p24/p24.mojo"
113113

114-
p25 = "mojo problems/p25/p25.mojo"
114+
p25 = "mojo -I . problems/p25/p25.mojo"
115115

116-
p26 = "mojo problems/p26/p26.mojo"
116+
p26 = "mojo -I . problems/p26/p26.mojo"
117117

118-
p27 = "mojo problems/p27/p27.mojo"
118+
p27 = "mojo -I . problems/p27/p27.mojo"
119119

120-
p28 = "bash solutions/gate.sh p28 mojo problems/p28/p28.mojo"
120+
p28 = "bash solutions/gate.sh p28 mojo -I . problems/p28/p28.mojo"
121121

122-
p29 = "bash solutions/gate.sh p29 mojo problems/p29/p29.mojo"
122+
p29 = "bash solutions/gate.sh p29 mojo -I . problems/p29/p29.mojo"
123123

124124
p30 = "mojo problems/p30/p30.mojo"
125125

126126
p31 = "mojo problems/p31/p31.mojo"
127127

128128
p32 = "mojo problems/p32/p32.mojo"
129129

130-
p33 = "bash solutions/gate.sh p33 mojo problems/p33/p33.mojo"
130+
p33 = "bash solutions/gate.sh p33 mojo -I . problems/p33/p33.mojo"
131131

132-
p34 = "bash solutions/gate.sh p34 mojo problems/p34/p34.mojo"
132+
p34 = "bash solutions/gate.sh p34 mojo -I . problems/p34/p34.mojo"
133133

134-
p35 = "mojo problems/p35/p35.mojo"
134+
p35 = "mojo -I . problems/p35/p35.mojo"
135135

136136
# GPU information
137137
gpu-info = { cmd = "python3 scripts/gpu_specs.py --summary" }

‎scripts/check_canaries.py‎

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
kernels in ``problems/pNN/op/``, so the glob below does not reach them.
2525
2626
Each puzzle in scope must use the canary in both its problem and solution
27-
files, and its `pixi` task must pass ``-I .`` so the `harness` import resolves.
27+
files, and both its `pixi` task and its `poe` task (the `uv` path, in
28+
``pyproject.toml``) must pass ``-I .`` so the `harness` import resolves.
2829
"""
2930

3031
from __future__ import annotations
@@ -66,8 +67,28 @@ def _pixi_tasks() -> dict[str, str]:
6667
)
6768

6869

70+
def _poe_tasks() -> dict[str, str]:
71+
# The [tool.poe.tasks] table, parsed the same way as pixi.toml rather than
72+
# with tomllib, which Python 3.10 (allowed by pyproject.toml) lacks. A
73+
# task's value can be a string, an inline table or a multi-line list, so
74+
# keep everything up to the next task name and search all of it.
75+
text = (REPO_ROOT / "pyproject.toml").read_text()
76+
table = re.search(
77+
r"^\[tool\.poe\.tasks\]$(.*?)(?=^\[|\Z)", text, re.MULTILINE | re.DOTALL
78+
)
79+
if table is None:
80+
return {}
81+
return dict(
82+
re.findall(
83+
r"^([A-Za-z0-9_-]+) = (.*?)(?=^[A-Za-z0-9_-]+ = |\Z)",
84+
table.group(1),
85+
re.MULTILINE | re.DOTALL,
86+
)
87+
)
88+
89+
6990
def main() -> None:
70-
tasks = _pixi_tasks()
91+
task_files = {"pixi.toml": _pixi_tasks(), "pyproject.toml": _poe_tasks()}
7192
problems = sorted((REPO_ROOT / "problems").glob("p*/p*.mojo"))
7293
failures: list[str] = []
7394
checked = 0
@@ -93,14 +114,15 @@ def main() -> None:
93114
)
94115

95116
task_name = problem.stem
96-
task = tasks.get(task_name)
97-
if task is None:
98-
failures.append(f"{rel}: no `{task_name}` task in pixi.toml")
99-
elif "-I ." not in task:
100-
failures.append(
101-
f"pixi.toml: task `{task_name}` must pass `-I .` so the"
102-
" harness import resolves"
103-
)
117+
for manifest, tasks in task_files.items():
118+
task = tasks.get(task_name)
119+
if task is None:
120+
failures.append(f"{rel}: no `{task_name}` task in {manifest}")
121+
elif "-I ." not in task:
122+
failures.append(
123+
f"{manifest}: task `{task_name}` must pass `-I .` so the"
124+
" harness import resolves"
125+
)
104126

105127
if failures:
106128
print(f"Checked {checked} learner-authored puzzles.\n")

‎solutions/sanitizer.sh‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
##===----------------------------------------------------------------------===##
1414
# Source shared configuration
1515
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
16+
17+
# Puzzles run from their own directory, so `mojo` needs the repo root to
18+
# find the `harness` package.
19+
PUZZLES_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
1620
source "$SCRIPT_DIR/config.sh"
1721

1822
# Detect GPU platform and compute capability at startup
@@ -176,7 +180,7 @@ run_mojo_files_with_sanitizer() {
176180
# puzzle written in the third style, including the race-detection one.
177181
if grep -qE "(argv\(\)\[1\]|test_type|flag)[[:space:]]*==[[:space:]]*\"$specific_flag\"" "$f"; then
178182
echo "=== Running compute-sanitizer --tool $tool on ${path_prefix}$f with flag: $specific_flag ==="
179-
output=$(compute-sanitizer --tool "$tool" mojo "$f" "$specific_flag" 2>&1)
183+
output=$(compute-sanitizer --tool "$tool" mojo -I "$PUZZLES_ROOT" "$f" "$specific_flag" 2>&1)
180184
filtered_output=$(echo "$output" | grep -E "$grep_pattern")
181185

182186
error_count=$(extract_error_count "$output")
@@ -203,7 +207,7 @@ run_mojo_files_with_sanitizer() {
203207
if [ -z "$flags" ]; then
204208
echo "No flags detected for ${path_prefix}$f"
205209
echo "=== Running compute-sanitizer --tool $tool on ${path_prefix}$f ==="
206-
output=$(compute-sanitizer --tool "$tool" mojo "$f" 2>&1)
210+
output=$(compute-sanitizer --tool "$tool" mojo -I "$PUZZLES_ROOT" "$f" 2>&1)
207211
filtered_output=$(echo "$output" | grep -E "$grep_pattern")
208212

209213
error_count=$(extract_error_count "$output")
@@ -222,7 +226,7 @@ run_mojo_files_with_sanitizer() {
222226
echo "Detected flags for ${path_prefix}$f: $flags"
223227
for flag in $flags; do
224228
echo "=== Running compute-sanitizer --tool $tool on ${path_prefix}$f with flag: $flag ==="
225-
output=$(compute-sanitizer --tool "$tool" mojo "$f" "$flag" 2>&1)
229+
output=$(compute-sanitizer --tool "$tool" mojo -I "$PUZZLES_ROOT" "$f" "$flag" 2>&1)
226230
filtered_output=$(echo "$output" | grep -E "$grep_pattern")
227231

228232
error_count=$(extract_error_count "$output")

0 commit comments

Comments
 (0)