@@ -229,7 +229,7 @@ DEF_KERN(dt_bool, EQ, x == y); | |||||
DEF_KERN_INT(FLOOR_DIV, dispatch_floordiv_int(x, y)); | DEF_KERN_INT(FLOOR_DIV, dispatch_floordiv_int(x, y)); | ||||
DEF_KERN_FLOAT(FLOOR_DIV, floorf(x / y)); | DEF_KERN_FLOAT(FLOOR_DIV, floorf(x / y)); | ||||
DEF_KERN_INT(MOD, x % y); | |||||
DEF_KERN_INT(MOD, ((y + x % y) % y)); // consistent with python modulo | |||||
DEF_KERN_FLOAT(MOD, fmodf(x, y)); | DEF_KERN_FLOAT(MOD, fmodf(x, y)); | ||||
DEF_KERN_INT(SHL, x << y); | DEF_KERN_INT(SHL, x << y); | ||||
@@ -878,8 +878,8 @@ DEF_TEST(all_modes) { | |||||
} while (0) | } while (0) | ||||
if (trait.allow_int) { | if (trait.allow_int) { | ||||
run(dtype::Int8{}); | |||||
run(dtype::Int32{}); | run(dtype::Int32{}); | ||||
run(dtype::Int8{}); | |||||
} | } | ||||
if (trait.allow_float) { | if (trait.allow_float) { | ||||
DNN_FLOAT16_SELECT( | DNN_FLOAT16_SELECT( | ||||
@@ -280,4 +280,24 @@ TEST_F(NAIVE, ELEMWISE_QUANTIZED_MODE_TERNARY) { | |||||
} | } | ||||
} | } | ||||
TEST_F(NAIVE, ELELMWISE_INT_MODULO) { | |||||
Checker<Elemwise> checker(handle(), /* check_dispatch */ false); | |||||
Elemwise::Param param; | |||||
param.mode = Elemwise::Param::Mode::MOD; | |||||
checker.set_param(param).exect( | |||||
Testcase{ | |||||
TensorValue( | |||||
{10}, dtype::Int32(), | |||||
{10, 24, -6, -20, 10, -90, 45, 3, -1, 0}), | |||||
TensorValue( | |||||
{10}, dtype::Int32(), {3, 7, 5, -3, -6, 11, 7, -1, 8, -1}), | |||||
{}}, | |||||
Testcase{ | |||||
{}, | |||||
{}, | |||||
TensorValue( | |||||
{10}, dtype::Int32(), {1, 3, 4, -2, -2, 9, 3, 0, 7, 0})}); | |||||
} | |||||
// vim: syntax=cpp.doxygen | // vim: syntax=cpp.doxygen |
@@ -25,7 +25,7 @@ float do_mod(float a, float b) { | |||||
} | } | ||||
int do_mod(int a, int b) { | int do_mod(int a, int b) { | ||||
return a % b; | |||||
return (a % b + b) % b; | |||||
} | } | ||||
float do_floor_div(float a, float b) { | float do_floor_div(float a, float b) { | ||||