mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-25 19:48:11 +00:00
parent
360fc32db4
commit
aac711ab2f
5 changed files with 297 additions and 3 deletions
|
|
@ -236,6 +236,7 @@ class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain,
|
|||
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, EyeLike);
|
||||
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, float, IsNaN);
|
||||
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, MLFloat16, IsNaN);
|
||||
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, Sign);
|
||||
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, Erf);
|
||||
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, int64_t_int64_t_int64_t, OneHot);
|
||||
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, float_int64_t_int64_t, OneHot);
|
||||
|
|
@ -459,7 +460,7 @@ void RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) {
|
|||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, Unsqueeze)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 7, 9, float, Upsample)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 7, 9, int32_t, Upsample)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 7, 9, uint8_t, Upsample)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 7, 9, uint8_t, Upsample)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 8, float, Expand)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 8, double, Expand)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 8, int8_t, Expand)>());
|
||||
|
|
@ -486,6 +487,7 @@ void RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) {
|
|||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, EyeLike)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, float, IsNaN)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, MLFloat16, IsNaN)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, Sign)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, Erf)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, int64_t_int64_t_int64_t, OneHot)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, float_int64_t_int64_t, OneHot)>());
|
||||
|
|
|
|||
112
onnxruntime/core/providers/cpu/math/sign.cc
Normal file
112
onnxruntime/core/providers/cpu/math/sign.cc
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "core/common/common.h"
|
||||
#include "core/framework/data_types.h"
|
||||
#include "core/framework/op_kernel.h"
|
||||
#include "core/util/math.h"
|
||||
#include "core/util/math_cpuonly.h"
|
||||
|
||||
#include "gsl/span"
|
||||
#include <type_traits>
|
||||
|
||||
using namespace ::onnxruntime::common;
|
||||
using namespace ONNX_NAMESPACE;
|
||||
namespace onnxruntime {
|
||||
|
||||
class Sign final : public OpKernel {
|
||||
public:
|
||||
explicit Sign(const OpKernelInfo& info) : OpKernel(info) {}
|
||||
|
||||
Status Compute(OpKernelContext* ctx) const override;
|
||||
};
|
||||
|
||||
ONNX_CPU_OPERATOR_KERNEL(
|
||||
Sign,
|
||||
9,
|
||||
KernelDefBuilder().TypeConstraint("T", {DataTypeImpl::GetTensorType<float>(),
|
||||
DataTypeImpl::GetTensorType<double>(),
|
||||
DataTypeImpl::GetTensorType<int64_t>(),
|
||||
DataTypeImpl::GetTensorType<uint64_t>(),
|
||||
DataTypeImpl::GetTensorType<int32_t>(),
|
||||
DataTypeImpl::GetTensorType<uint32_t>(),
|
||||
DataTypeImpl::GetTensorType<int16_t>(),
|
||||
DataTypeImpl::GetTensorType<uint16_t>(),
|
||||
DataTypeImpl::GetTensorType<int8_t>(),
|
||||
DataTypeImpl::GetTensorType<uint8_t>(),
|
||||
DataTypeImpl::GetTensorType<MLFloat16>(),
|
||||
DataTypeImpl::GetTensorType<BFloat16>()}),
|
||||
Sign);
|
||||
|
||||
namespace sign_internal {
|
||||
// The spec does not specify how NaN is
|
||||
// treated but we have to treat it somehow. We choose
|
||||
// to return 0 for NaN as TF does.
|
||||
template <class T>
|
||||
inline T FloatingImpl(T val) {
|
||||
if (std::isnan(val) || val == T(0)) {
|
||||
return T(0);
|
||||
} else if (val > T(0)) {
|
||||
return T(1);
|
||||
} else {
|
||||
return T(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void SignMLFloat16(const Tensor* input, Tensor* output) {
|
||||
auto span = gsl::make_span(input->Data<MLFloat16>(), input->Shape().Size());
|
||||
auto output_data = output->template MutableData<MLFloat16>();
|
||||
std::transform(span.cbegin(), span.cend(), output_data, [](const MLFloat16& val) {
|
||||
float fl = math::halfToFloat(val.val);
|
||||
return MLFloat16(math::floatToHalf(FloatingImpl(fl)));
|
||||
});
|
||||
}
|
||||
|
||||
void SignBFloat16(const Tensor* input, Tensor* output) {
|
||||
auto span = gsl::make_span(input->Data<BFloat16>(), input->Shape().Size());
|
||||
auto output_data = output->template MutableData<BFloat16>();
|
||||
std::transform(span.cbegin(), span.cend(), output_data, [](const BFloat16& val) {
|
||||
float fl = val.ToFloat();
|
||||
return BFloat16(FloatingImpl(fl));
|
||||
});
|
||||
}
|
||||
} // namespace sign_internal
|
||||
|
||||
Status Sign::Compute(OpKernelContext* ctx) const {
|
||||
using namespace sign_internal;
|
||||
|
||||
auto input = ctx->Input<Tensor>(0);
|
||||
auto output = ctx->Output(0, input->Shape());
|
||||
|
||||
auto dtype = input->DataType();
|
||||
if (dtype == DataTypeImpl::GetType<float>()) {
|
||||
EigenMap<float>(*output) = EigenMap<float>(*input).array().cwiseSign();
|
||||
} else if (dtype == DataTypeImpl::GetType<double>()) {
|
||||
EigenMap<double>(*output) = EigenMap<double>(*input).array().cwiseSign();
|
||||
} else if (dtype == DataTypeImpl::GetType<int8_t>()) {
|
||||
EigenMap<int8_t>(*output) = EigenMap<int8_t>(*input).array().cwiseSign();
|
||||
} else if (dtype == DataTypeImpl::GetType<int16_t>()) {
|
||||
EigenMap<int16_t>(*output) = EigenMap<int16_t>(*input).array().cwiseSign();
|
||||
} else if (dtype == DataTypeImpl::GetType<int32_t>()) {
|
||||
EigenMap<int32_t>(*output) = EigenMap<int32_t>(*input).array().cwiseSign();
|
||||
} else if (dtype == DataTypeImpl::GetType<int64_t>()) {
|
||||
EigenMap<int64_t>(*output) = EigenMap<int64_t>(*input).array().cwiseSign();
|
||||
} else if (dtype == DataTypeImpl::GetType<uint8_t>()) {
|
||||
EigenMap<uint8_t>(*output) = EigenMap<uint8_t>(*input).array().cwiseSign();
|
||||
} else if (dtype == DataTypeImpl::GetType<uint16_t>()) {
|
||||
EigenMap<uint16_t>(*output) = EigenMap<uint16_t>(*input).array().cwiseSign();
|
||||
} else if (dtype == DataTypeImpl::GetType<uint32_t>()) {
|
||||
EigenMap<uint32_t>(*output) = EigenMap<uint32_t>(*input).array().cwiseSign();
|
||||
} else if (dtype == DataTypeImpl::GetType<uint64_t>()) {
|
||||
EigenMap<uint64_t>(*output) = EigenMap<uint64_t>(*input).array().cwiseSign();
|
||||
} else if (dtype == DataTypeImpl::GetType<MLFloat16>()) {
|
||||
SignMLFloat16(input, output);
|
||||
} else if (dtype == DataTypeImpl::GetType<BFloat16>()) {
|
||||
SignBFloat16(input, output);
|
||||
} else {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "Unsupported input datatype");
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
} // namespace onnxruntime
|
||||
|
|
@ -309,7 +309,6 @@ int real_main(int argc, char* argv[]) {
|
|||
{"acosh_example", "opset 9 not supported yet"},
|
||||
{"atanh_example", "opset 9 not supported yet"},
|
||||
{"sign_model", "opset 9 not supported yet"},
|
||||
{"sign", "opset 9 not supported yet"},
|
||||
{"scatter_with_axis", "opset 9 not supported yet"},
|
||||
{"scatter_without_axis", "opset 9 not supported yet"},
|
||||
{"scan_sum", "opset 9 not supported yet"},
|
||||
|
|
|
|||
182
onnxruntime/test/providers/cpu/math/sing_test.cc
Normal file
182
onnxruntime/test/providers/cpu/math/sing_test.cc
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "test/providers/provider_test_utils.h"
|
||||
#include "core/util/math.h"
|
||||
|
||||
namespace onnxruntime {
|
||||
namespace test {
|
||||
|
||||
namespace test_sign_internal {
|
||||
|
||||
template <class T, class A>
|
||||
struct make_type {
|
||||
static T make(A v) {
|
||||
return T(v);
|
||||
}
|
||||
};
|
||||
|
||||
template <class A>
|
||||
struct make_type<MLFloat16, A> {
|
||||
static MLFloat16 make(A v) {
|
||||
return MLFloat16(math::floatToHalf(float(v)));
|
||||
}
|
||||
};
|
||||
|
||||
template <class A>
|
||||
struct make_type<BFloat16, A> {
|
||||
static BFloat16 make(A v) {
|
||||
return BFloat16(float(v));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class OutputIter>
|
||||
typename std::enable_if<!std::numeric_limits<T>::is_signed>::type
|
||||
GenerateSequence(OutputIter out) {
|
||||
for (int i = 0; i < 7; ++i) {
|
||||
*out = make_type<T, int>::make(i);
|
||||
++out;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class OutputIter>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_signed>::type
|
||||
GenerateSequence(OutputIter out) {
|
||||
for (int i = -5; i < 2; ++i) {
|
||||
*out = make_type<T, int>::make(i);
|
||||
++out;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline auto to_testable_type(T v) {
|
||||
return v;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline auto to_testable_type(MLFloat16 v) {
|
||||
return math::halfToFloat(v.val);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline auto to_testable_type(BFloat16 v) {
|
||||
return v.ToFloat();
|
||||
}
|
||||
|
||||
template <class T, class ForwardIter, class OutputIter>
|
||||
typename std::enable_if<!std::numeric_limits<T>::is_signed &&
|
||||
!std::is_same<T, MLFloat16>::value &&
|
||||
!std::is_same<T, BFloat16>::value>::type
|
||||
TestImpl(ForwardIter first, ForwardIter last, OutputIter out) {
|
||||
std::transform(first, last, out, [](T v) {
|
||||
auto t = to_testable_type<T>(v);
|
||||
if (t == 0) {
|
||||
t = 0;
|
||||
} else {
|
||||
t = 1;
|
||||
}
|
||||
return make_type<T, decltype(t)>::make(t);
|
||||
});
|
||||
}
|
||||
|
||||
template <class T, class ForwardIter, class OutputIter>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_signed ||
|
||||
std::is_same<T, MLFloat16>::value ||
|
||||
std::is_same<T, BFloat16>::value>::type
|
||||
TestImpl(ForwardIter first, ForwardIter last, OutputIter out) {
|
||||
std::transform(first, last, out, [](T v) {
|
||||
auto t = to_testable_type<T>(v);
|
||||
if (t == 0) {
|
||||
t = 0;
|
||||
} else if (t > 0) {
|
||||
t = 1;
|
||||
} else {
|
||||
t = -1;
|
||||
}
|
||||
return make_type<T, decltype(t)>::make(t);
|
||||
});
|
||||
}
|
||||
} // namespace test_sign_internal
|
||||
|
||||
TEST(MathOpTest, Sign_uint64) {
|
||||
using namespace test_sign_internal;
|
||||
OpTester test("Sign", 9);
|
||||
|
||||
std::vector<int64_t> input_dims{7};
|
||||
std::vector<uint64_t> input;
|
||||
GenerateSequence<uint64_t>(std::back_inserter(input));
|
||||
ASSERT_EQ(input.size(), 7U);
|
||||
test.AddInput<uint64_t>("input", input_dims, input);
|
||||
|
||||
std::vector<uint64_t> output;
|
||||
TestImpl<uint64_t>(input.cbegin(), input.cend(), std::back_inserter(output));
|
||||
test.AddOutput<uint64_t>("output", input_dims, output);
|
||||
test.Run(OpTester::ExpectResult::kExpectSuccess);
|
||||
}
|
||||
|
||||
TEST(MathOpTest, Sign_int64) {
|
||||
using namespace test_sign_internal;
|
||||
OpTester test("Sign", 9);
|
||||
|
||||
std::vector<int64_t> input_dims{7};
|
||||
std::vector<int64_t> input;
|
||||
GenerateSequence<int64_t>(std::back_inserter(input));
|
||||
ASSERT_EQ(input.size(), 7U);
|
||||
test.AddInput<int64_t>("input", input_dims, input);
|
||||
|
||||
std::vector<int64_t> output;
|
||||
TestImpl<int64_t>(input.cbegin(), input.cend(), std::back_inserter(output));
|
||||
test.AddOutput<int64_t>("output", input_dims, output);
|
||||
test.Run(OpTester::ExpectResult::kExpectSuccess);
|
||||
}
|
||||
|
||||
TEST(MathOpTest, Sign_float) {
|
||||
using namespace test_sign_internal;
|
||||
OpTester test("Sign", 9);
|
||||
|
||||
std::vector<int64_t> input_dims{7};
|
||||
std::vector<float> input;
|
||||
GenerateSequence<float>(std::back_inserter(input));
|
||||
ASSERT_EQ(input.size(), 7U);
|
||||
test.AddInput<float>("input", input_dims, input);
|
||||
|
||||
std::vector<float> output;
|
||||
TestImpl<float>(input.cbegin(), input.cend(), std::back_inserter(output));
|
||||
test.AddOutput<float>("output", input_dims, output);
|
||||
test.Run(OpTester::ExpectResult::kExpectSuccess);
|
||||
}
|
||||
|
||||
TEST(MathOpTest, Sign_double) {
|
||||
using namespace test_sign_internal;
|
||||
OpTester test("Sign", 9);
|
||||
|
||||
std::vector<int64_t> input_dims{7};
|
||||
std::vector<double> input;
|
||||
GenerateSequence<double>(std::back_inserter(input));
|
||||
ASSERT_EQ(input.size(), 7U);
|
||||
test.AddInput<double>("input", input_dims, input);
|
||||
|
||||
std::vector<double> output;
|
||||
TestImpl<double>(input.cbegin(), input.cend(), std::back_inserter(output));
|
||||
test.AddOutput<double>("output", input_dims, output);
|
||||
test.Run(OpTester::ExpectResult::kExpectSuccess);
|
||||
}
|
||||
TEST(MathOpTest, Sign_MLFloat16) {
|
||||
using namespace test_sign_internal;
|
||||
OpTester test("Sign", 9);
|
||||
|
||||
std::vector<int64_t> input_dims{7};
|
||||
std::vector<MLFloat16> input;
|
||||
GenerateSequence<MLFloat16>(std::back_inserter(input));
|
||||
ASSERT_EQ(input.size(), 7U);
|
||||
test.AddInput<MLFloat16>("input", input_dims, input);
|
||||
|
||||
std::vector<MLFloat16> output;
|
||||
TestImpl<MLFloat16>(input.cbegin(), input.cend(), std::back_inserter(output));
|
||||
test.AddOutput<MLFloat16>("output", input_dims, output);
|
||||
test.Run(OpTester::ExpectResult::kExpectSuccess);
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace onnxruntime
|
||||
|
|
@ -31,7 +31,6 @@ backend_test.exclude(r'('
|
|||
'|^test_scatter_without_axis_cpu.*'
|
||||
'|^test_shrink_hard_cpu.*'
|
||||
'|^test_shrink_soft_cpu.*'
|
||||
'|^test_sign_cpu.*'
|
||||
'|^test_where_example_cpu.*'
|
||||
'|^test_AvgPool1d_cpu.*'
|
||||
'|^test_AvgPool1d_stride_cpu.*'
|
||||
|
|
|
|||
Loading…
Reference in a new issue