mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-29 20:14:01 +00:00
Support opset-11 Range CPU kernel (#1980)
* Initial commit * Update * Update * Update * Add tests to MKLDNN exclsuion * Update * PR feedback * Revert
This commit is contained in:
parent
a7414287a9
commit
534660bf2c
7 changed files with 198 additions and 229 deletions
|
|
@ -1,90 +0,0 @@
|
|||
#include "range.h"
|
||||
#include "onnx/defs/schema.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace onnxruntime {
|
||||
namespace contrib {
|
||||
|
||||
template <typename T>
|
||||
static Status ComputeRange(OpKernelContext* ctx) {
|
||||
auto& start_tensor = *ctx->Input<Tensor>(0);
|
||||
auto& limit_tensor = *ctx->Input<Tensor>(1);
|
||||
auto delta_tensor_ptr = ctx->Input<Tensor>(2);
|
||||
|
||||
if (!start_tensor.Shape().IsScalar()) {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT,
|
||||
"start in Range operator should be scalar like tensor, yet got shape:",
|
||||
start_tensor.Shape());
|
||||
}
|
||||
if (!limit_tensor.Shape().IsScalar()) {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT,
|
||||
"limit in Range operator should be scalar like tensor, yet got shape:",
|
||||
limit_tensor.Shape());
|
||||
}
|
||||
if (delta_tensor_ptr != nullptr && !delta_tensor_ptr->Shape().IsScalar()) {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT,
|
||||
"delta in Range operator should be scalar like tensor, yet got shape:",
|
||||
delta_tensor_ptr->Shape());
|
||||
}
|
||||
|
||||
T start = *start_tensor.template Data<T>();
|
||||
T limit = *limit_tensor.template Data<T>();
|
||||
T delta = (delta_tensor_ptr == nullptr) ? T{1} : *(delta_tensor_ptr->template Data<T>());
|
||||
|
||||
if (delta == T{0}) {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "delta in Range operator can not be zero!");
|
||||
}
|
||||
int64_t n = static_cast<int64_t>(ceil((1.0 * (limit - start)) / delta));
|
||||
if (n <= 0) n = 0;
|
||||
TensorShape shape = {n};
|
||||
T* y = ctx->Output(0, shape)->template MutableData<T>();
|
||||
for (int64_t i = 0; i < n; ++i) {
|
||||
*y++ = start;
|
||||
start += delta;
|
||||
}
|
||||
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status Range::Compute(OpKernelContext* ctx) const {
|
||||
auto input_tensor = ctx->Input<Tensor>(0);
|
||||
if (input_tensor == nullptr) return Status(common::ONNXRUNTIME, common::FAIL, "input count mismatch");
|
||||
auto data_type = input_tensor->DataType();
|
||||
if (data_type == DataTypeImpl::GetType<int32_t>()) {
|
||||
return ComputeRange<int32_t>(ctx);
|
||||
}
|
||||
else if (data_type == DataTypeImpl::GetType<int16_t>()) {
|
||||
return ComputeRange<int16_t>(ctx);
|
||||
}
|
||||
else if (data_type == DataTypeImpl::GetType<int64_t>()) {
|
||||
return ComputeRange<int64_t>(ctx);
|
||||
}
|
||||
else if (data_type == DataTypeImpl::GetType<float>()) {
|
||||
return ComputeRange<float>(ctx);
|
||||
}
|
||||
else if (data_type == DataTypeImpl::GetType<double>()) {
|
||||
return ComputeRange<double>(ctx);
|
||||
}
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT,
|
||||
"Unsupportted tensor data type:",
|
||||
data_type);
|
||||
}
|
||||
|
||||
/* Range operator */
|
||||
ONNX_OPERATOR_KERNEL_EX(
|
||||
Range, //name
|
||||
kMSDomain,
|
||||
1,
|
||||
kCpuExecutionProvider,
|
||||
KernelDefBuilder().TypeConstraint("T", {
|
||||
DataTypeImpl::GetTensorType<float>(),
|
||||
DataTypeImpl::GetTensorType<double>(),
|
||||
DataTypeImpl::GetTensorType<int16_t>(),
|
||||
DataTypeImpl::GetTensorType<int32_t>(),
|
||||
DataTypeImpl::GetTensorType<int64_t>()}),
|
||||
Range);
|
||||
|
||||
|
||||
} // namespace contrib
|
||||
} // namespace onnxruntime
|
||||
|
|
@ -394,6 +394,7 @@ class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, Ge
|
|||
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, GatherElements);
|
||||
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, Pad);
|
||||
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, GatherND);
|
||||
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, Range);
|
||||
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, Unique);
|
||||
|
||||
void RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) {
|
||||
|
|
@ -1011,6 +1012,7 @@ void RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) {
|
|||
BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, GatherElements)>,
|
||||
BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, Pad)>,
|
||||
BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, GatherND)>,
|
||||
BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, Range)>,
|
||||
BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, Unique)>};
|
||||
|
||||
for (auto& function_table_entry : function_table) {
|
||||
|
|
|
|||
103
onnxruntime/core/providers/cpu/generator/range.cc
Normal file
103
onnxruntime/core/providers/cpu/generator/range.cc
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
#include "range.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace onnxruntime {
|
||||
|
||||
// Register a kernel for kMsDomain (contrib op) Range
|
||||
#ifndef DISABLE_CONTRIB_OPS
|
||||
|
||||
namespace contrib {
|
||||
// TODO: Remove this contrib kernel registration and the schema from the appropriate places
|
||||
// once Keras Mask RCNN is shipped with all ONNX domain ops
|
||||
|
||||
// Currently this kernel is required to support Keras Mask-RCNN
|
||||
ONNX_OPERATOR_KERNEL_EX(
|
||||
Range, //name
|
||||
kMSDomain,
|
||||
1,
|
||||
kCpuExecutionProvider,
|
||||
KernelDefBuilder().TypeConstraint("T", {DataTypeImpl::GetTensorType<float>(),
|
||||
DataTypeImpl::GetTensorType<double>(),
|
||||
DataTypeImpl::GetTensorType<int16_t>(),
|
||||
DataTypeImpl::GetTensorType<int32_t>(),
|
||||
DataTypeImpl::GetTensorType<int64_t>()}),
|
||||
Range);
|
||||
|
||||
} // namespace contrib
|
||||
|
||||
#endif
|
||||
|
||||
ONNX_CPU_OPERATOR_KERNEL(
|
||||
Range,
|
||||
11,
|
||||
KernelDefBuilder().TypeConstraint("T", {DataTypeImpl::GetTensorType<float>(),
|
||||
DataTypeImpl::GetTensorType<double>(),
|
||||
DataTypeImpl::GetTensorType<int16_t>(),
|
||||
DataTypeImpl::GetTensorType<int32_t>(),
|
||||
DataTypeImpl::GetTensorType<int64_t>()}),
|
||||
Range);
|
||||
|
||||
template <typename T>
|
||||
static Status ComputeRange(OpKernelContext* ctx) {
|
||||
const auto& start_tensor = *ctx->Input<Tensor>(0);
|
||||
const auto& limit_tensor = *ctx->Input<Tensor>(1);
|
||||
const auto* delta_tensor_ptr = ctx->Input<Tensor>(2);
|
||||
|
||||
if (!start_tensor.Shape().IsScalar()) {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT,
|
||||
"start in Range operator should be scalar like tensor, yet got shape:",
|
||||
start_tensor.Shape());
|
||||
}
|
||||
if (!limit_tensor.Shape().IsScalar()) {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT,
|
||||
"limit in Range operator should be scalar like tensor, yet got shape:",
|
||||
limit_tensor.Shape());
|
||||
}
|
||||
if (delta_tensor_ptr != nullptr && !delta_tensor_ptr->Shape().IsScalar()) {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT,
|
||||
"delta in Range operator should be scalar like tensor, yet got shape:",
|
||||
delta_tensor_ptr->Shape());
|
||||
}
|
||||
|
||||
T start = *start_tensor.template Data<T>();
|
||||
T limit = *limit_tensor.template Data<T>();
|
||||
T delta = (delta_tensor_ptr == nullptr) ? T{1} : *(delta_tensor_ptr->template Data<T>());
|
||||
|
||||
if (delta == T{0}) {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "delta in Range operator can not be zero!");
|
||||
}
|
||||
int64_t n = static_cast<int64_t>(ceil((1.0 * (limit - start)) / delta));
|
||||
if (n <= 0)
|
||||
n = 0;
|
||||
TensorShape shape = {n};
|
||||
T* y = ctx->Output(0, shape)->template MutableData<T>();
|
||||
for (int64_t i = 0; i < n; ++i) {
|
||||
*y++ = start;
|
||||
start += delta;
|
||||
}
|
||||
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status Range::Compute(OpKernelContext* ctx) const {
|
||||
const auto* input_tensor = ctx->Input<Tensor>(0);
|
||||
if (input_tensor == nullptr) return Status(common::ONNXRUNTIME, common::FAIL, "input count mismatch");
|
||||
auto data_type = input_tensor->DataType();
|
||||
if (data_type == DataTypeImpl::GetType<int32_t>()) {
|
||||
return ComputeRange<int32_t>(ctx);
|
||||
} else if (data_type == DataTypeImpl::GetType<float>()) {
|
||||
return ComputeRange<float>(ctx);
|
||||
} else if (data_type == DataTypeImpl::GetType<int64_t>()) {
|
||||
return ComputeRange<int64_t>(ctx);
|
||||
} else if (data_type == DataTypeImpl::GetType<double>()) {
|
||||
return ComputeRange<double>(ctx);
|
||||
} else if (data_type == DataTypeImpl::GetType<int16_t>()) {
|
||||
return ComputeRange<int16_t>(ctx);
|
||||
}
|
||||
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT,
|
||||
"Range op: Unsupported tensor data type:", data_type);
|
||||
}
|
||||
|
||||
} // namespace onnxruntime
|
||||
|
|
@ -8,7 +8,6 @@
|
|||
#include "core/framework/tensor.h"
|
||||
|
||||
namespace onnxruntime {
|
||||
namespace contrib {
|
||||
|
||||
class Range : public OpKernel {
|
||||
public:
|
||||
|
|
@ -17,5 +16,4 @@ class Range : public OpKernel {
|
|||
Status Compute(OpKernelContext* context) const override;
|
||||
};
|
||||
|
||||
} // namespace contrib
|
||||
} // namespace onnxruntime
|
||||
|
|
@ -1,133 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "test/providers/provider_test_utils.h"
|
||||
|
||||
namespace onnxruntime {
|
||||
namespace test {
|
||||
|
||||
TEST(RangeTest, PositiveInt32DeltaDefault) {
|
||||
OpTester test("Range", 1, onnxruntime::kMSDomain);
|
||||
std::vector<int32_t> start = {0};
|
||||
std::vector<int32_t> limit = {5};
|
||||
std::vector<int32_t> expected_output = {0, 1, 2, 3, 4};
|
||||
|
||||
test.AddInput<int32_t>("start", {1}, start);
|
||||
test.AddInput<int32_t>("limit", {1}, limit);
|
||||
test.AddOutput<int32_t>("Y", {5LL}, expected_output);
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(RangeTest, PositiveInt32Delta_0) {
|
||||
OpTester test("Range", 1, onnxruntime::kMSDomain);
|
||||
std::vector<int32_t> start = {0};
|
||||
std::vector<int32_t> limit = {10};
|
||||
std::vector<int32_t> delta = {2};
|
||||
std::vector<int32_t> expected_output = {0, 2, 4, 6, 8};
|
||||
|
||||
test.AddInput<int32_t>("start", {1}, start);
|
||||
test.AddInput<int32_t>("limit", {1}, limit);
|
||||
test.AddInput<int32_t>("delta", {1}, delta);
|
||||
test.AddOutput<int32_t>("Y", {5LL}, expected_output);
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(RangeTest, PositiveInt32Delta_1) {
|
||||
OpTester test("Range", 1, onnxruntime::kMSDomain);
|
||||
std::vector<int32_t> start = {0};
|
||||
std::vector<int32_t> limit = {9};
|
||||
std::vector<int32_t> delta = {2};
|
||||
std::vector<int32_t> expected_output = {0, 2, 4, 6, 8};
|
||||
|
||||
test.AddInput<int32_t>("start", {1}, start);
|
||||
test.AddInput<int32_t>("limit", {1}, limit);
|
||||
test.AddInput<int32_t>("delta", {1}, delta);
|
||||
test.AddOutput<int32_t>("Y", {5LL}, expected_output);
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(RangeTest, PositiveInt32Delta_2) {
|
||||
OpTester test("Range", 1, onnxruntime::kMSDomain);
|
||||
std::vector<int32_t> start = {1};
|
||||
std::vector<int32_t> limit = {2};
|
||||
std::vector<int32_t> delta = {2};
|
||||
std::vector<int32_t> expected_output = {1};
|
||||
|
||||
test.AddInput<int32_t>("start", {1}, start);
|
||||
test.AddInput<int32_t>("limit", {1}, limit);
|
||||
test.AddInput<int32_t>("delta", {1}, delta);
|
||||
test.AddOutput<int32_t>("Y", {1LL}, expected_output);
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(RangeTest, Int32ScalarNegativeDelta_0) {
|
||||
OpTester test("Range", 1, onnxruntime::kMSDomain);
|
||||
std::vector<int32_t> start = {2};
|
||||
std::vector<int32_t> limit = {-9};
|
||||
std::vector<int32_t> delta = {-2};
|
||||
std::vector<int32_t> expected_output = {2, 0, -2, -4, -6, -8};
|
||||
|
||||
test.AddInput<int32_t>("start", {}, start);
|
||||
test.AddInput<int32_t>("limit", {}, limit);
|
||||
test.AddInput<int32_t>("delta", {}, delta);
|
||||
test.AddOutput<int32_t>("Y", {6LL}, expected_output);
|
||||
test.Run();
|
||||
}
|
||||
|
||||
|
||||
TEST(RangeTest, Int32ScalarNegativeDelta_1) {
|
||||
OpTester test("Range", 1, onnxruntime::kMSDomain);
|
||||
std::vector<int32_t> start = {2};
|
||||
std::vector<int32_t> limit = {9};
|
||||
std::vector<int32_t> delta = {-2};
|
||||
std::vector<int32_t> expected_output = {};
|
||||
|
||||
test.AddInput<int32_t>("start", {}, start);
|
||||
test.AddInput<int32_t>("limit", {}, limit);
|
||||
test.AddInput<int32_t>("delta", {}, delta);
|
||||
test.AddOutput<int32_t>("Y", {0}, expected_output);
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(RangeTest, ScalarFloatNegativeDelta) {
|
||||
OpTester test("Range", 1, onnxruntime::kMSDomain);
|
||||
std::vector<float> start = {2.0f};
|
||||
std::vector<float> limit = {-8.1f};
|
||||
std::vector<float> delta = {-2.0f};
|
||||
std::vector<float> expected_output = {2.0f, 0.0f, -2.0f, -4.0f, -6.0f, -8.0f};
|
||||
|
||||
test.AddInput<float>("start", {}, start);
|
||||
test.AddInput<float>("limit", {}, limit);
|
||||
test.AddInput<float>("delta", {}, delta);
|
||||
test.AddOutput<float>("Y", {6LL}, expected_output);
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(RangeTest, SameStartAndLimit) {
|
||||
OpTester test("Range", 1, onnxruntime::kMSDomain);
|
||||
std::vector<float> start = {2.0f};
|
||||
std::vector<float> limit = {2.0f};
|
||||
std::vector<float> expected_output = {};
|
||||
|
||||
test.AddInput<float>("start", {}, start);
|
||||
test.AddInput<float>("limit", {}, limit);
|
||||
test.AddOutput<float>("Y", {0}, expected_output);
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(RangeTest, AlmostSameStartAndLimitHighDelta) {
|
||||
OpTester test("Range", 1, onnxruntime::kMSDomain);
|
||||
std::vector<float> start = {2.0f};
|
||||
std::vector<float> limit = {2.01f};
|
||||
std::vector<float> delta = {1000000.0f};
|
||||
std::vector<float> expected_output = {2.0f};
|
||||
|
||||
test.AddInput<float>("start", {}, start);
|
||||
test.AddInput<float>("limit", {}, limit);
|
||||
test.AddInput<float>("delta", {}, delta);
|
||||
test.AddOutput<float>("Y", {1}, expected_output);
|
||||
test.Run();
|
||||
}
|
||||
} // namespace test
|
||||
} // namespace onnxruntime
|
||||
|
|
@ -394,10 +394,6 @@ int real_main(int argc, char* argv[], Ort::Env& env) {
|
|||
{"top_k_negative_axis", "TopK(11) not implemented yet"},
|
||||
{"unique_not_sorted_without_axis", "Expected data for 'Y' is incorrect and in sorted order."},
|
||||
{"cumsum_1d_reverse_exclusive", "only failing linux GPU CI. Likely build error."},
|
||||
{"range_float_type_positive_delta", "not implemented yet"},
|
||||
{"range_float_type_positive_delta_expanded", "not implemented yet"},
|
||||
{"range_int32_type_negative_delta", "not implemented yet"},
|
||||
{"range_int32_type_negative_delta_expanded", "not implemented yet"},
|
||||
{"det_2d", "not implemented yet"},
|
||||
{"det_nd", "not implemented yet"},
|
||||
{"resize_downsample_scales_cubic_A_n0p5_exclude_outside", "not implemented yet"},
|
||||
|
|
@ -500,6 +496,8 @@ int real_main(int argc, char* argv[], Ort::Env& env) {
|
|||
broken_tests.insert({"tf_mobilenet_v1_1.0_224", "result mismatch"});
|
||||
broken_tests.insert({"mobilenetv2-1.0", "result mismatch"});
|
||||
broken_tests.insert({"candy", "result mismatch"});
|
||||
broken_tests.insert({"range_float_type_positive_delta_expanded", "get unknown exception from MKLDNN EP"});
|
||||
broken_tests.insert({"range_int32_type_negative_delta_expanded", "get unknown exception from MKLDNN EP"});
|
||||
#endif
|
||||
|
||||
#ifdef USE_OPENVINO
|
||||
|
|
|
|||
91
onnxruntime/test/providers/cpu/generator/range_test.cc
Normal file
91
onnxruntime/test/providers/cpu/generator/range_test.cc
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "test/providers/provider_test_utils.h"
|
||||
|
||||
namespace onnxruntime {
|
||||
namespace test {
|
||||
|
||||
template <typename T>
|
||||
static void RunTest(
|
||||
T start,
|
||||
T limit,
|
||||
T delta,
|
||||
const std::vector<int64_t>& output_dims,
|
||||
const std::vector<T>& output) {
|
||||
// ONNX domain opset-11
|
||||
OpTester test1("Range", 11);
|
||||
test1.AddInput<T>("start", {}, {start});
|
||||
test1.AddInput<T>("limit", {}, {limit});
|
||||
test1.AddInput<T>("delta", {}, {delta});
|
||||
test1.AddOutput<T>("output", output_dims, output);
|
||||
// NGraph does not yet support opset-11 and builds break on this test, hence exclude the EP
|
||||
test1.Run(OpTester::ExpectResult::kExpectSuccess, "", {kNGraphExecutionProvider});
|
||||
|
||||
#ifndef DISABLE_CONTRIB_OPS
|
||||
|
||||
// MSFT domain opset-1 (contrib op)
|
||||
OpTester test2("Range", 1, kMSDomain);
|
||||
test2.AddInput<T>("start", {}, {start});
|
||||
test2.AddInput<T>("limit", {}, {limit});
|
||||
|
||||
if (delta != T{1}) // only contrib schema allows optional 'delta' input
|
||||
test2.AddInput<T>("delta", {}, {delta});
|
||||
|
||||
test2.AddOutput<T>("output", output_dims, output);
|
||||
test2.Run();
|
||||
|
||||
#endif
|
||||
} // namespace test
|
||||
|
||||
TEST(RangeTest, Int32_DeltaDefault) {
|
||||
RunTest<int32_t>(0, 5, 1, {5}, {0, 1, 2, 3, 4});
|
||||
}
|
||||
|
||||
TEST(RangeTest, Int64_DeltaDefault) {
|
||||
RunTest<int64_t>(0, 5, 1, {5}, {0, 1, 2, 3, 4});
|
||||
}
|
||||
|
||||
TEST(RangeTest, Float_DeltaDefault) {
|
||||
RunTest<float>(0.f, 5.f, 1.f, {5}, {0.f, 1.f, 2.f, 3.f, 4.f});
|
||||
}
|
||||
|
||||
TEST(RangeTest, Double_DeltaDefault) {
|
||||
RunTest<double>(0., 5., 1., {5}, {0., 1., 2., 3., 4.});
|
||||
}
|
||||
|
||||
TEST(RangeTest, Int32_Delta_NonDefault) {
|
||||
RunTest<int32_t>(0, 10, 2, {5}, {0, 2, 4, 6, 8});
|
||||
}
|
||||
|
||||
TEST(RangeTest, Int64_Delta_NonDefault_0) {
|
||||
RunTest<int64_t>(0, 9, 2, {5}, {0, 2, 4, 6, 8});
|
||||
}
|
||||
|
||||
TEST(RangeTest, Int64_Delta_NonDefault_1) {
|
||||
RunTest<int64_t>(1, 2, 2, {1}, {1});
|
||||
}
|
||||
|
||||
TEST(RangeTest, Int32_NegativeDelta_0) {
|
||||
RunTest<int32_t>(2, -9, -2, {6}, {2, 0, -2, -4, -6, -8});
|
||||
}
|
||||
|
||||
TEST(RangeTest, Int32_NegativeDelta_1) {
|
||||
RunTest<int32_t>(2, 9, -2, {0}, {});
|
||||
}
|
||||
|
||||
TEST(RangeTest, Float_NegativeDelta_0) {
|
||||
RunTest<float>(2.0f, -8.1f, -2.0f, {6}, {2.0f, 0.0f, -2.0f, -4.0f, -6.0f, -8.0f});
|
||||
}
|
||||
|
||||
TEST(RangeTest, Float_SameStartAndLimit) {
|
||||
RunTest<float>(2.0f, 2.0f, 1, {0}, {});
|
||||
}
|
||||
|
||||
TEST(RangeTest, AlmostSameStartAndLimitHighDelta) {
|
||||
RunTest<float>(2.0f, 2.01f, 1000000.0f, {1}, {2.0f});
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace onnxruntime
|
||||
Loading…
Reference in a new issue