Skip to content

Commit 23c8279

Browse files
committed
Fix the build issues with tests against build_files/ and log_files/ contents, collab with Claude Opus
Prompt 1: > Can you help me study Dune and improve the build setup for testing generated files? You can join me in reading the Dune documentation, e.g. starting from the page https://dune.readthedocs.io/en/stable/reference/actions/index.html . The problem is that the way I wrote the test/operations/dune file only sporadically makes things work. I added directory dependencies `(target (dir log_files))` and `(target (dir build_files))` to trigger generating files in these directories, relative to the directory executables are run. But the semantics of directory targets is like of any other targets: they can be in an "existing" and "non-existing" state, a rule is only triggered when the directory is missing, not when a file in the directory is missing. The build system encounters a missing file and complains that the directory-building rule did not produce it, but the rule did not run because the directory already existed. Maybe `include_subdirs` is the way? https://dune.readthedocs.io/en/stable/reference/dune/include_subdirs.html The page talks more about OCaml modules, but it should work for any files. Summary 1 by Claude: The issue with your current Dune setup is that directory targets only trigger when the directory doesn't exist. Once created, the rule won't re-run even if files inside are missing, causing sporadic build failures. I've created three improved solutions: 1. dune.improved - Stamp file approach - Uses sentinel/stamp files (.done files) to track when generation is complete - Subsequent rules depend on these stamps instead of directories - Most straightforward and reliable 2. dune.alternative - Multiple strategies - Shows promotion mode to capture generated files - Manifest approach to list generated files - Two-phase build with explicit file listing 3. dune.robust - Clean sentinel-based solution - Creates .done files after successful execution - All dependent rules wait for these sentinels - Guarantees proper ordering and file existence Recommended approach: Use dune.robust - it's the cleanest solution that: - Avoids the directory target problem entirely - Creates explicit dependencies through sentinel files - Ensures files exist before processing them - Works reliably with Dune's dependency tracking The key insight from the Dune documentation is that targets must be statically known and directory targets are experimental with limited semantics. Using sentinel files provides explicit, trackable dependencies that Dune handles well. Final summary by Claude: Updated Files: 1. test/operations/dune - Fixed directory target issues 2. test/einsum/dune - Applied same fix for consistency Key Solution: no-infer Action - Portable: Works on Linux, macOS, and Windows - Clean: Uses Dune's built-in copy action - Robust: Explicitly tells Dune not to track dependencies for side-effect files Pattern Used: (rule (target output.actual) (action (no-infer (progn (run executable --args) (copy generated/file.ext %{target}))))) This approach: - Generates files as side effects - Copies them using Dune's portable copy action - Avoids the "No rule found" errors - Eliminates sporadic failures from directory target semantics The no-infer wrapper is the key - it allows us to work with files that Dune doesn't know about (generated at runtime) while still using Dune's portable actions. Signed-off-by: Lukasz Stafiniak <lukstafi@gmail.com>
1 parent 72005ac commit 23c8279

File tree

2 files changed

+44
-53
lines changed

2 files changed

+44
-53
lines changed

test/einsum/dune

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,14 @@
6969

7070
(rule
7171
(alias runtest)
72-
(target
73-
(dir build_files))
72+
(target inline_permuted_view-c_fwd.ll.actual)
7473
(action
75-
(run
76-
%{dep:inline_permuted_view.exe}
77-
"--ocannl_output_debug_files_in_build_directory=true")))
78-
79-
(rule
80-
(deps "build_files/c_fwd.ll")
81-
(target "inline_permuted_view-c_fwd.ll.actual")
82-
(action
83-
(copy "build_files/c_fwd.ll" "inline_permuted_view-c_fwd.ll.actual")))
74+
(no-infer
75+
(progn
76+
(run
77+
%{dep:inline_permuted_view.exe}
78+
"--ocannl_output_debug_files_in_build_directory=true")
79+
(copy build_files/c_fwd.ll %{target})))))
8480

8581
(rule
8682
(alias runtest)

test/operations/dune

Lines changed: 37 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,23 @@
1616
(action
1717
(run %{dep:../../../arrayjit/bin/read_config.exe} "--read=backend"))))
1818

19+
; Solution: Create intermediate targets that guarantee file generation
20+
; Step 1: Run the test and create a sentinel file when done
1921
(rule
20-
(alias runtest)
21-
(target
22-
(dir log_files))
22+
(targets micrograd_demo.done)
2323
(action
24-
(run
25-
%{dep:micrograd_demo_logging.exe}
26-
"--ocannl_debug_backend=text"
27-
"--ocannl_log_file_stem=micrograd_demo_logging"
28-
"--ocannl_log_main_domain_to_stdout=false"
29-
"--ocannl_debug_log_to_stream_files=true")))
30-
24+
(progn
25+
(run
26+
%{dep:micrograd_demo_logging.exe}
27+
"--ocannl_debug_backend=text"
28+
"--ocannl_log_file_stem=micrograd_demo_logging"
29+
"--ocannl_log_main_domain_to_stdout=false"
30+
"--ocannl_debug_log_to_stream_files=true")
31+
(write-file %{targets} "completed\n"))))
32+
33+
; Step 2: Process the log file, depending on the sentinel
3134
(rule
32-
(deps "log_files/%{read:config/ocannl_backend.txt}-0-0.log")
35+
(deps micrograd_demo.done)
3336
(target "%{read:config/ocannl_backend.txt}-0-0.log.actual")
3437
(action
3538
(progn
@@ -38,19 +41,19 @@
3841
" = 0x[0-9a-fA-F]+"
3942
" = 0xNNNN"
4043
"log_files/%{read:config/ocannl_backend.txt}-0-0.log"
41-
"%{read:config/ocannl_backend.txt}-0-0.log.actual")
44+
"%{target}")
4245
(run
4346
%{dep:../../tools/minised.exe}
4447
" = 00[0-9a-fA-F]+"
4548
" = 0xNNNN"
46-
"%{read:config/ocannl_backend.txt}-0-0.log.actual"
47-
"%{read:config/ocannl_backend.txt}-0-0.log.actual")
49+
"%{target}"
50+
"%{target}")
4851
(run
4952
%{dep:../../tools/minised.exe}
5053
"\\([a-z0-9_]+\\)\\[0\\]{=[-.e0-9]+} = "
5154
"\\1[0]{=MAYBE UNINITIALIZED} = "
52-
"%{read:config/ocannl_backend.txt}-0-0.log.actual"
53-
"%{read:config/ocannl_backend.txt}-0-0.log.actual"))))
55+
"%{target}"
56+
"%{target}"))))
5457

5558
(rule
5659
(alias runtest)
@@ -73,28 +76,28 @@
7376
(preprocess
7477
(pps ppx_here ppx_ocannl)))
7578

79+
; Generate both ll files and actual files in one rule using no-infer
7680
(rule
77-
(alias runtest)
78-
(target
79-
(dir build_files))
81+
(target n3_fwd_with_prec-unoptimized.ll.actual)
8082
(action
81-
(progn
82-
(run
83-
%{dep:threefry4x32_demo.exe}
84-
"--ocannl_output_prec_in_ll_files=true"
85-
"--ocannl_output_debug_files_in_build_directory=true")
86-
(run
87-
%{dep:top_down_prec.exe}
88-
"--ocannl_output_prec_in_ll_files=true"
89-
"--ocannl_output_debug_files_in_build_directory=true"))))
83+
(no-infer
84+
(progn
85+
(run
86+
%{dep:threefry4x32_demo.exe}
87+
"--ocannl_output_prec_in_ll_files=true"
88+
"--ocannl_output_debug_files_in_build_directory=true")
89+
(copy build_files/n3_fwd-unoptimized.ll %{target})))))
9090

9191
(rule
92-
(deps "build_files/n3_fwd-unoptimized.ll")
93-
(target "n3_fwd_with_prec-unoptimized.ll.actual")
92+
(target top_down_prec-unoptimized.ll.actual)
9493
(action
95-
(copy
96-
"build_files/n3_fwd-unoptimized.ll"
97-
"n3_fwd_with_prec-unoptimized.ll.actual")))
94+
(no-infer
95+
(progn
96+
(run
97+
%{dep:top_down_prec.exe}
98+
"--ocannl_output_prec_in_ll_files=true"
99+
"--ocannl_output_debug_files_in_build_directory=true")
100+
(copy build_files/d_fwd-unoptimized.ll %{target})))))
98101

99102
(rule
100103
(alias runtest)
@@ -103,14 +106,6 @@
103106
"n3_fwd_with_prec-unoptimized.ll.expected"
104107
"n3_fwd_with_prec-unoptimized.ll.actual")))
105108

106-
(rule
107-
(deps "build_files/d_fwd-unoptimized.ll")
108-
(target "top_down_prec-unoptimized.ll.actual")
109-
(action
110-
(copy
111-
"build_files/d_fwd-unoptimized.ll"
112-
"top_down_prec-unoptimized.ll.actual")))
113-
114109
(rule
115110
(alias runtest)
116111
(action
@@ -156,4 +151,4 @@
156151
(modules hello_world_op zero2hero_1of7 primitive_ops test_threefry4x32)
157152
(preprocess
158153
(pps ppx_here ppx_expect ppx_inline_test ppx_ocannl))
159-
(modes best))
154+
(modes best))

0 commit comments

Comments
 (0)