-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[mlir][utils] Add script to verify canonicalizations against Alive2 #91867
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This script takes IR before and after canonicalization, translates it into llvm IR and converts to format suitablle for Alive2 https://alive2.llvm.org/ce/ This is primarily for arith canonicalizations verification, but technically it can be adapted for any dialect translatable to llvm. Usage `python verify_canon.py canonicalize.mlir func1 func2 ...` Example output: https://alive2.llvm.org/ce/z/KhQs4J Initial discussion: llvm#91646 (review)
@llvm/pr-subscribers-mlir Author: Ivan Butygin (Hardcode84) ChangesThis script takes IR before and after canonicalization, translates it into llvm IR and converts it to format suitable for Alive2 https://alive2.llvm.org/ce/ This is primarily for arith canonicalizations verification, but technically it can be adapted for any dialect translatable to llvm. Usage Example output: https://alive2.llvm.org/ce/z/KhQs4J Initial discussion: #91646 (review) Full diff: https://github.com/llvm/llvm-project/pull/91867.diff 1 Files Affected:
diff --git a/mlir/utils/verify-canon/verify_canon.py b/mlir/utils/verify-canon/verify_canon.py
new file mode 100644
index 0000000000000..1dae30757f220
--- /dev/null
+++ b/mlir/utils/verify-canon/verify_canon.py
@@ -0,0 +1,74 @@
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+# Run canonicalization, convert IR to LLVM and convert to format suitable to
+# verification against Alive2 https://alive2.llvm.org/ce/.
+
+import subprocess
+import tempfile
+import sys
+from pathlib import Path
+
+
+def filter_funcs(ir, funcs):
+ if not funcs:
+ return ir
+
+ funcs_str = ",".join(funcs)
+ return subprocess.check_output(
+ ["mlir-opt", f"--symbol-privatize=exclude={funcs_str}", "--symbol-dce"],
+ input=ir,
+ )
+
+
+def add_func_prefix(src, prefix):
+ return src.replace("@", "@" + prefix)
+
+
+def merge_ir(chunks):
+ files = []
+ for chunk in chunks:
+ tmp = tempfile.NamedTemporaryFile(suffix=".ll")
+ tmp.write(chunk)
+ tmp.flush()
+ files.append(tmp)
+
+ return subprocess.check_output(["llvm-link", "-S"] + [f.name for f in files])
+
+
+if __name__ == "__main__":
+ argv = sys.argv
+ if len(argv) < 2:
+ print(f"usage: {argv[0]} canonicalize.mlir [func1] [func2] ...")
+ exit(0)
+
+ file = argv[1]
+ funcs = argv[2:]
+
+ orig_ir = Path(file).read_bytes()
+ orig_ir = filter_funcs(orig_ir, funcs)
+
+ to_llvm_args = [
+ "--convert-arith-to-llvm",
+ "--convert-func-to-llvm",
+ "--convert-ub-to-llvm",
+ "--convert-vector-to-llvm",
+ ]
+ orig_args = ["mlir-opt"] + to_llvm_args
+ canon_args = ["mlir-opt", "-canonicalize"] + to_llvm_args
+ translate_args = ["mlir-translate", "-mlir-to-llvmir"]
+
+ orig = subprocess.check_output(orig_args, input=orig_ir)
+ canonicalized = subprocess.check_output(canon_args, input=orig_ir)
+
+ orig = subprocess.check_output(translate_args, input=orig)
+ canonicalized = subprocess.check_output(translate_args, input=canonicalized)
+
+ enc = "utf-8"
+ orig = bytes(add_func_prefix(orig.decode(enc), "src_"), enc)
+ canonicalized = bytes(add_func_prefix(canonicalized.decode(enc), "tgt_"), enc)
+
+ res = merge_ir([orig, canonicalized])
+
+ print(res.decode(enc))
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for writing this. I came up with a similar arith
rewrite testing flow but never bothered to package it as a script, seems very useful!
"--convert-arith-to-llvm", | ||
"--convert-func-to-llvm", | ||
"--convert-ub-to-llvm", | ||
"--convert-vector-to-llvm", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should all be handled by a single --convert-to-llvm
, aren't they?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
# Run canonicalization, convert IR to LLVM and convert to format suitable to | ||
# verification against Alive2 https://alive2.llvm.org/ce/. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would probably go for an item list here to make it a bit less dense:
e.g.:
This script is a helper to verify canonicalization patterns using Alive2 https://alive2.llvm.org/ce/.
It performs the following steps:
- Filters out the provided test functions.
- Runs the canonicalization pass on the remaining functions.
- Lowers both the original and the canonicalized functions to LLVM IR.
- Prints the canonicalized and the original function side-by-side in a format that can be copied into Alive2 for verification.
Example: `python verify_canon.py canonicalize.mlir func1 func2 func3`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
LGTM from my end.
# - Filters out the provided test functions. | ||
# - Runs the canonicalization pass on the remaining functions. | ||
# - Lowers both the original and the canonicalized functions to LLVM IR. | ||
# - Prints the canonicalized and the original function side-by-side in a format |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# - Prints the canonicalized and the original function side-by-side in a format | |
# - Prints the canonicalized and the original functions side-by-side in a format |
Sorry my bad... This should be plural.
Just noticed this one, this is really nice. Hoping it flushes out more cases :) |
This script takes IR before and after canonicalization, translates it into llvm IR and converts it to format suitable for Alive2 https://alive2.llvm.org/ce/
This is primarily for arith canonicalizations verification, but technically it can be adapted for any dialect translatable to llvm.
Usage
python verify_canon.py canonicalize.mlir -f func1 func2 ...
Example output: https://alive2.llvm.org/ce/z/KhQs4J
Initial discussion: #91646 (review)