Skip to content

Commit

Permalink
Attempted redo of faster noise (#6539)
Browse files Browse the repository at this point in the history
* Make random 2x faster by putting the innermost var last

* Improve period of low bits of random noise

* Add new rewrite rules for quadratics

By pulling constant additions outside of quadratics, we can shave off a
few add instructions in the inner loop for random number generation,
which uses a quadratic modulo 2^32

I also removed the !overflows predicates, because rules already fail to
match if a fold overflows.

New rules formally verified.

* Make expensive_zero actually always zero

* Partially revert new simplifier rules

* Enable new rules

* Revert test

Co-authored-by: Steven Johnson <srj@google.com>
  • Loading branch information
abadams and steven-johnson authored Jan 7, 2022
1 parent daa5b7c commit b8a711a
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 5 deletions.
10 changes: 8 additions & 2 deletions src/Random.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ Expr random_int(const vector<Expr> &e) {
rng32(Variable::make(UInt(32), name)));
}
}
// The low bytes of this have a poor period, so mix in the high bytes for
// two additional instructions.
result = result ^ (result >> 16);

return result;
}

Expand All @@ -101,7 +105,9 @@ class LowerRandom : public IRMutator {
Expr visit(const Call *op) override {
if (op->is_intrinsic(Call::random)) {
vector<Expr> args = op->args;
args.insert(args.end(), extra_args.begin(), extra_args.end());
// Insert the free vars in reverse, so innermost vars typically end
// up last.
args.insert(args.end(), extra_args.rbegin(), extra_args.rend());
if (op->type == Float(32)) {
return random_float(args);
} else if (op->type == Int(32)) {
Expand All @@ -121,14 +127,14 @@ class LowerRandom : public IRMutator {

public:
LowerRandom(const vector<VarOrRVar> &free_vars, int tag) {
extra_args.emplace_back(tag);
for (const VarOrRVar &v : free_vars) {
if (v.is_rvar) {
extra_args.push_back(v.rvar);
} else {
extra_args.push_back(v.var);
}
}
extra_args.emplace_back(tag);
}
};

Expand Down
5 changes: 5 additions & 0 deletions src/Simplify_Mul.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ Expr Simplify::visit(const Mul *op, ExprInfo *bounds) {
}

if (rewrite(c0 * c1, fold(c0 * c1)) ||
(!no_overflow(op->type) && // Intentionally-overflowing quadratics used in random number generation
(rewrite((x + c0) * (x + c1), x * (x + fold(c0 + c1)) + fold(c0 * c1)) ||
rewrite((x * c0 + c1) * (x + c2), x * (x * c0 + fold(c1 + c0 * c2)) + fold(c1 * c2)) ||
rewrite((x + c2) * (x * c0 + c1), x * (x * c0 + fold(c1 + c0 * c2)) + fold(c1 * c2)) ||
rewrite((x * c0 + c1) * (x * c2 + c3), x * (x * fold(c0 * c2) + fold(c0 * c3 + c1 * c2)) + fold(c1 * c3)))) ||
rewrite((x + c0) * c1, x * c1 + fold(c0 * c1), !overflows(c0 * c1)) ||
rewrite((c0 - x) * c1, x * fold(-c1) + fold(c0 * c1), !overflows(c0 * c1)) ||
rewrite((0 - x) * y, 0 - x * y) ||
Expand Down
6 changes: 3 additions & 3 deletions test/correctness/async_device_copy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ Expr expensive_zero(Expr x, Expr y, Expr t, int n) {
RDom r(0, n);
Func a, b, c;
Var z;
a(x, y, t, z) = random_int() % 1024;
b(x, y, t, z) = random_int() % 1024;
c(x, y, t, z) = random_int() % 1024;
a(x, y, t, z) = random_int() % 1024 + 5;
b(x, y, t, z) = random_int() % 1024 + 5;
c(x, y, t, z) = random_int() % 1024 + 5;
return sum(select(pow(a(x, y, t, r), 3) + pow(b(x, y, t, r), 3) == pow(c(x, y, t, r), 3), 1, 0));
}

Expand Down

0 comments on commit b8a711a

Please sign in to comment.