Skip to content

Commit 18672fb

Browse files
Fix Log and Equal is_equivalent ignoring primitive state (#4266)
Co-authored-by: Cheng <git@zcbenz.com>
1 parent dcf4b2a commit 18672fb

3 files changed

Lines changed: 35 additions & 2 deletions

File tree

mlx/primitives.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,6 +1941,11 @@ std::pair<std::vector<array>, std::vector<int>> Equal::vmap(
19411941
return {{equal(a, b, stream())}, {to_ax}};
19421942
}
19431943

1944+
bool Equal::is_equivalent(const Primitive& other) const {
1945+
const Equal& e_other = static_cast<const Equal&>(other);
1946+
return equal_nan_ == e_other.equal_nan_;
1947+
}
1948+
19441949
std::vector<array> Equal::vjp(
19451950
const std::vector<array>& primals,
19461951
const std::vector<array>& cotangents,
@@ -2795,6 +2800,11 @@ std::pair<std::vector<array>, std::vector<int>> Log::vmap(
27952800
axes};
27962801
}
27972802

2803+
bool Log::is_equivalent(const Primitive& other) const {
2804+
const Log& l_other = static_cast<const Log&>(other);
2805+
return base_ == l_other.base_;
2806+
}
2807+
27982808
std::vector<array> Log1p::vjp(
27992809
const std::vector<array>& primals,
28002810
const std::vector<array>& cotangents,

mlx/primitives.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -975,9 +975,9 @@ class Equal : public UnaryPrimitive {
975975

976976
DEFINE_VMAP()
977977
DEFINE_GRADS()
978-
DEFINE_DEFAULT_IS_EQUIVALENT()
979978
DEFINE_INPUT_OUTPUT_SHAPE()
980979

980+
bool is_equivalent(const Primitive& other) const override;
981981
const char* name() const override {
982982
if (equal_nan_) {
983983
return "NaNEqual";
@@ -1325,9 +1325,9 @@ class Log : public UnaryPrimitive {
13251325

13261326
DEFINE_VMAP()
13271327
DEFINE_GRADS()
1328-
DEFINE_DEFAULT_IS_EQUIVALENT()
13291328
DEFINE_INPUT_OUTPUT_SHAPE()
13301329

1330+
bool is_equivalent(const Primitive& other) const override;
13311331
Base state() const {
13321332
return base_;
13331333
};

python/tests/test_compile.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1623,6 +1623,29 @@ def test_compile_abs_unsigned(self):
16231623
x = mx.array([1, 2, 3], dtype)
16241624
self.assertTrue(mx.array_equal(mx.compile(fun)(x), fun(x)))
16251625

1626+
def test_compile_different_log_bases(self):
1627+
# The logs are intermediates, since outputs are not simplified.
1628+
def entropies(p):
1629+
nats = -mx.sum(p * mx.log(p))
1630+
bits = -mx.sum(p * mx.log2(p))
1631+
return mx.stack([nats, bits])
1632+
1633+
p = np.array([0.1, 0.2, 0.3, 0.4], dtype=np.float32)
1634+
expected = np.array(
1635+
[-(p * np.log(p)).sum(), -(p * np.log2(p)).sum()], dtype=np.float32
1636+
)
1637+
out = mx.compile(entropies)(mx.array(p))
1638+
self.assertTrue(np.allclose(out, expected, atol=1e-5))
1639+
1640+
def test_compile_equal_nan(self):
1641+
def fun(x):
1642+
return mx.stack(
1643+
[mx.array_equal(x, x), mx.array_equal(x, x, equal_nan=True)]
1644+
)
1645+
1646+
x = mx.array([1.0, float("nan"), 3.0])
1647+
self.assertTrue(mx.array_equal(mx.compile(fun)(x), mx.array([False, True])))
1648+
16261649

16271650
if __name__ == "__main__":
16281651
mlx_tests.MLXTestRunner()

0 commit comments

Comments
 (0)