mirror of
https://github.com/ml-explore/mlx.git
synced 2025-08-09 10:46:39 +08:00
handle hadamard and addmm on empty inputs
This commit is contained in:
parent
caaa3f1f8c
commit
bc3357e6ad
@ -132,6 +132,10 @@ void AddMM::eval_cpu(const std::vector<array>& inputs, array& out) {
|
|||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"[AddMM::eval_cpu] Currently only supports float32.");
|
"[AddMM::eval_cpu] Currently only supports float32.");
|
||||||
}
|
}
|
||||||
|
if (out.size() == 0) {
|
||||||
|
out.set_data(allocator::malloc(out.nbytes()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Fill output with C
|
// Fill output with C
|
||||||
auto& c = inputs[2];
|
auto& c = inputs[2];
|
||||||
@ -139,7 +143,9 @@ void AddMM::eval_cpu(const std::vector<array>& inputs, array& out) {
|
|||||||
? CopyType::Scalar
|
? CopyType::Scalar
|
||||||
: (c.flags().row_contiguous ? CopyType::Vector : CopyType::General);
|
: (c.flags().row_contiguous ? CopyType::Vector : CopyType::General);
|
||||||
copy(c, out, ctype, stream());
|
copy(c, out, ctype, stream());
|
||||||
|
if (inputs[0].shape(-1) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
matmul_general(inputs[0], inputs[1], out, stream(), alpha_, beta_);
|
matmul_general(inputs[0], inputs[1], out, stream(), alpha_, beta_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,6 +716,23 @@ void AddMM::eval_gpu(const std::vector<array>& inputs, array& out) {
|
|||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"[matmul] Does not yet support non-floating point types.");
|
"[matmul] Does not yet support non-floating point types.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return 0s if either input is empty
|
||||||
|
if (out.size() == 0) {
|
||||||
|
out.set_data(allocator::malloc(out.nbytes()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy c into out and return
|
||||||
|
if (inputs[0].shape(-1) == 0) {
|
||||||
|
copy_gpu(
|
||||||
|
inputs[2],
|
||||||
|
out,
|
||||||
|
inputs[2].flags().row_contiguous ? CopyType::Vector : CopyType::General,
|
||||||
|
stream());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
out.set_data(allocator::malloc(out.nbytes()));
|
out.set_data(allocator::malloc(out.nbytes()));
|
||||||
auto& s = stream();
|
auto& s = stream();
|
||||||
auto& d = metal::device(s.device);
|
auto& d = metal::device(s.device);
|
||||||
|
@ -472,6 +472,10 @@ array hadamard_transform(
|
|||||||
const array& a,
|
const array& a,
|
||||||
std::optional<float> scale_ /* = std::nullopt */,
|
std::optional<float> scale_ /* = std::nullopt */,
|
||||||
StreamOrDevice s /* = {} */) {
|
StreamOrDevice s /* = {} */) {
|
||||||
|
if (a.size() == 0) {
|
||||||
|
throw std::invalid_argument(
|
||||||
|
"[hadamard_transform] Does not support empty arrays.");
|
||||||
|
}
|
||||||
// Default to an orthonormal Hadamard matrix scaled by 1/sqrt(N)
|
// Default to an orthonormal Hadamard matrix scaled by 1/sqrt(N)
|
||||||
int n = a.ndim() > 0 ? a.shape(-1) : 1;
|
int n = a.ndim() > 0 ? a.shape(-1) : 1;
|
||||||
float scale = scale_.has_value() ? *scale_ : 1.0f / std::sqrt(n);
|
float scale = scale_.has_value() ? *scale_ : 1.0f / std::sqrt(n);
|
||||||
|
@ -745,6 +745,19 @@ class TestBlas(mlx_tests.MLXTestCase):
|
|||||||
mx.eval(c)
|
mx.eval(c)
|
||||||
self.assertEqual(c.shape, (0, 0))
|
self.assertEqual(c.shape, (0, 0))
|
||||||
|
|
||||||
|
c = mx.array([], dtype=mx.float32)
|
||||||
|
a = mx.array([], dtype=mx.float32)
|
||||||
|
b = mx.array([], dtype=mx.float32)
|
||||||
|
out = mx.addmm(a, b, c)
|
||||||
|
mx.eval(out)
|
||||||
|
self.assertEqual(out.shape, ())
|
||||||
|
|
||||||
|
a = mx.zeros(shape=(5, 0))
|
||||||
|
b = mx.zeros(shape=(0, 5))
|
||||||
|
c = mx.random.uniform(shape=(5, 5))
|
||||||
|
out = mx.addmm(c, a, b)
|
||||||
|
self.assertTrue(mx.allclose(out, c))
|
||||||
|
|
||||||
def test_block_masked_matmul(self):
|
def test_block_masked_matmul(self):
|
||||||
def ref_block_masked_mm(
|
def ref_block_masked_mm(
|
||||||
a, b, block_size, out_mask=None, lhs_mask=None, rhs_mask=None
|
a, b, block_size, out_mask=None, lhs_mask=None, rhs_mask=None
|
||||||
|
@ -2830,6 +2830,9 @@ class TestOps(mlx_tests.MLXTestCase):
|
|||||||
return H
|
return H
|
||||||
|
|
||||||
def test_hadamard(self):
|
def test_hadamard(self):
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
mx.hadamard_transform(mx.array([]))
|
||||||
|
|
||||||
h28_str = """
|
h28_str = """
|
||||||
+------++----++-+--+-+--++--
|
+------++----++-+--+-+--++--
|
||||||
-+-----+++-----+-+--+-+--++-
|
-+-----+++-----+-+--+-+--++-
|
||||||
|
Loading…
Reference in New Issue
Block a user