68
68
const DUMP_MLIR_DIR = Ref {Union{Nothing,String}} (nothing )
69
69
# Whether to always dump MLIR, regardless of failure
70
70
const DUMP_MLIR_ALWAYS = Ref {Bool} (false )
71
+ # Counter for dumping MLIR modules
72
+ const MLIR_DUMP_COUNTER = Threads. Atomic {Int} (0 )
71
73
72
74
# Utilities for dumping to a file the module of a failed compilation, useful for
73
75
# debugging purposes.
74
- function dump_mlir (mod:: Module , pm:: Union{Nothing,PassManager} = nothing ; failed:: Bool = false )
76
+ function dump_mlir (
77
+ mod:: Module , pm:: Union{Nothing,PassManager} = nothing , mode:: String = " " ; failed:: Bool = false
78
+ )
75
79
try
76
80
# If `DUMP_MLIR_DIR` is `nothing`, create a persistent new temp
77
81
# directory, otherwise use the provided path.
78
82
dir = if isnothing (DUMP_MLIR_DIR[])
79
83
mkpath (tempdir ())
80
- mktempdir (; prefix= " reactant_" , cleanup= false )
84
+ # Use the same directory for this session
85
+ DUMP_MLIR_DIR[] = mktempdir (; prefix= " reactant_" , cleanup= false )
81
86
else
82
87
DUMP_MLIR_DIR[]
83
88
end
89
+
84
90
# Make sure the directory exists
85
91
mkpath (dir)
86
- path = tempname (dir; cleanup= false ) * " .mlir"
92
+
93
+ # Attempt to get the name of the module if that exists
94
+ module_op = Operation (mod)
95
+ mod_name = attr (module_op, String (API. mlirSymbolTableGetSymbolAttributeName ()))
96
+ fname = mod_name === nothing ? randstring (4 ) : String (mod_name)
97
+ fname = " module_" * lpad (MLIR_DUMP_COUNTER[], 3 , " 0" ) * " _$(fname) "
98
+ if isempty (mode)
99
+ fname *= " .mlir"
100
+ else
101
+ fname *= " _$(mode) .mlir"
102
+ end
103
+ MLIR_DUMP_COUNTER[] += 1
104
+ path = joinpath (dir, fname)
105
+
87
106
open (path, " w" ) do io
88
107
if ! isnothing (pm)
89
108
println (io, " // Pass pipeline:" )
@@ -93,7 +112,11 @@ function dump_mlir(mod::Module, pm::Union{Nothing,PassManager}=nothing; failed::
93
112
end
94
113
show (IOContext (io, :debug => true ), mod)
95
114
end
96
- failed && @error " Compilation failed, MLIR module written to $(path) "
115
+ if failed
116
+ @error " Compilation failed, MLIR module written to $(path) "
117
+ else
118
+ @debug " MLIR module written to $(path) "
119
+ end
97
120
catch err
98
121
@error " Couldn't save MLIR module" exception = err
99
122
end
@@ -103,15 +126,15 @@ function try_compile_dump_mlir(f, mod::Module, pm=nothing)
103
126
failed = false
104
127
# Dump MLIR before calling `f`. We set `pm` to nothing because the pass
105
128
# manager isn't called yet here.
106
- DUMP_MLIR_ALWAYS[] && dump_mlir (mod, nothing )
129
+ DUMP_MLIR_ALWAYS[] && dump_mlir (mod, nothing , " pre_xla_compile " )
107
130
try
108
131
f ()
109
132
catch
110
133
failed = true
111
134
rethrow ()
112
135
finally
113
136
if failed || DUMP_MLIR_ALWAYS[]
114
- dump_mlir (mod, pm; failed)
137
+ dump_mlir (mod, pm, " post_xla_compile " ; failed)
115
138
end
116
139
end
117
140
end
@@ -124,15 +147,15 @@ Run the provided `passManager` on the given `module`.
124
147
function run! (pm:: PassManager , mod:: Module )
125
148
# Dump MLIR before running the pass manager. We set `pm` to nothing because
126
149
# the pass manager isn't called yet here.
127
- DUMP_MLIR_ALWAYS[] && dump_mlir (mod, nothing )
150
+ DUMP_MLIR_ALWAYS[] && dump_mlir (mod, nothing , " pre_pm " )
128
151
status = LogicalResult (@static if isdefined (API, :mlirPassManagerRunOnOp )
129
152
API. mlirPassManagerRunOnOp (pm, Operation (mod))
130
153
else
131
154
API. mlirPassManagerRun (pm, mod)
132
155
end )
133
156
failed = isfailure (status)
134
157
if failed || DUMP_MLIR_ALWAYS[]
135
- dump_mlir (mod, pm; failed)
158
+ dump_mlir (mod, pm, " post_pm " ; failed)
136
159
end
137
160
if failed
138
161
throw (" failed to run pass manager on module" )
0 commit comments