mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-28 20:11:22 +00:00
TopK op: Promote onnx to a newer commit and handle changed TopK spec for opset 10 (#611)
* Initial commit * Nit fix
This commit is contained in:
parent
7dd9bc4d78
commit
cfb08c4848
7 changed files with 269 additions and 102 deletions
|
|
@ -49,7 +49,7 @@
|
|||
"component":{
|
||||
"type":"git",
|
||||
"git":{
|
||||
"commitHash":"a89a4a162f3d0c9b8269e97327c44297b04214a1",
|
||||
"commitHash":"1ec81bc6d49ccae23cd7801515feaadd13082903",
|
||||
"repositoryUrl":"https://github.com/onnx/onnx.git"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
cmake/external/onnx
vendored
2
cmake/external/onnx
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit a89a4a162f3d0c9b8269e97327c44297b04214a1
|
||||
Subproject commit 1ec81bc6d49ccae23cd7801515feaadd13082903
|
||||
|
|
@ -96,7 +96,7 @@ class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOn
|
|||
class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, 9, int64_t, MatMul);
|
||||
class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, 9, uint64_t, MatMul);
|
||||
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, Softmax);
|
||||
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, TopK);
|
||||
class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, 9, TopK);
|
||||
class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 7, 9, BatchNormalization);
|
||||
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, Conv);
|
||||
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, ConvTranspose);
|
||||
|
|
@ -271,6 +271,7 @@ class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain,
|
|||
|
||||
// Opset 10
|
||||
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, StringNormalizer);
|
||||
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, TopK);
|
||||
|
||||
void RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) {
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 6, Clip)>());
|
||||
|
|
@ -359,7 +360,7 @@ void RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) {
|
|||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, 9, int64_t, MatMul)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 9, 9, uint64_t, MatMul)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, Softmax)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, TopK)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, 9, TopK)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 7, 9, BatchNormalization)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, Conv)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 1, ConvTranspose)>());
|
||||
|
|
@ -535,6 +536,7 @@ void RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) {
|
|||
|
||||
// Opset 10
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, StringNormalizer)>());
|
||||
kernel_registry.Register(BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 10, TopK)>());
|
||||
}
|
||||
|
||||
// Forward declarations of ml op kernels
|
||||
|
|
|
|||
|
|
@ -24,13 +24,8 @@
|
|||
#include <queue>
|
||||
using namespace std;
|
||||
namespace onnxruntime {
|
||||
// spec https://github.com/onnx/onnx/blob/master/docs/Operators.md#TopK
|
||||
ONNX_CPU_OPERATOR_KERNEL(
|
||||
TopK,
|
||||
1,
|
||||
KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType<float>()).TypeConstraint("I", DataTypeImpl::GetTensorType<int64_t>()),
|
||||
TopK<float>);
|
||||
|
||||
// Helper methods
|
||||
static int64_t SizeToDim(size_t k, const vector<int64_t>& dims) {
|
||||
ORT_ENFORCE(k <= dims.size());
|
||||
int64_t r = 1;
|
||||
|
|
@ -60,17 +55,15 @@ struct ValueCmp {
|
|||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
Status TopK<float>::Compute(OpKernelContext* p_op_kernel_context) const {
|
||||
const Tensor* X = p_op_kernel_context->Input<Tensor>(0);
|
||||
if (X == nullptr) return Status(common::ONNXRUNTIME, common::FAIL, "input count mismatch");
|
||||
// Core TopK implementation
|
||||
Status TopKImpl(OpKernelContext* p_op_kernel_context, const Tensor* X, const int axis, const unsigned k) {
|
||||
const vector<int64_t>& in_dims = X->Shape().GetDims();
|
||||
// Will return axis_ as is if positive or fixes it in case it is negative
|
||||
auto axis_parsed = HandleNegativeAxis(axis_, in_dims.size());
|
||||
// Check to ensure k_ is within the bounds of what is available in that specific axis
|
||||
if (in_dims.at(axis_parsed) < k_) {
|
||||
auto axis_parsed = HandleNegativeAxis(axis, in_dims.size());
|
||||
// Check to ensure k is within the bounds of what is available in that specific axis
|
||||
if (in_dims.at(axis_parsed) < k) {
|
||||
ostringstream err_msg;
|
||||
err_msg << "k argment [" << k_ << "] should not be greater than specified axis dim value [" << in_dims.at(axis_parsed) << "]";
|
||||
err_msg << "k argment [" << k << "] should not be greater than specified axis dim value [" << in_dims.at(axis_parsed) << "]";
|
||||
return Status(common::ONNXRUNTIME, common::FAIL, err_msg.str());
|
||||
}
|
||||
|
||||
|
|
@ -82,10 +75,10 @@ Status TopK<float>::Compute(OpKernelContext* p_op_kernel_context) const {
|
|||
cols);
|
||||
|
||||
// Resize output tensors to be the same shape as the input except
|
||||
// for the specified dimension ((i.e.) axis_parsed), which will be of size k_. E.x. for an input tensor
|
||||
// of shape [3, 4, 5] and k_=2 with axis_parsed=1, both of these will be shape [3, 2, 5]
|
||||
// for the specified dimension ((i.e.) axis_parsed), which will be of size k. E.x. for an input tensor
|
||||
// of shape [3, 4, 5] and k=2 with axis_parsed=1, both of these will be shape [3, 2, 5]
|
||||
vector<int64_t> output_linear_shape = in_dims;
|
||||
output_linear_shape[axis_parsed] = k_;
|
||||
output_linear_shape[axis_parsed] = k;
|
||||
auto* Values = p_op_kernel_context->Output(0, output_linear_shape);
|
||||
auto* Indices = p_op_kernel_context->Output(1, output_linear_shape);
|
||||
|
||||
|
|
@ -96,40 +89,100 @@ Status TopK<float>::Compute(OpKernelContext* p_op_kernel_context) const {
|
|||
auto Indices_map = EigenMatrixMapRowMajor<int64_t>(
|
||||
Indices->template MutableData<int64_t>(), rows, reduced_cols);
|
||||
|
||||
// This is basically the number of elements within each of the "k_" rows
|
||||
const int64_t block_slice = reduced_cols / k_;
|
||||
// This is basically the number of elements within each of the "k" rows
|
||||
const int64_t block_slice = reduced_cols / k;
|
||||
// Sort preserving Indices
|
||||
for (int64_t i = 0; i < rows; ++i) {
|
||||
for (int64_t j = 0; j < block_slice; ++j) {
|
||||
// Build a min-heap, the heap element is pair of (value, idx)
|
||||
// the top of the heap is the smallest value
|
||||
priority_queue<
|
||||
pair<float, int64_t>,
|
||||
vector<pair<float, int64_t>>,
|
||||
ValueCmp<float>>
|
||||
min_heap;
|
||||
// Maintain the size of heap to be less or equal to k_, so the
|
||||
// heap will hold the k_ largest Values
|
||||
for (int64_t k = 0; k < in_dims[axis_parsed]; ++k) {
|
||||
const auto value = input_map(i, k * block_slice + j);
|
||||
if (min_heap.size() < k_ || value > min_heap.top().first) {
|
||||
min_heap.push({value, k});
|
||||
}
|
||||
if (min_heap.size() > k_) {
|
||||
min_heap.pop();
|
||||
}
|
||||
}
|
||||
// Extract these k_ elements and place them in the results placeholder
|
||||
for (int64_t l = 0; l < k_; ++l) {
|
||||
auto& pqElem = min_heap.top();
|
||||
auto col_index = (k_ - l -1) * block_slice + j;
|
||||
Values_map(i, col_index) = pqElem.first;
|
||||
Indices_map(i, col_index) = pqElem.second;
|
||||
min_heap.pop();
|
||||
}
|
||||
}
|
||||
for (int64_t j = 0; j < block_slice; ++j) {
|
||||
// Build a min-heap, the heap element is pair of (value, idx)
|
||||
// the top of the heap is the smallest value
|
||||
priority_queue<
|
||||
pair<float, int64_t>,
|
||||
vector<pair<float, int64_t>>,
|
||||
ValueCmp<float>>
|
||||
min_heap;
|
||||
// Maintain the size of heap to be less or equal to k_, so the
|
||||
// heap will hold the k largest Values
|
||||
for (int64_t l = 0; l < in_dims[axis_parsed]; ++l) {
|
||||
const auto value = input_map(i, l * block_slice + j);
|
||||
if (min_heap.size() < k || value > min_heap.top().first) {
|
||||
min_heap.push({value, l});
|
||||
}
|
||||
if (min_heap.size() > k) {
|
||||
min_heap.pop();
|
||||
}
|
||||
}
|
||||
// Extract these k elements and place them in the results placeholder
|
||||
for (int64_t l = 0; l < k; ++l) {
|
||||
auto& pqElem = min_heap.top();
|
||||
auto col_index = (k - l - 1) * block_slice + j;
|
||||
Values_map(i, col_index) = pqElem.first;
|
||||
Indices_map(i, col_index) = pqElem.second;
|
||||
min_heap.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Status::OK();
|
||||
}
|
||||
} // namespace onnxruntime
|
||||
|
||||
// Opset ver - 1 to 9
|
||||
template <>
|
||||
TopK<9, float>::TopK(const OpKernelInfo& op_kernel_info) : OpKernel(op_kernel_info) {
|
||||
int64_t k_temp;
|
||||
ORT_ENFORCE(op_kernel_info.GetAttr<int64_t>("k", &k_temp).IsOK());
|
||||
ORT_ENFORCE(k_temp > 0);
|
||||
k_ = gsl::narrow_cast<unsigned>(k_temp);
|
||||
|
||||
int64_t axis_temp;
|
||||
ORT_ENFORCE(op_kernel_info.GetAttr<int64_t>("axis", &axis_temp).IsOK());
|
||||
axis_ = gsl::narrow_cast<int>(axis_temp);
|
||||
}
|
||||
|
||||
// Opset ver - 1 to 9
|
||||
template <>
|
||||
Status TopK<9, float>::Compute(OpKernelContext* p_op_kernel_context) const {
|
||||
const Tensor* X = p_op_kernel_context->Input<Tensor>(0);
|
||||
if (X == nullptr) return Status(common::ONNXRUNTIME, common::FAIL,
|
||||
"input count mismatch, expected 1 input - the tensor to be processed");
|
||||
return TopKImpl(p_op_kernel_context, X, axis_, k_);
|
||||
}
|
||||
|
||||
// Opset ver - 10
|
||||
template <>
|
||||
TopK<10, float>::TopK(const OpKernelInfo& op_kernel_info) : OpKernel(op_kernel_info) {
|
||||
int64_t axis_temp;
|
||||
ORT_ENFORCE(op_kernel_info.GetAttr<int64_t>("axis", &axis_temp).IsOK());
|
||||
axis_ = gsl::narrow_cast<int>(axis_temp);
|
||||
}
|
||||
|
||||
// Opset ver - 10
|
||||
template <>
|
||||
Status TopK<10, float>::Compute(OpKernelContext* p_op_kernel_context) const {
|
||||
const Tensor* X = p_op_kernel_context->Input<Tensor>(0);
|
||||
const Tensor* Y = p_op_kernel_context->Input<Tensor>(1);
|
||||
if (X == nullptr || Y == nullptr) return Status(common::ONNXRUNTIME, common::FAIL,
|
||||
"input count mismatch, expected 2 inputs - "
|
||||
"the tensor to be processed and a tensor containing k value");
|
||||
const vector<int64_t>& y_shape = Y->Shape().GetDims();
|
||||
if (y_shape.size() != 1 || y_shape[0] != 1) return Status(common::ONNXRUNTIME, common::FAIL, "k tensor should be a 1D tensor of size 1");
|
||||
unsigned parsed_input_k = gsl::narrow_cast<unsigned>(Y->template Data<int64_t>()[0]);
|
||||
if (parsed_input_k <= 0) return Status(common::ONNXRUNTIME, common::FAIL, "value of k should be greater than 0");
|
||||
return TopKImpl(p_op_kernel_context, X, axis_, parsed_input_k);
|
||||
}
|
||||
|
||||
// Register necessary kernels
|
||||
// spec https://github.com/onnx/onnx/blob/master/docs/Operators.md#TopK
|
||||
ONNX_CPU_OPERATOR_VERSIONED_KERNEL(
|
||||
TopK,
|
||||
1, 9,
|
||||
KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType<float>()).TypeConstraint("I", DataTypeImpl::GetTensorType<int64_t>()),
|
||||
TopK<9, float>);
|
||||
|
||||
ONNX_CPU_OPERATOR_KERNEL(
|
||||
TopK,
|
||||
10,
|
||||
KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType<float>()).TypeConstraint("I", DataTypeImpl::GetTensorType<int64_t>()),
|
||||
TopK<10, float>);
|
||||
|
||||
} // namespace onnxruntime
|
||||
|
|
@ -1,27 +1,15 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "core/common/common.h"
|
||||
#include "core/common/exceptions.h"
|
||||
#pragma once
|
||||
|
||||
#include "core/framework/op_kernel.h"
|
||||
#include "core/framework/tensor.h"
|
||||
#include "core/util/math_cpuonly.h"
|
||||
#include "gsl/gsl_util"
|
||||
|
||||
namespace onnxruntime {
|
||||
template <typename T>
|
||||
template <int OpSet, typename T>
|
||||
class TopK final : public OpKernel {
|
||||
public:
|
||||
TopK(const OpKernelInfo& op_kernel_info) : OpKernel(op_kernel_info) {
|
||||
int64_t k_temp;
|
||||
ORT_ENFORCE(op_kernel_info.GetAttr<int64_t>("k", &k_temp).IsOK());
|
||||
ORT_ENFORCE(k_temp > 0);
|
||||
k_ = gsl::narrow_cast<unsigned>(k_temp);
|
||||
|
||||
int64_t axis_temp;
|
||||
ORT_ENFORCE(op_kernel_info.GetAttr<int64_t>("axis", &axis_temp).IsOK());
|
||||
axis_ = gsl::narrow_cast<int>(axis_temp);
|
||||
}
|
||||
TopK(const OpKernelInfo& op_kernel_info);
|
||||
|
||||
Status Compute(OpKernelContext* p_op_kernel_context) const override;
|
||||
|
||||
|
|
@ -29,4 +17,4 @@ class TopK final : public OpKernel {
|
|||
int axis_;
|
||||
unsigned k_;
|
||||
};
|
||||
} // namespace onnxruntime
|
||||
} // namespace onnxruntime
|
||||
|
|
@ -8,7 +8,8 @@
|
|||
namespace onnxruntime {
|
||||
namespace test {
|
||||
|
||||
static void RunTest(int64_t k,
|
||||
static void RunTest(int op_set,
|
||||
int64_t k,
|
||||
const std::vector<float>& input_vals,
|
||||
const std::vector<int64_t>& input_dimensions,
|
||||
const std::vector<float>& expected_vals,
|
||||
|
|
@ -17,122 +18,131 @@ static void RunTest(int64_t k,
|
|||
int64_t axis = -1,
|
||||
OpTester::ExpectResult expect_result = OpTester::ExpectResult::kExpectSuccess,
|
||||
const std::string& expected_err_str = "") {
|
||||
OpTester test("TopK");
|
||||
test.AddAttribute("k", k);
|
||||
if (axis != -1) {
|
||||
test.AddAttribute("axis", axis);
|
||||
}
|
||||
OpTester test("TopK", op_set);
|
||||
|
||||
// Attributes
|
||||
if (axis != -1)
|
||||
test.AddAttribute("axis", axis);
|
||||
if (op_set <= 9)
|
||||
test.AddAttribute("k", k);
|
||||
|
||||
// Inputs
|
||||
test.AddInput<float>("X", input_dimensions, input_vals);
|
||||
if (op_set == 10)
|
||||
test.AddInput<int64_t>("K", {1}, {k});
|
||||
|
||||
// Outputs
|
||||
test.AddOutput<float>("Values", expected_dimensions, expected_vals);
|
||||
test.AddOutput<int64_t>("Indices", expected_dimensions, expected_indices);
|
||||
|
||||
// Run test and check results
|
||||
test.Run(expect_result, expected_err_str);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, Top1DefaultAxis) {
|
||||
TEST(TopKOperator, Top1DefaultAxisOpset9) {
|
||||
std::vector<float> input_vals = {0.1f, 0.3f, 0.2f, 0.4f, 0.1f, 0.3f, 0.3f, 0.2f};
|
||||
std::vector<int64_t> input_dimensions = {2, 4};
|
||||
std::vector<float> expected_vals = {0.4f, 0.3f};
|
||||
std::vector<int64_t> expected_indices = {3, 1};
|
||||
std::vector<int64_t> expected_dimensions = {2, 1};
|
||||
RunTest(1, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions);
|
||||
RunTest(9, 1, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, Top2DefaultAxis) {
|
||||
TEST(TopKOperator, Top2DefaultAxisOpset9) {
|
||||
std::vector<float> input_vals = {0.1f, 0.3f, 0.2f, 0.4f, 0.1f, 0.3f, 0.4f, 0.2f};
|
||||
std::vector<int64_t> input_dimensions = {2, 4};
|
||||
std::vector<float> expected_vals = {0.4f, 0.3f, 0.4f, 0.3f};
|
||||
std::vector<int64_t> expected_indices = {3, 1, 2, 1};
|
||||
std::vector<int64_t> expected_dimensions = {2, 2};
|
||||
RunTest(2, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions);
|
||||
RunTest(9, 2, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, Top3DefaultAxis) {
|
||||
TEST(TopKOperator, Top3DefaultAxisOpset9) {
|
||||
std::vector<float> input_vals = {0.1f, 0.3f, 0.2f, 0.4f, 0.1f, 0.3f, 0.4f, 0.2f};
|
||||
std::vector<int64_t> input_dimensions = {2, 4};
|
||||
std::vector<float> expected_vals = {0.4f, 0.3f, 0.2f, 0.4f, 0.3f, 0.2f};
|
||||
std::vector<int64_t> expected_indices = {3, 1, 2, 2, 1, 3};
|
||||
std::vector<int64_t> expected_dimensions = {2, 3};
|
||||
RunTest(3, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions);
|
||||
RunTest(9, 3, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, TopAllDefaultAxis) {
|
||||
TEST(TopKOperator, TopAllDefaultAxisOpset9) {
|
||||
std::vector<float> input_vals = {0.1f, 0.3f, 0.2f, 0.4f, 0.1f, 0.3f, 0.3f, 0.2f};
|
||||
std::vector<int64_t> input_dimensions = {2, 4};
|
||||
std::vector<float> expected_vals = {0.4f, 0.3f, 0.2f, 0.1f, 0.3f, 0.3f, 0.2f, 0.1f};
|
||||
std::vector<int64_t> expected_indices = {3, 1, 2, 0, 1, 2, 3, 0};
|
||||
std::vector<int64_t> expected_dimensions = {2, 4};
|
||||
RunTest(4, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions);
|
||||
RunTest(9, 4, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, Top1ExplicitAxis) {
|
||||
TEST(TopKOperator, Top1ExplicitAxisOpset9) {
|
||||
std::vector<float> input_vals = {0.1f, 0.3f, 0.2f, 0.4f, 0.1f, 0.3f, 0.3f, 0.2f};
|
||||
std::vector<int64_t> input_dimensions = {4, 2};
|
||||
std::vector<float> expected_vals = {0.3f, 0.4f};
|
||||
std::vector<int64_t> expected_indices = {3, 1};
|
||||
std::vector<int64_t> expected_dimensions = {1, 2};
|
||||
int64_t axis = 0;
|
||||
RunTest(1, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
RunTest(9, 1, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, Top2ExplicitAxis) {
|
||||
TEST(TopKOperator, Top2ExplicitAxisOpset9) {
|
||||
std::vector<float> input_vals = {0.0f, 1.0f, 2.0f, 11.0f, 08.0f, 5.0f, 6.0f, 7.0f, 4.0f, 9.0f, 10.0f, 3.0f};
|
||||
std::vector<int64_t> input_dimensions = {3, 4};
|
||||
std::vector<float> expected_vals = {8.0f, 9.0f, 10.0f, 11.0f, 4.0f, 5.0f, 6.0f, 7.0f};
|
||||
std::vector<int64_t> expected_indices = {1, 2, 2, 0, 2, 1, 1, 1};
|
||||
std::vector<int64_t> expected_dimensions = {2, 4};
|
||||
int64_t axis = 0;
|
||||
RunTest(2, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
RunTest(9, 2, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, Top3ExplicitAxis) {
|
||||
TEST(TopKOperator, Top3ExplicitAxisOpset9) {
|
||||
std::vector<float> input_vals = {0.1f, 0.3f, 0.2f, 0.4f, 0.1f, 0.3f, 0.3f, 0.2f};
|
||||
std::vector<int64_t> input_dimensions = {4, 2};
|
||||
std::vector<float> expected_vals = {0.3f, 0.4f, 0.2f, 0.3f, 0.1f, 0.3f};
|
||||
std::vector<int64_t> expected_indices = {3, 1, 1, 0, 0, 2};
|
||||
std::vector<int64_t> expected_dimensions = {3, 2};
|
||||
int64_t axis = 0;
|
||||
RunTest(3, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
RunTest(9, 3, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
}
|
||||
|
||||
|
||||
TEST(TopKOperator, TopAllExplicitAxis) {
|
||||
TEST(TopKOperator, TopAllExplicitAxisOpset9) {
|
||||
std::vector<float> input_vals = {0.1f, 0.3f, 0.2f, 0.4f, 0.1f, 0.3f, 0.3f, 0.2f};
|
||||
std::vector<int64_t> input_dimensions = {4, 2};
|
||||
std::vector<float> expected_vals = {0.3f, 0.4f, 0.2f, 0.3f, 0.1f, 0.3f, 0.1f, 0.2f};
|
||||
std::vector<int64_t> expected_indices = {3, 1, 1, 0, 0, 2, 2, 3};
|
||||
std::vector<int64_t> expected_dimensions = {4, 2};
|
||||
int64_t axis = 0;
|
||||
RunTest(4, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
RunTest(9, 4, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, TopAllExplicitAxis1DInput) {
|
||||
TEST(TopKOperator, TopAllExplicitAxis1DInputOpset9) {
|
||||
std::vector<float> input_vals = {93.0f, 695.0f, 971.0f, 978.0f, 483.0f, 247.0f, 242.0f, 983.0f, 531.0f, 723.0f, 285.0f, 527.0f, 862.0f};
|
||||
std::vector<int64_t> input_dimensions = {13};
|
||||
std::vector<float> expected_vals = {983.0f, 978.0f, 971.0f, 862.0f, 723.0f, 695.0f, 531.0f, 527.0f, 483.0f, 285.0f, 247.0f, 242.0f, 93.0f};
|
||||
std::vector<int64_t> expected_indices = {7, 3, 2, 12, 9, 1, 8, 11, 4, 10, 5, 6,0};
|
||||
std::vector<int64_t> expected_indices = {7, 3, 2, 12, 9, 1, 8, 11, 4, 10, 5, 6, 0};
|
||||
std::vector<int64_t> expected_dimensions = {13};
|
||||
int64_t axis = 0;
|
||||
RunTest(13, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
RunTest(9, 13, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, Top1ExplicitAxisMultiDInput) {
|
||||
TEST(TopKOperator, Top1ExplicitAxisMultiDInputOpset9) {
|
||||
std::vector<float> input_vals = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f};
|
||||
std::vector<int64_t> input_dimensions = {2, 2, 2};
|
||||
std::vector<float> expected_vals = {3, 4, 7, 8};
|
||||
std::vector<int64_t> expected_indices = {1, 1, 1, 1};
|
||||
std::vector<int64_t> expected_dimensions = {2, 1, 2};
|
||||
int64_t axis = 1;
|
||||
RunTest(1, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
RunTest(9, 1, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, InvalidK) {
|
||||
TEST(TopKOperator, InvalidKOpset9) {
|
||||
std::vector<float> input_vals = {0.1f, 0.3f, 0.2f, 0.4f, 0.1f, 0.3f, 0.3f, 0.2f};
|
||||
std::vector<int64_t> input_dimensions = {2, 4};
|
||||
std::vector<float> expected_vals = {0.4f, 0.3f, 0.2f, 0.1f, 0.3f, 0.3f, 0.2f, 0.1f};
|
||||
std::vector<int64_t> expected_indices = {3, 1, 2, 0, 1, 2, 3, 0};
|
||||
std::vector<int64_t> expected_dimensions = {2, 4};
|
||||
RunTest(0,
|
||||
RunTest(9,
|
||||
0,
|
||||
input_vals,
|
||||
input_dimensions,
|
||||
expected_vals,
|
||||
|
|
@ -143,5 +153,119 @@ TEST(TopKOperator, InvalidK) {
|
|||
"Invalid value for attribute k");
|
||||
}
|
||||
|
||||
TEST(TopKOperator, Top1DefaultAxisOpset10) {
|
||||
std::vector<float> input_vals = {0.1f, 0.3f, 0.2f, 0.4f, 0.1f, 0.3f, 0.3f, 0.2f};
|
||||
std::vector<int64_t> input_dimensions = {2, 4};
|
||||
std::vector<float> expected_vals = {0.4f, 0.3f};
|
||||
std::vector<int64_t> expected_indices = {3, 1};
|
||||
std::vector<int64_t> expected_dimensions = {2, 1};
|
||||
RunTest(10, 1, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, Top2DefaultAxisOpset10) {
|
||||
std::vector<float> input_vals = {0.1f, 0.3f, 0.2f, 0.4f, 0.1f, 0.3f, 0.4f, 0.2f};
|
||||
std::vector<int64_t> input_dimensions = {2, 4};
|
||||
std::vector<float> expected_vals = {0.4f, 0.3f, 0.4f, 0.3f};
|
||||
std::vector<int64_t> expected_indices = {3, 1, 2, 1};
|
||||
std::vector<int64_t> expected_dimensions = {2, 2};
|
||||
RunTest(10, 2, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, Top3DefaultAxisOpset10) {
|
||||
std::vector<float> input_vals = {0.1f, 0.3f, 0.2f, 0.4f, 0.1f, 0.3f, 0.4f, 0.2f};
|
||||
std::vector<int64_t> input_dimensions = {2, 4};
|
||||
std::vector<float> expected_vals = {0.4f, 0.3f, 0.2f, 0.4f, 0.3f, 0.2f};
|
||||
std::vector<int64_t> expected_indices = {3, 1, 2, 2, 1, 3};
|
||||
std::vector<int64_t> expected_dimensions = {2, 3};
|
||||
RunTest(10, 3, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, TopAllDefaultAxisOpset10) {
|
||||
std::vector<float> input_vals = {0.1f, 0.3f, 0.2f, 0.4f, 0.1f, 0.3f, 0.3f, 0.2f};
|
||||
std::vector<int64_t> input_dimensions = {2, 4};
|
||||
std::vector<float> expected_vals = {0.4f, 0.3f, 0.2f, 0.1f, 0.3f, 0.3f, 0.2f, 0.1f};
|
||||
std::vector<int64_t> expected_indices = {3, 1, 2, 0, 1, 2, 3, 0};
|
||||
std::vector<int64_t> expected_dimensions = {2, 4};
|
||||
RunTest(10, 4, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, Top1ExplicitAxisOpset10) {
|
||||
std::vector<float> input_vals = {0.1f, 0.3f, 0.2f, 0.4f, 0.1f, 0.3f, 0.3f, 0.2f};
|
||||
std::vector<int64_t> input_dimensions = {4, 2};
|
||||
std::vector<float> expected_vals = {0.3f, 0.4f};
|
||||
std::vector<int64_t> expected_indices = {3, 1};
|
||||
std::vector<int64_t> expected_dimensions = {1, 2};
|
||||
int64_t axis = 0;
|
||||
RunTest(10, 1, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, Top2ExplicitAxisOpset10) {
|
||||
std::vector<float> input_vals = {0.0f, 1.0f, 2.0f, 11.0f, 08.0f, 5.0f, 6.0f, 7.0f, 4.0f, 9.0f, 10.0f, 3.0f};
|
||||
std::vector<int64_t> input_dimensions = {3, 4};
|
||||
std::vector<float> expected_vals = {8.0f, 9.0f, 10.0f, 11.0f, 4.0f, 5.0f, 6.0f, 7.0f};
|
||||
std::vector<int64_t> expected_indices = {1, 2, 2, 0, 2, 1, 1, 1};
|
||||
std::vector<int64_t> expected_dimensions = {2, 4};
|
||||
int64_t axis = 0;
|
||||
RunTest(10, 2, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, Top3ExplicitAxisOpset10) {
|
||||
std::vector<float> input_vals = {0.1f, 0.3f, 0.2f, 0.4f, 0.1f, 0.3f, 0.3f, 0.2f};
|
||||
std::vector<int64_t> input_dimensions = {4, 2};
|
||||
std::vector<float> expected_vals = {0.3f, 0.4f, 0.2f, 0.3f, 0.1f, 0.3f};
|
||||
std::vector<int64_t> expected_indices = {3, 1, 1, 0, 0, 2};
|
||||
std::vector<int64_t> expected_dimensions = {3, 2};
|
||||
int64_t axis = 0;
|
||||
RunTest(10, 3, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, TopAllExplicitAxisOpset10) {
|
||||
std::vector<float> input_vals = {0.1f, 0.3f, 0.2f, 0.4f, 0.1f, 0.3f, 0.3f, 0.2f};
|
||||
std::vector<int64_t> input_dimensions = {4, 2};
|
||||
std::vector<float> expected_vals = {0.3f, 0.4f, 0.2f, 0.3f, 0.1f, 0.3f, 0.1f, 0.2f};
|
||||
std::vector<int64_t> expected_indices = {3, 1, 1, 0, 0, 2, 2, 3};
|
||||
std::vector<int64_t> expected_dimensions = {4, 2};
|
||||
int64_t axis = 0;
|
||||
RunTest(10, 4, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, TopAllExplicitAxis1DInputOpset10) {
|
||||
std::vector<float> input_vals = {93.0f, 695.0f, 971.0f, 978.0f, 483.0f, 247.0f, 242.0f, 983.0f, 531.0f, 723.0f, 285.0f, 527.0f, 862.0f};
|
||||
std::vector<int64_t> input_dimensions = {13};
|
||||
std::vector<float> expected_vals = {983.0f, 978.0f, 971.0f, 862.0f, 723.0f, 695.0f, 531.0f, 527.0f, 483.0f, 285.0f, 247.0f, 242.0f, 93.0f};
|
||||
std::vector<int64_t> expected_indices = {7, 3, 2, 12, 9, 1, 8, 11, 4, 10, 5, 6, 0};
|
||||
std::vector<int64_t> expected_dimensions = {13};
|
||||
int64_t axis = 0;
|
||||
RunTest(10, 13, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, Top1ExplicitAxisMultiDInputOpset10) {
|
||||
std::vector<float> input_vals = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f};
|
||||
std::vector<int64_t> input_dimensions = {2, 2, 2};
|
||||
std::vector<float> expected_vals = {3, 4, 7, 8};
|
||||
std::vector<int64_t> expected_indices = {1, 1, 1, 1};
|
||||
std::vector<int64_t> expected_dimensions = {2, 1, 2};
|
||||
int64_t axis = 1;
|
||||
RunTest(10, 1, input_vals, input_dimensions, expected_vals, expected_indices, expected_dimensions, axis);
|
||||
}
|
||||
|
||||
TEST(TopKOperator, InvalidKOpset10) {
|
||||
std::vector<float> input_vals = {0.1f, 0.3f, 0.2f, 0.4f, 0.1f, 0.3f, 0.3f, 0.2f};
|
||||
std::vector<int64_t> input_dimensions = {2, 4};
|
||||
std::vector<float> expected_vals = {0.4f, 0.3f, 0.2f, 0.1f, 0.3f, 0.3f, 0.2f, 0.1f};
|
||||
std::vector<int64_t> expected_indices = {3, 1, 2, 0, 1, 2, 3, 0};
|
||||
std::vector<int64_t> expected_dimensions = {2, 4};
|
||||
RunTest(10,
|
||||
0,
|
||||
input_vals,
|
||||
input_dimensions,
|
||||
expected_vals,
|
||||
expected_indices,
|
||||
expected_dimensions,
|
||||
1,
|
||||
OpTester::ExpectResult::kExpectFailure,
|
||||
"value of k should be greater than 0");
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace onnxruntime
|
||||
} // namespace onnxruntime
|
||||
|
|
@ -38,8 +38,8 @@ else
|
|||
#5af210ca8a1c73aa6bae8754c9346ec54d0a756e is v1.2.3
|
||||
#bae6333e149a59a3faa9c4d9c44974373dcf5256 is v1.3.0
|
||||
#9e55ace55aad1ada27516038dfbdc66a8a0763db is v1.4.1
|
||||
#873ddbbc33c6e54d90c5628387edd391fb651dfc is v1.4.1 latest
|
||||
for onnx_version in "5af210ca8a1c73aa6bae8754c9346ec54d0a756e" "bae6333e149a59a3faa9c4d9c44974373dcf5256" "9e55ace55aad1ada27516038dfbdc66a8a0763db" "a89a4a162f3d0c9b8269e97327c44297b04214a1"; do
|
||||
#1ec81bc6d49ccae23cd7801515feaadd13082903 is v1.4.1 latest
|
||||
for onnx_version in "5af210ca8a1c73aa6bae8754c9346ec54d0a756e" "bae6333e149a59a3faa9c4d9c44974373dcf5256" "9e55ace55aad1ada27516038dfbdc66a8a0763db" "1ec81bc6d49ccae23cd7801515feaadd13082903"; do
|
||||
if [ -z ${lastest_onnx_version+x} ]; then
|
||||
echo "first pass";
|
||||
else
|
||||
|
|
|
|||
Loading…
Reference in a new issue