Skip to content

Commit c2c04b3

Browse files
Albert/fix minimum and div core dump (#283)
* Fix(fix_minimum_and_div_core_dump)
1 parent 31b0a11 commit c2c04b3

6 files changed

Lines changed: 68 additions & 17 deletions

File tree

musa_ext/kernels/math/musa_minimum_op.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ using namespace tensorflow;
5454
::tensorflow::musa::MusaMinimumOp<type>);
5555

5656
REGISTER_MUSA_MIN(float);
57-
REGISTER_MUSA_MIN(double);
5857
REGISTER_MUSA_MIN(int32);
5958
REGISTER_MUSA_MIN(int64);
6059
REGISTER_MUSA_MIN(Eigen::half); // FP16

musa_ext/kernels/math/musa_multiply_op.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ class MusaMultiplyOp : public MusaOpKernel {
318318
MusaMultiplyOp<TYPE>);
319319

320320
REGISTER_MUSA_MULTIPLY(float);
321+
REGISTER_MUSA_MULTIPLY(double);
321322
REGISTER_MUSA_MULTIPLY(Eigen::half);
322323
REGISTER_MUSA_MULTIPLY(bfloat16);
323324
REGISTER_MUSA_MULTIPLY(int32);

musa_ext/kernels/math/musa_realdiv_op.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class MusaRealDivOp : public MusaOpKernel {
5656
mTensor t_out = CreateMTensor(*out, format_);
5757

5858
::musa::dnn::Binary op;
59-
op.SetMode(::musa::dnn::Binary::Mode::DIV);
59+
op.SetMode(::musa::dnn::Binary::Mode::TRUEDIV);
6060

6161
auto status = op.Run(handle, t_out, t_dividend, t_divisor);
6262
OP_REQUIRES(ctx, status == ::musa::dnn::Status::SUCCESS,

musa_ext/kernels/utils_op.cc

100755100644
Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,23 @@ mTensor CreateMTensor(const Tensor& t, mFormat format) {
7474
// Reuse TensorFlow's shape storage directly instead of copying dims into a
7575
// temporary vector. For small elementwise ops this shaves a bit of host-side
7676
// wrapper overhead.
77-
const int64_t* dims =
78-
reinterpret_cast<const int64_t*>(dims_raw.data());
77+
const int64_t* dims = reinterpret_cast<const int64_t*>(dims_raw.data());
7978

8079
if (rank >= 4) {
8180
rst.SetFormat(format);
8281
} else {
8382
rst.SetFormat(mFormat::NCHW);
8483
}
8584

86-
rst.SetNdInfo(rank, dims);
85+
// muDNN does not accept rank-0 (scalar) tensors; represent scalars as a
86+
// rank-1 [1] view so elementwise kernels such as Minimum/Multiply/Add can
87+
// still execute on MUSA instead of tripping the error path.
88+
if (rank == 0) {
89+
const int64_t one = 1;
90+
rst.SetNdInfo(1, &one);
91+
} else {
92+
rst.SetNdInfo(rank, dims);
93+
}
8794
return rst;
8895
}
8996

test/ops/multiply_op_test.py

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,30 +32,30 @@ def _test_multiply(self, shape_x, shape_y, dtype, rtol=1e-5, atol=1e-8):
3232
else:
3333
x_np = np.random.uniform(-1, 1, size=shape_x).astype(dtype.as_numpy_dtype)
3434
y_np = np.random.uniform(-1, 1, size=shape_y).astype(dtype.as_numpy_dtype)
35-
35+
3636
x = tf.constant(x_np, dtype=dtype)
3737
y = tf.constant(y_np, dtype=dtype)
38-
38+
3939
# Test on CPU
4040
with tf.device('/CPU:0'):
4141
cpu_result = tf.multiply(x, y)
42-
42+
4343
# Test on MUSA
4444
with tf.device('/device:MUSA:0'):
4545
musa_result = tf.multiply(x, y)
46-
46+
4747
# Compare results
4848
if dtype in [tf.float16, tf.bfloat16]:
4949
cpu_result_f32 = tf.cast(cpu_result, tf.float32)
5050
musa_result_f32 = tf.cast(musa_result, tf.float32)
51-
self.assertAllClose(cpu_result_f32.numpy(),
51+
self.assertAllClose(cpu_result_f32.numpy(),
5252
musa_result_f32.numpy(),
53-
rtol=rtol,
53+
rtol=rtol,
5454
atol=atol)
5555
else:
56-
self.assertAllClose(cpu_result.numpy(),
56+
self.assertAllClose(cpu_result.numpy(),
5757
musa_result.numpy(),
58-
rtol=rtol,
58+
rtol=rtol,
5959
atol=atol)
6060

6161
def testMultiplyBasic(self):
@@ -102,12 +102,12 @@ def testMultiplyZeroValues(self):
102102
y_data = [[1.0, 0.0], [0.0, 3.0]]
103103
x = tf.constant(x_data, dtype=tf.float32)
104104
y = tf.constant(y_data, dtype=tf.float32)
105-
105+
106106
expected = [[0.0, 0.0], [0.0, 0.0]]
107-
107+
108108
with tf.device('/device:MUSA:0'):
109109
result = tf.multiply(x, y)
110-
110+
111111
self.assertAllClose(result.numpy(), expected)
112112

113113

@@ -125,6 +125,19 @@ def testMultiplyFastPathHotShapes(self):
125125
with self.subTest(shape_x=shape_x, shape_y=shape_y, dtype=dtype):
126126
self._test_multiply(shape_x, shape_y, dtype, rtol=rtol, atol=atol)
127127

128+
def testMultiplyFloat64StaysOnMusa(self):
129+
x = tf.constant([2.0], dtype=tf.float64)
130+
y = tf.constant([3.0], dtype=tf.float64)
131+
132+
with tf.device('/device:MUSA:0'):
133+
result = tf.multiply(x, y)
134+
135+
self.assertIn(
136+
'MUSA', result.device,
137+
msg=f"Mul(float64) output landed on {result.device!r} instead of MUSA")
138+
self.assertEqual(result.dtype, tf.float64)
139+
self.assertAllClose(result.numpy(), [6.0], rtol=1e-12, atol=1e-12)
140+
128141

129142
if __name__ == "__main__":
130-
tf.test.main()
143+
tf.test.main()

test/ops/realdiv_op_test.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66

77
class RealDivOpTest(MUSATestCase):
88

9+
def _assert_tensor_on_musa(self, tensor, op_name):
10+
self.assertIn(
11+
'MUSA', tensor.device,
12+
msg=f"{op_name} output landed on {tensor.device!r} instead of MUSA")
13+
914
def _test_realdiv(self, shape_x, shape_y, dtype, rtol=1e-5, atol=1e-8):
1015
np_dtype = dtype.as_numpy_dtype
1116

@@ -113,6 +118,32 @@ def testRealDivLargeTensors(self):
113118
for dtype in [tf.float32]:
114119
self._test_realdiv([1024, 1024, 2], [1024, 1024, 2], dtype)
115120

121+
def testRealDivFloat64ScalarStaysOnMusa(self):
122+
with tf.device('/device:MUSA:0'):
123+
dividend = tf.constant(100.0, dtype=tf.float64)
124+
divisor = tf.constant(1000.0, dtype=tf.float64)
125+
result = tf.math.truediv(dividend, divisor)
126+
127+
self._assert_tensor_on_musa(result, 'RealDiv')
128+
self.assertEqual(result.dtype, tf.float64)
129+
self.assertEqual(result.shape.rank, 0)
130+
self.assertAllClose(result.numpy(), 0.1, rtol=1e-12, atol=1e-12)
131+
132+
def testInt64TrueDivInsideTfFunctionStaysOnMusa(self):
133+
with tf.device('/device:MUSA:0'):
134+
step = tf.Variable(100, dtype=tf.int64, name='iterations')
135+
136+
@tf.function
137+
def warmup_scale(step_var):
138+
return step_var / 1000
139+
140+
result = warmup_scale(step)
141+
142+
self._assert_tensor_on_musa(result, 'tf.function truediv')
143+
self.assertEqual(result.dtype, tf.float64)
144+
self.assertEqual(result.shape.rank, 0)
145+
self.assertAllClose(result.numpy(), 0.1, rtol=1e-12, atol=1e-12)
146+
116147

117148
if __name__ == "__main__":
118149
tf.test.main()

0 commit comments

Comments
 (0)