forked from mindspore-Ecosystem/mindspore
add divide op
This commit is contained in:
parent
2744bad8b9
commit
fadc97a18f
|
@ -951,5 +951,87 @@ bool Subtract(const LiteMat &src1, const LiteMat &src2, LiteMat &dst) {
|
|||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void DivideImpl(const T *src1_ptr, const T *src2_ptr, T *dst, size_t total_size) {
|
||||
for (size_t i = 0; i < total_size; i++) {
|
||||
dst[i] = src1_ptr[i] / (src2_ptr[i] + std::numeric_limits<float>::min());
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void DivideImpl(const uint8_t *src1_ptr, const uint8_t *src2_ptr, uint8_t *dst, size_t total_size) {
|
||||
for (size_t i = 0; i < total_size; i++) {
|
||||
int val = std::round(src1_ptr[i] / (src2_ptr[i] + std::numeric_limits<float>::min()));
|
||||
dst[i] =
|
||||
std::max<int>(std::numeric_limits<uint8_t>::min(), std::min<int>(std::numeric_limits<uint8_t>::max(), val));
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void DivideImpl(const uint16_t *src1_ptr, const uint16_t *src2_ptr, uint16_t *dst, size_t total_size) {
|
||||
for (size_t i = 0; i < total_size; i++) {
|
||||
int val = std::round(src1_ptr[i] / (src2_ptr[i] + std::numeric_limits<float>::min()));
|
||||
dst[i] =
|
||||
std::max<int>(std::numeric_limits<uint16_t>::min(), std::min<int>(std::numeric_limits<uint16_t>::max(), val));
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void DivideImpl(const uint32_t *src1_ptr, const uint32_t *src2_ptr, uint32_t *dst, size_t total_size) {
|
||||
for (size_t i = 0; i < total_size; i++) {
|
||||
int64_t val = std::round(src1_ptr[i] / (src2_ptr[i] + std::numeric_limits<double>::min()));
|
||||
dst[i] = std::max<int64_t>(std::numeric_limits<uint32_t>::min(),
|
||||
std::min<int64_t>(std::numeric_limits<uint32_t>::max(), val));
|
||||
}
|
||||
}
|
||||
|
||||
bool Divide(const LiteMat &src1, const LiteMat &src2, LiteMat &dst) {
|
||||
if (src1.width_ != src2.width_ || src1.height_ != src2.height_ || src1.channel_ != src2.channel_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (src1.data_type_ != src2.data_type_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dst.IsEmpty()) {
|
||||
dst.Init(src1.width_, src1.height_, src1.channel_, src1.data_type_);
|
||||
} else if (src1.width_ != dst.width_ || src1.height_ != dst.height_ || src1.channel_ != dst.channel_) {
|
||||
return false;
|
||||
} else if (src1.data_type_ != dst.data_type_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t total_size = src1.height_ * src1.width_ * src1.channel_;
|
||||
|
||||
if (src1.data_type_ == LDataType::BOOL) {
|
||||
DivideImpl<bool>(src1, src2, dst, total_size);
|
||||
} else if (src1.data_type_ == LDataType::INT8) {
|
||||
DivideImpl<int8_t>(src1, src2, dst, total_size);
|
||||
} else if (src1.data_type_ == LDataType::UINT8) {
|
||||
DivideImpl<uint8_t>(src1, src2, dst, total_size);
|
||||
} else if (src1.data_type_ == LDataType::INT16) {
|
||||
DivideImpl<int16_t>(src1, src2, dst, total_size);
|
||||
} else if (src1.data_type_ == LDataType::UINT16) {
|
||||
DivideImpl<uint16_t>(src1, src2, dst, total_size);
|
||||
} else if (src1.data_type_ == LDataType::INT32) {
|
||||
DivideImpl<int32_t>(src1, src2, dst, total_size);
|
||||
} else if (src1.data_type_ == LDataType::UINT32) {
|
||||
DivideImpl<uint32_t>(src1, src2, dst, total_size);
|
||||
} else if (src1.data_type_ == LDataType::INT64) {
|
||||
DivideImpl<int64_t>(src1, src2, dst, total_size);
|
||||
} else if (src1.data_type_ == LDataType::UINT64) {
|
||||
DivideImpl<uint64_t>(src1, src2, dst, total_size);
|
||||
} else if (src1.data_type_ == LDataType::FLOAT32) {
|
||||
DivideImpl<float>(src1, src2, dst, total_size);
|
||||
} else if (src1.data_type_ == LDataType::FLOAT64) {
|
||||
DivideImpl<double>(src1, src2, dst, total_size);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
||||
|
|
|
@ -105,6 +105,9 @@ std::vector<int> ApplyNms(const std::vector<std::vector<float>> &all_boxes, std:
|
|||
/// \brief Calculates the difference between the two images for each element
|
||||
bool Subtract(const LiteMat &src1, const LiteMat &src2, LiteMat &dst);
|
||||
|
||||
/// \brief Calculates the division between the two images for each element
|
||||
bool Divide(const LiteMat &src1, const LiteMat &src2, LiteMat &dst);
|
||||
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
||||
#endif // IMAGE_PROCESS_H_
|
||||
|
|
|
@ -583,3 +583,136 @@ TEST_F(MindDataImageProcess, TestSubtractFloat) {
|
|||
static_cast<FLOAT32_C1 *>(dst_float.data_ptr_)[i].c1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(MindDataImageProcess, TestDivideUint8) {
|
||||
const size_t cols = 4;
|
||||
// Test uint8
|
||||
LiteMat src1_uint8(1, cols);
|
||||
LiteMat src2_uint8(1, cols);
|
||||
LiteMat expect_uint8(1, cols);
|
||||
for (size_t i = 0; i < cols; i++) {
|
||||
static_cast<UINT8_C1 *>(src1_uint8.data_ptr_)[i] = 8;
|
||||
static_cast<UINT8_C1 *>(src2_uint8.data_ptr_)[i] = 4;
|
||||
static_cast<UINT8_C1 *>(expect_uint8.data_ptr_)[i] = 2;
|
||||
}
|
||||
LiteMat dst_uint8;
|
||||
EXPECT_TRUE(Divide(src1_uint8, src2_uint8, dst_uint8));
|
||||
for (size_t i = 0; i < cols; i++) {
|
||||
EXPECT_EQ(static_cast<UINT8_C1 *>(expect_uint8.data_ptr_)[i].c1,
|
||||
static_cast<UINT8_C1 *>(dst_uint8.data_ptr_)[i].c1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(MindDataImageProcess, TestDivideInt8) {
|
||||
const size_t cols = 4;
|
||||
// Test int8
|
||||
LiteMat src1_int8(1, cols, LDataType(LDataType::INT8));
|
||||
LiteMat src2_int8(1, cols, LDataType(LDataType::INT8));
|
||||
LiteMat expect_int8(1, cols, LDataType(LDataType::INT8));
|
||||
for (size_t i = 0; i < cols; i++) {
|
||||
static_cast<INT8_C1 *>(src1_int8.data_ptr_)[i] = 8;
|
||||
static_cast<INT8_C1 *>(src2_int8.data_ptr_)[i] = -4;
|
||||
static_cast<INT8_C1 *>(expect_int8.data_ptr_)[i] = -2;
|
||||
}
|
||||
LiteMat dst_int8;
|
||||
EXPECT_TRUE(Divide(src1_int8, src2_int8, dst_int8));
|
||||
for (size_t i = 0; i < cols; i++) {
|
||||
EXPECT_EQ(static_cast<INT8_C1 *>(expect_int8.data_ptr_)[i].c1,
|
||||
static_cast<INT8_C1 *>(dst_int8.data_ptr_)[i].c1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(MindDataImageProcess, TestDivideUInt16) {
|
||||
const size_t cols = 4;
|
||||
// Test uint16
|
||||
LiteMat src1_uint16(1, cols, LDataType(LDataType::UINT16));
|
||||
LiteMat src2_uint16(1, cols, LDataType(LDataType::UINT16));
|
||||
LiteMat expect_uint16(1, cols, LDataType(LDataType::UINT16));
|
||||
for (size_t i = 0; i < cols; i++) {
|
||||
static_cast<UINT16_C1 *>(src1_uint16.data_ptr_)[i] = 40000;
|
||||
static_cast<UINT16_C1 *>(src2_uint16.data_ptr_)[i] = 20000;
|
||||
static_cast<UINT16_C1 *>(expect_uint16.data_ptr_)[i] = 2;
|
||||
}
|
||||
LiteMat dst_uint16;
|
||||
EXPECT_TRUE(Divide(src1_uint16, src2_uint16, dst_uint16));
|
||||
for (size_t i = 0; i < cols; i++) {
|
||||
EXPECT_EQ(static_cast<UINT16_C1 *>(expect_uint16.data_ptr_)[i].c1,
|
||||
static_cast<UINT16_C1 *>(dst_uint16.data_ptr_)[i].c1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(MindDataImageProcess, TestDivideInt16) {
|
||||
const size_t cols = 4;
|
||||
// Test int16
|
||||
LiteMat src1_int16(1, cols, LDataType(LDataType::INT16));
|
||||
LiteMat src2_int16(1, cols, LDataType(LDataType::INT16));
|
||||
LiteMat expect_int16(1, cols, LDataType(LDataType::INT16));
|
||||
for (size_t i = 0; i < cols; i++) {
|
||||
static_cast<INT16_C1 *>(src1_int16.data_ptr_)[i] = 30000;
|
||||
static_cast<INT16_C1 *>(src2_int16.data_ptr_)[i] = -3;
|
||||
static_cast<INT16_C1 *>(expect_int16.data_ptr_)[i] = -10000;
|
||||
}
|
||||
LiteMat dst_int16;
|
||||
EXPECT_TRUE(Divide(src1_int16, src2_int16, dst_int16));
|
||||
for (size_t i = 0; i < cols; i++) {
|
||||
EXPECT_EQ(static_cast<INT16_C1 *>(expect_int16.data_ptr_)[i].c1,
|
||||
static_cast<INT16_C1 *>(dst_int16.data_ptr_)[i].c1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(MindDataImageProcess, TestDivideUInt32) {
|
||||
const size_t cols = 4;
|
||||
// Test uint16
|
||||
LiteMat src1_uint32(1, cols, LDataType(LDataType::UINT32));
|
||||
LiteMat src2_uint32(1, cols, LDataType(LDataType::UINT32));
|
||||
LiteMat expect_uint32(1, cols, LDataType(LDataType::UINT32));
|
||||
for (size_t i = 0; i < cols; i++) {
|
||||
static_cast<UINT32_C1 *>(src1_uint32.data_ptr_)[i] = 4000000000;
|
||||
static_cast<UINT32_C1 *>(src2_uint32.data_ptr_)[i] = 4;
|
||||
static_cast<UINT32_C1 *>(expect_uint32.data_ptr_)[i] = 1000000000;
|
||||
}
|
||||
LiteMat dst_uint32;
|
||||
EXPECT_TRUE(Divide(src1_uint32, src2_uint32, dst_uint32));
|
||||
for (size_t i = 0; i < cols; i++) {
|
||||
EXPECT_EQ(static_cast<UINT32_C1 *>(expect_uint32.data_ptr_)[i].c1,
|
||||
static_cast<UINT32_C1 *>(dst_uint32.data_ptr_)[i].c1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(MindDataImageProcess, TestDivideInt32) {
|
||||
const size_t cols = 4;
|
||||
// Test int32
|
||||
LiteMat src1_int32(1, cols, LDataType(LDataType::INT32));
|
||||
LiteMat src2_int32(1, cols, LDataType(LDataType::INT32));
|
||||
LiteMat expect_int32(1, cols, LDataType(LDataType::INT32));
|
||||
for (size_t i = 0; i < cols; i++) {
|
||||
static_cast<INT32_C1 *>(src1_int32.data_ptr_)[i] = 2000000000;
|
||||
static_cast<INT32_C1 *>(src2_int32.data_ptr_)[i] = -2;
|
||||
static_cast<INT32_C1 *>(expect_int32.data_ptr_)[i] = -1000000000;
|
||||
}
|
||||
LiteMat dst_int32;
|
||||
EXPECT_TRUE(Divide(src1_int32, src2_int32, dst_int32));
|
||||
for (size_t i = 0; i < cols; i++) {
|
||||
EXPECT_EQ(static_cast<INT32_C1 *>(expect_int32.data_ptr_)[i].c1,
|
||||
static_cast<INT32_C1 *>(dst_int32.data_ptr_)[i].c1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(MindDataImageProcess, TestDivideFloat) {
|
||||
const size_t cols = 4;
|
||||
// Test float
|
||||
LiteMat src1_float(1, cols, LDataType(LDataType::FLOAT32));
|
||||
LiteMat src2_float(1, cols, LDataType(LDataType::FLOAT32));
|
||||
LiteMat expect_float(1, cols, LDataType(LDataType::FLOAT32));
|
||||
for (size_t i = 0; i < cols; i++) {
|
||||
static_cast<FLOAT32_C1 *>(src1_float.data_ptr_)[i] = 12.34f;
|
||||
static_cast<FLOAT32_C1 *>(src2_float.data_ptr_)[i] = -2.0f;
|
||||
static_cast<FLOAT32_C1 *>(expect_float.data_ptr_)[i] = -6.17f;
|
||||
}
|
||||
LiteMat dst_float;
|
||||
EXPECT_TRUE(Divide(src1_float, src2_float, dst_float));
|
||||
for (size_t i = 0; i < cols; i++) {
|
||||
EXPECT_FLOAT_EQ(static_cast<FLOAT32_C1 *>(expect_float.data_ptr_)[i].c1,
|
||||
static_cast<FLOAT32_C1 *>(dst_float.data_ptr_)[i].c1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue