Skip to content

Commit

Permalink
Make the xls_ir_equivalence_test rule actually function as a test.
Browse files Browse the repository at this point in the history
Previously the test would always be considered passing because the checker exited 0 in all circumstances. Make the checker exit non-zero (255) if the expected outcome is not seen.

PiperOrigin-RevId: 666993715
  • Loading branch information
allight authored and copybara-github committed Aug 24, 2024
1 parent 6c8c014 commit d374f5f
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 13 deletions.
8 changes: 5 additions & 3 deletions docs_src/bazel_rules_macros.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,8 @@ Examples:
## xls_dslx_opt_ir_test

<pre>
xls_dslx_opt_ir_test(<a href="#xls_dslx_opt_ir_test-name">name</a>, <a href="#xls_dslx_opt_ir_test-benchmark_ir_args">benchmark_ir_args</a>, <a href="#xls_dslx_opt_ir_test-dep">dep</a>, <a href="#xls_dslx_opt_ir_test-dslx_test_args">dslx_test_args</a>, <a href="#xls_dslx_opt_ir_test-input_validator">input_validator</a>,
<a href="#xls_dslx_opt_ir_test-input_validator_expr">input_validator_expr</a>, <a href="#xls_dslx_opt_ir_test-ir_equivalence_args">ir_equivalence_args</a>, <a href="#xls_dslx_opt_ir_test-ir_eval_args">ir_eval_args</a>,
xls_dslx_opt_ir_test(<a href="#xls_dslx_opt_ir_test-name">name</a>, <a href="#xls_dslx_opt_ir_test-benchmark_ir_args">benchmark_ir_args</a>, <a href="#xls_dslx_opt_ir_test-dep">dep</a>, <a href="#xls_dslx_opt_ir_test-dslx_test_args">dslx_test_args</a>, <a href="#xls_dslx_opt_ir_test-expect_equivalent">expect_equivalent</a>,
<a href="#xls_dslx_opt_ir_test-input_validator">input_validator</a>, <a href="#xls_dslx_opt_ir_test-input_validator_expr">input_validator_expr</a>, <a href="#xls_dslx_opt_ir_test-ir_equivalence_args">ir_equivalence_args</a>, <a href="#xls_dslx_opt_ir_test-ir_eval_args">ir_eval_args</a>,
<a href="#xls_dslx_opt_ir_test-scheduling_options_proto">scheduling_options_proto</a>, <a href="#xls_dslx_opt_ir_test-top">top</a>)
</pre>

Expand Down Expand Up @@ -330,6 +330,7 @@ Examples:
| <a id="xls_dslx_opt_ir_test-benchmark_ir_args"></a>benchmark_ir_args | Arguments of the benchmark IR tool. For details on the arguments, refer to the benchmark_main application at //xls/tools/benchmark_main.cc. | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | `{}` |
| <a id="xls_dslx_opt_ir_test-dep"></a>dep | The xls_dslx_opt_ir target to test. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | `None` |
| <a id="xls_dslx_opt_ir_test-dslx_test_args"></a>dslx_test_args | Arguments of the DSLX interpreter executable. For details on the arguments, refer to the interpreter_main application at //xls/dslx/interpreter_main.cc. | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | `{}` |
| <a id="xls_dslx_opt_ir_test-expect_equivalent"></a>expect_equivalent | If true this test fails if IRs are not equivalent. If false the test only passes if the IRs are not equivalent. | Boolean | optional | `True` |
| <a id="xls_dslx_opt_ir_test-input_validator"></a>input_validator | The DSLX library defining the input validator for this test. Mutually exclusive with "input_validator_expr". | <a href="https://bazel.build/concepts/labels">Label</a> | optional | `None` |
| <a id="xls_dslx_opt_ir_test-input_validator_expr"></a>input_validator_expr | The expression to validate an input for the test function. Mutually exclusive with "input_validator". | String | optional | `""` |
| <a id="xls_dslx_opt_ir_test-ir_equivalence_args"></a>ir_equivalence_args | Arguments of the IR equivalence tool. For details on the arguments, refer to the check_ir_equivalence_main application at //xls/tools/check_ir_equivalence_main.cc. The 'function' argument is not assigned using this attribute. | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | `{}` |
Expand Down Expand Up @@ -498,7 +499,7 @@ Examples:
## xls_ir_equivalence_test

<pre>
xls_ir_equivalence_test(<a href="#xls_ir_equivalence_test-name">name</a>, <a href="#xls_ir_equivalence_test-ir_equivalence_args">ir_equivalence_args</a>, <a href="#xls_ir_equivalence_test-src_0">src_0</a>, <a href="#xls_ir_equivalence_test-src_1">src_1</a>, <a href="#xls_ir_equivalence_test-top">top</a>)
xls_ir_equivalence_test(<a href="#xls_ir_equivalence_test-name">name</a>, <a href="#xls_ir_equivalence_test-expect_equivalent">expect_equivalent</a>, <a href="#xls_ir_equivalence_test-ir_equivalence_args">ir_equivalence_args</a>, <a href="#xls_ir_equivalence_test-src_0">src_0</a>, <a href="#xls_ir_equivalence_test-src_1">src_1</a>, <a href="#xls_ir_equivalence_test-top">top</a>)
</pre>

Executes the equivalence tool on two IR files.
Expand Down Expand Up @@ -536,6 +537,7 @@ Examples:
| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="xls_ir_equivalence_test-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
| <a id="xls_ir_equivalence_test-expect_equivalent"></a>expect_equivalent | If true this test fails if IRs are not equivalent. If false the test only passes if the IRs are not equivalent. | Boolean | optional | `True` |
| <a id="xls_ir_equivalence_test-ir_equivalence_args"></a>ir_equivalence_args | Arguments of the IR equivalence tool. For details on the arguments, refer to the check_ir_equivalence_main application at //xls/tools/check_ir_equivalence_main.cc. The 'function' argument is not assigned using this attribute. | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | `{}` |
| <a id="xls_ir_equivalence_test-src_0"></a>src_0 | An IR source file for the rule. A single source file must be provided. The file must have a '.ir' extension. | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
| <a id="xls_ir_equivalence_test-src_1"></a>src_1 | An IR source file for the rule. A single source file must be provided. The file must have a '.ir' extension. | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
Expand Down
13 changes: 11 additions & 2 deletions xls/build_rules/xls_ir_rules.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ def get_ir_equivalence_test_cmd(
ctx,
src_0,
src_1,
expect_equiv,
append_cmd_line_args = True):
"""
Returns the runfiles and command that executes in the ir_equivalence_test rule.
Expand All @@ -293,6 +294,7 @@ def get_ir_equivalence_test_cmd(
ctx: The current rule's context object.
src_0: A file for the test.
src_1: A file for the test.
expect_equiv: Is a passing result when the irs are equivalent.
append_cmd_line_args: Flag controlling appending the command-line
arguments invoking the command generated by this function. When set to
True, the command-line arguments invoking the command are appended.
Expand All @@ -314,11 +316,13 @@ def get_ir_equivalence_test_cmd(
ir_equivalence_args.setdefault("top", ctx.attr.top)
my_args = args_to_string(ir_equivalence_args)

cmd = "{} {} {} {}\n".format(
cmd = "{} {} {} {} --match_exit_code={} --mismatch_exit_code={}\n".format(
ir_equivalence_tool.short_path,
src_0.ir_file.short_path,
src_1.ir_file.short_path,
my_args,
0 if expect_equiv else 255,
255 if expect_equiv else 0,
)

# Append command-line arguments.
Expand Down Expand Up @@ -832,7 +836,7 @@ def _xls_ir_equivalence_test_impl(ctx):
transitive_files.append(ctx.attr.src_0[DefaultInfo].files)
transitive_files.append(ctx.attr.src_1[DefaultInfo].files)

runfiles, cmd = get_ir_equivalence_test_cmd(ctx, ir_file_a, ir_file_b)
runfiles, cmd = get_ir_equivalence_test_cmd(ctx, ir_file_a, ir_file_b, ctx.attr.expect_equivalent)
executable_file = ctx.actions.declare_file(ctx.label.name + ".sh")
ctx.actions.write(
output = executable_file,
Expand Down Expand Up @@ -878,6 +882,11 @@ xls_ir_equivalence_test_attrs = {
"at //xls/tools/check_ir_equivalence_main.cc. " +
"The 'function' argument is not assigned using this attribute.",
),
"expect_equivalent": attr.bool(
default = True,
doc = "If true this test fails if IRs are not equivalent. If false the " +
"test only passes if the IRs are not equivalent.",
),
}

xls_ir_equivalence_test = rule(
Expand Down
1 change: 1 addition & 0 deletions xls/build_rules/xls_rules.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ def _xls_dslx_opt_ir_test_impl(ctx):
ctx,
conv_ir_file,
opt_ir_file,
True,
)
runfiles = runfiles.merge(my_runfiles)

Expand Down
17 changes: 15 additions & 2 deletions xls/tools/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@

# pytype binary and test
load("@rules_python//python:proto.bzl", "py_proto_library")
# cc_proto_library is used in this file

load("@xls_pip_deps//:requirements.bzl", "requirement")
load("//xls/build_rules:xls_build_defs.bzl", "xls_ir_equivalence_test")
# cc_proto_library is used in this file

package(
default_applicable_licenses = ["//:license"],
Expand Down Expand Up @@ -431,6 +431,19 @@ cc_binary(
],
)

xls_ir_equivalence_test(
name = "equiv_test",
src_0 = "testdata/add_big.ir",
src_1 = "testdata/add_big.ir",
)

xls_ir_equivalence_test(
name = "not_equiv_test",
expect_equivalent = False,
src_0 = "testdata/add_big.ir",
src_1 = "testdata/add_small.ir",
)

filegroup(
name = "check_ir_equivalence_sh",
srcs = ["check_ir_equivalence.sh"],
Expand Down
24 changes: 18 additions & 6 deletions xls/tools/check_ir_equivalence_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,20 @@ Example invocation:
check_ir_equivalence_main <IR file> <IR file>
If there are multiple functions in the specified files, then it's _strongly_
recommended that you specify --function to ensure that the right functions are
recommended that you specify --top to ensure that the right functions are
compared. If the tool picks the wrong one, a crash may result.
Exits with code --mismatch_exit_code if equivalence is not found.
)";

// LINT.IfChange
ABSL_FLAG(std::string, top, "",
"The top entity to check. If unspecified, an attempt will be made"
"to find and check a top entity for the package. Currently, only"
"Functions are supported.");
ABSL_FLAG(int, mismatch_exit_code, 255,
"Value to exit with if equivalence is not proven.");
ABSL_FLAG(int, match_exit_code, 0,
"Value to exit with if equivalence is not proven.");
ABSL_FLAG(absl::Duration, timeout, absl::InfiniteDuration(),
"How long to wait for any proof to complete.");
// LINT.ThenChange(//xls/build_rules/xls_ir_rules.bzl)
Expand Down Expand Up @@ -95,8 +100,9 @@ absl::StatusOr<std::vector<std::string>> CounterexampleParams(
return counterexample;
}

absl::Status RealMain(const std::vector<std::string_view>& ir_paths,
const std::string& entry, absl::Duration timeout) {
absl::StatusOr<bool> RealMain(const std::vector<std::string_view>& ir_paths,
const std::string& entry,
absl::Duration timeout) {
std::vector<std::unique_ptr<Package>> packages;
for (const auto ir_path : ir_paths) {
XLS_ASSIGN_OR_RETURN(std::string ir_text, GetFileContents(ir_path));
Expand Down Expand Up @@ -149,9 +155,10 @@ absl::Status RealMain(const std::vector<std::string_view>& ir_paths,
std::get<solvers::z3::ProvenFalse>(result)));
std::cout << "Verified NOT equivalent; results differ for input: "
<< absl::StrJoin(params, ", ") << "\n";
return false;
}

return absl::OkStatus();
return true;
}

} // namespace
Expand All @@ -161,6 +168,11 @@ int main(int argc, char** argv) {
std::vector<std::string_view> positional_args =
xls::InitXls(kUsage, argc, argv);
QCHECK_EQ(positional_args.size(), 2) << "Two IR files must be specified!";
return xls::ExitStatus(xls::RealMain(
positional_args, absl::GetFlag(FLAGS_top), absl::GetFlag(FLAGS_timeout)));
auto result = xls::RealMain(positional_args, absl::GetFlag(FLAGS_top),
absl::GetFlag(FLAGS_timeout));
if (!result.ok()) {
return xls::ExitStatus(result.status());
}
return *result ? absl::GetFlag(FLAGS_match_exit_code)
: absl::GetFlag(FLAGS_mismatch_exit_code);
}
6 changes: 6 additions & 0 deletions xls/tools/testdata/add_big.ir
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

package add_pkg

top fn add(a: bits[8], b: bits[8]) -> bits[8] {
ret add.3: bits[8] = add(a, b, id=3)
}
8 changes: 8 additions & 0 deletions xls/tools/testdata/add_small.ir
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package add_pkg

top fn add(a: bits[8], b: bits[8]) -> bits[8] {
bit_slice.3: bits[4] = bit_slice(a, start=0, width=4, id=3)
bit_slice.4: bits[4] = bit_slice(b, start=0, width=4, id=4)
add.5: bits[4] = add(bit_slice.3, bit_slice.4, id=5)
ret zero_ext.6: bits[8] = zero_ext(add.5, new_bit_count=8, id=6)
}

0 comments on commit d374f5f

Please sign in to comment.