Skip to content

Commit

Permalink
Expand the x86 SIMD variants tested in correctness_vector_reductions (#…
Browse files Browse the repository at this point in the history
…6762)

A recent bug in LLVM codegen was missed because it only affected x86 architectures with earlier-than-AVX2 SIMD enabled; it didn't show up for AVX2 or later. This revamps correctness_vector_reductions to re-run multiple times when multiple SIMD architectures are available on x86 systems.

(correctness_vector_reductions was chosen here because it reliably demonstrated the specific failures in this case.)
  • Loading branch information
steven-johnson authored May 13, 2022
1 parent 4ab4ad9 commit 09a986e
Showing 1 changed file with 57 additions and 4 deletions.
61 changes: 57 additions & 4 deletions test/correctness/vector_reductions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

using namespace Halide;

int main(int argc, char **argv) {
namespace {

void run_test(const Target &target) {
std::cout << "vector_reductions: Testing with " << target << "\n";

for (int dst_lanes : {1, 3}) {
for (int reduce_factor : {2, 3, 4}) {
std::vector<Type> types =
Expand Down Expand Up @@ -103,10 +107,23 @@ int main(int argc, char **argv) {
.vectorize(rx);
ref.compute_root();

// Useful for debugging; leave in (commented out)
// std::cout << "Testing: dst_lanes: " << dst_lanes
// << " reduce_factor " << reduce_factor
// << " src_type " << src_type
// << " widen_factor " << widen_factor
// << " dst_type " << dst_type
// << " op " << op
// << "\n";

RDom c(0, 128);
Expr err = cast<double>(maximum(absd(f(c), ref(c))));

double e = evaluate<double>(err);
// Func.evaluate() doesn't let you specify a Target (!),
// so let's use Func.realize() instead.
Func err("err");
err() = cast<double>(maximum(absd(f(c), ref(c))));
Buffer<double, 0> err_im = err.realize({}, target);
double e = err_im();

if (e > 1e-3) {
std::cerr
Expand All @@ -122,7 +139,43 @@ int main(int argc, char **argv) {
}
}
}
}

} // namespace

int main(int argc, char **argv) {
Target target = get_jit_target_from_environment();
run_test(target);
if (target.arch == Target::X86) {
// LLVM has had SIMD codegen errors that we missed because we didn't test against
// multiple SIMD architectures, using just 'host' instead. To remedy this, we'll
// re-run this multiple times, downgrading the SIMD successively, to ensure we get
// test coverage. Note that this doesn't attempt to be exhaustive -- there are too
// many permutations to really test, especially with AVX512 -- but this way we
// can get at least baseline coverage for the major variants.
//
// (Note also that our codegen for x86 implicitly 'fills in' required prerequisites,
// e.g. if you specify a target with AVX2, the codegen will automatically include
// AVX and SSE41 as well.)
if (target.has_feature(Target::AVX512)) {
Target avx2_target(target.os, target.arch, target.bits, {Target::AVX2});
run_test(avx2_target);
}
if (target.has_feature(Target::AVX2)) {
Target sse41_target(target.os, target.arch, target.bits, {Target::AVX});
run_test(sse41_target);
}
if (target.has_feature(Target::AVX)) {
Target sse41_target(target.os, target.arch, target.bits, {Target::SSE41});
run_test(sse41_target);
}
if (target.has_feature(Target::SSE41)) {
// Halide assumes that all x86 targets have at least sse2
Target sse2_target(target.os, target.arch, target.bits);
run_test(sse2_target);
}
}

printf("Success!\n");
std::cout << "Success!\n";
return 0;
}

0 comments on commit 09a986e

Please sign in to comment.