mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-30 20:18:08 +00:00
Add Features to ForecastingPivot Transformer for ONNX Export (#3608)
* checkin * fix MSVC build error * test changes * split pivot output into multiple tensors * add horizon tensor * Support multiple types for non-pivot tensor * limit horizon tensor type to int32_t as max_horizon type * work around some conversion warnings for local machine * support variadic shape for non-pivot input * dropping all rows is an exception * fix a bug * fix the way that generates horizon tensor * more tests added * add TypeConstraint() in ONNX_OPERATOR_KERNEL_EX * update Featurizerslibrary
This commit is contained in:
parent
2c74766ad1
commit
70b554cc85
5 changed files with 241 additions and 56 deletions
|
|
@ -450,7 +450,7 @@
|
|||
{
|
||||
"component": {
|
||||
"git": {
|
||||
"commitHash": "7922489c1e7e7baf20c4b1557743d6c7ea72647d",
|
||||
"commitHash": "f01d8beeac92b54bf93df8053a2acb6a8a10f03c",
|
||||
"repositoryUrl": "https://github.com/microsoft/FeaturizersLibrary.git"
|
||||
},
|
||||
"type": "git"
|
||||
|
|
|
|||
2
cmake/external/FeaturizersLibrary
vendored
2
cmake/external/FeaturizersLibrary
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit 7922489c1e7e7baf20c4b1557743d6c7ea72647d
|
||||
Subproject commit f01d8beeac92b54bf93df8053a2acb6a8a10f03c
|
||||
|
|
@ -494,6 +494,7 @@ void RegisterForecastingPivotFeaturizerVer1(){
|
|||
MS_FEATURIZERS_OPERATOR_SCHEMA(ForecastingPivotTransformer)
|
||||
.SinceVersion(1)
|
||||
.SetDomain(kMSFeaturizersDomain)
|
||||
.Attr("num_pivot_columns", "The first num_pivot_columns input in Input1 are pivoted", AttributeProto::INT)
|
||||
.Input(
|
||||
0,
|
||||
"State",
|
||||
|
|
@ -504,32 +505,31 @@ void RegisterForecastingPivotFeaturizerVer1(){
|
|||
"Inputs",
|
||||
"Variadic number of Input containing tensors of different size",
|
||||
"T",
|
||||
ONNX_NAMESPACE::OpSchema::FormalParameterOption::Variadic)
|
||||
ONNX_NAMESPACE::OpSchema::FormalParameterOption::Variadic,
|
||||
false)
|
||||
.Output(
|
||||
0,
|
||||
"Output",
|
||||
"No information is available",
|
||||
"T")
|
||||
"T",
|
||||
ONNX_NAMESPACE::OpSchema::FormalParameterOption::Variadic,
|
||||
false)
|
||||
.TypeConstraint(
|
||||
"T0",
|
||||
{"tensor(uint8)"},
|
||||
"No information is available")
|
||||
.TypeConstraint(
|
||||
"T",
|
||||
{"tensor(float)", "tensor(double)"},
|
||||
{"tensor(int8)", "tensor(int16)", "tensor(int32)", "tensor(int64)", "tensor(uint8)", "tensor(uint16)", "tensor(uint32)", "tensor(uint64)",
|
||||
"tensor(float)", "tensor(double)", "tensor(bool)", "tensor(string)"},
|
||||
"No information is available")
|
||||
.TypeAndShapeInferenceFunction(
|
||||
[](ONNX_NAMESPACE::InferenceContext& ctx) {
|
||||
auto input_elem_type = ctx.getInputType(1)->tensor_type().elem_type();
|
||||
if (input_elem_type == ONNX_NAMESPACE::TensorProto_DataType_FLOAT) {
|
||||
propagateElemTypeFromDtypeToOutput(ctx, ONNX_NAMESPACE::TensorProto_DataType_FLOAT, 0);
|
||||
} else if (input_elem_type == ONNX_NAMESPACE::TensorProto_DataType_DOUBLE) {
|
||||
propagateElemTypeFromDtypeToOutput(ctx, ONNX_NAMESPACE::TensorProto_DataType_DOUBLE, 0);
|
||||
}
|
||||
//The first num_pivot_columns inputs of Input(1) only support float & double
|
||||
if (hasInputShape(ctx, 1)) {
|
||||
const auto& input_shape = getInputShape(ctx, 1);
|
||||
if (input_shape.dim_size() != 3) {
|
||||
fail_shape_inference("Expecting Inputs to have 3 dimensions");
|
||||
if (input_shape.dim_size() < 2) {
|
||||
fail_shape_inference("Expecting Inputs to have more than 2 dimensions");
|
||||
}
|
||||
}
|
||||
ONNX_NAMESPACE::TensorShapeProto shape;
|
||||
|
|
|
|||
|
|
@ -13,9 +13,27 @@ namespace NS = Microsoft::Featurizer;
|
|||
namespace onnxruntime {
|
||||
namespace featurizers {
|
||||
|
||||
template <typename T>
|
||||
struct CopyImputedColumnsImpl {
|
||||
void operator()(const Tensor* input_tensor, Tensor* output_tensor_imputed,
|
||||
const std::vector<int64_t>& row_idx_record, int64_t input_matrix_size, int num_output_rows) const {
|
||||
const T* input_data(input_tensor->template Data<T>());
|
||||
T* output_data_imputed = output_tensor_imputed->MutableData<T>();
|
||||
|
||||
for (int imputed_output_row_idx = 0; imputed_output_row_idx < num_output_rows; imputed_output_row_idx++) {
|
||||
output_data_imputed = std::copy(input_data + row_idx_record[imputed_output_row_idx] * input_matrix_size,
|
||||
input_data + (row_idx_record[imputed_output_row_idx] + 1) * input_matrix_size,
|
||||
output_data_imputed);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ForecastingPivotTransformerImpl {
|
||||
void operator()(OpKernelContext* ctx) const {
|
||||
void operator()(OpKernelContext* ctx, int64_t num_pivot_columns) const {
|
||||
|
||||
ORT_ENFORCE(num_pivot_columns > 0, "num_pivot_columns > 0, otherwise there will be no input to pivot");
|
||||
|
||||
using MatrixT = NS::RowMajMatrix<typename NS::Traits<T>::nullable_type>;
|
||||
using InputType = std::vector<Eigen::Map<const MatrixT>>;
|
||||
using OutputType = std::vector<T>;
|
||||
|
|
@ -33,21 +51,26 @@ struct ForecastingPivotTransformerImpl {
|
|||
|
||||
//Get the output for whole rows is inevitable because there is conceptually no way to determine the shape of output for each row
|
||||
std::vector<OutputType> output;
|
||||
std::vector<int64_t> row_idx_record;
|
||||
int64_t row_idx = 0;
|
||||
std::function<void(OutputType const & value)> callback_fn;
|
||||
callback_fn = [&output](OutputType const & value) -> void {
|
||||
callback_fn = [&output, &row_idx_record, &row_idx](OutputType const & value) -> void {
|
||||
output.emplace_back(value);
|
||||
row_idx_record.push_back(row_idx);
|
||||
};
|
||||
|
||||
// Transform
|
||||
const int input_node_0_count = ctx->NumVariadicInputs(0);
|
||||
const int input_node_1_count = ctx->NumVariadicInputs(1);
|
||||
|
||||
InputType input;
|
||||
input.reserve(input_node_1_count);
|
||||
input.reserve(num_pivot_columns);
|
||||
std::unordered_map<int, std::tuple<const T*,int64_t, int64_t>> dataPtrMap;
|
||||
for (int64_t row_idx = 0; row_idx < row_num; ++row_idx) {
|
||||
std::vector<uint32_t> horizon_output_helper;
|
||||
for (row_idx = 0; row_idx < row_num; ++row_idx) {
|
||||
//Prepare Input and Output
|
||||
input.clear();
|
||||
for (int index = input_node_0_count; index < input_node_0_count + input_node_1_count; ++index) {
|
||||
for (int index = input_node_0_count; index < input_node_0_count + num_pivot_columns; ++index) {
|
||||
if (row_idx == 0) {
|
||||
//Get the Input
|
||||
const auto* input_tensor(ctx->Input<Tensor>(index));
|
||||
|
|
@ -66,34 +89,102 @@ struct ForecastingPivotTransformerImpl {
|
|||
input.push_back(typename InputType::value_type(input_data, input_dim_1, input_dim_2));
|
||||
//Increment data pointer
|
||||
input_data += input_dim_1 * input_dim_2;
|
||||
std::get<0>(inputTuple) = input_data;
|
||||
}
|
||||
|
||||
// Get the horizon vector from input, since num_pivot_columns > 0. So input is not null
|
||||
const size_t matrix_cols_num = input[0].cols();
|
||||
for (size_t col_idx = 0; col_idx < matrix_cols_num; col_idx++) {
|
||||
bool has_nan = false;
|
||||
for (int input_matrix_id = 0; input_matrix_id < num_pivot_columns; input_matrix_id++) {
|
||||
const size_t matrix_rows_num = input[input_matrix_id].rows();
|
||||
auto matrix = input[input_matrix_id];
|
||||
for (int row_id = 0; row_id < static_cast<int>(matrix_rows_num); row_id++) {
|
||||
if (std::isnan(matrix(row_id, col_idx))) {
|
||||
has_nan = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (has_nan)
|
||||
break;
|
||||
}
|
||||
if (!has_nan) {
|
||||
horizon_output_helper.push_back(static_cast<uint32_t>(matrix_cols_num - col_idx));
|
||||
}
|
||||
}
|
||||
|
||||
//Execute
|
||||
transformer.execute(std::make_tuple(input.begin(), input.end()), callback_fn);
|
||||
}
|
||||
transformer.flush(callback_fn);
|
||||
|
||||
// Prepare the Output
|
||||
TensorShape output_shape({static_cast<int64_t>(output.size()), static_cast<int64_t>(output[0].size())});
|
||||
Tensor* output_tensor(ctx->Output(0, output_shape));
|
||||
T* output_data = output_tensor->MutableData<T>();
|
||||
// Prepare the number of output rows
|
||||
ORT_ENFORCE(!output.empty(), "All rows dropped is an exception");
|
||||
int num_output_rows = static_cast<int>(output.size());
|
||||
ORT_ENFORCE(static_cast<int>(row_idx_record.size()) == num_output_rows, "row_idx_record.size() == num_output_rows");
|
||||
|
||||
for (OutputType const & row : output)
|
||||
output_data = std::copy(row.begin(), row.end(), output_data);
|
||||
// Prepare the pivoted Output
|
||||
int num_pivot_output_columns = 0;
|
||||
if (!output.empty() && !output[0].empty()) {
|
||||
num_pivot_output_columns = static_cast<int>(output[0].size());
|
||||
|
||||
for (int pivot_output_tensor_idx = 0; pivot_output_tensor_idx < num_pivot_output_columns; pivot_output_tensor_idx++) {
|
||||
TensorShape output_shape({static_cast<int64_t>(num_output_rows), 1});
|
||||
Tensor* output_tensor(ctx->Output(pivot_output_tensor_idx, output_shape));
|
||||
T* output_data = output_tensor->MutableData<T>();
|
||||
|
||||
for (int pivot_output_row_idx = 0; pivot_output_row_idx < num_output_rows; pivot_output_row_idx++){
|
||||
*output_data++ = output[pivot_output_row_idx][pivot_output_tensor_idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare the non-pivot(imputed) Output
|
||||
for (int imputed_output_count_idx = 0; imputed_output_count_idx < input_node_1_count - num_pivot_columns; imputed_output_count_idx++) {
|
||||
|
||||
int tensor_id = input_node_0_count + static_cast<int>(num_pivot_columns) + imputed_output_count_idx;
|
||||
const auto* input_tensor(ctx->Input<Tensor>(tensor_id));
|
||||
|
||||
auto input_dims = input_tensor->Shape();
|
||||
int64_t input_matrix_size = 1;
|
||||
for (size_t dim_idx = 1; dim_idx < input_dims.NumDimensions(); dim_idx++)
|
||||
input_matrix_size *= input_dims[dim_idx];
|
||||
|
||||
TensorShape output_shape_imputed({static_cast<int64_t>(num_output_rows), input_matrix_size});
|
||||
Tensor* output_tensor_imputed(ctx->Output(imputed_output_count_idx + num_pivot_output_columns, output_shape_imputed));
|
||||
|
||||
const auto elem_type = input_tensor->GetElementType();
|
||||
|
||||
utils::MLTypeCallDispatcher<CopyImputedColumnsImpl,
|
||||
int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t,
|
||||
float, double, bool, std::string> t_disp(elem_type);
|
||||
t_disp.Invoke(input_tensor, output_tensor_imputed, row_idx_record, input_matrix_size, num_output_rows);
|
||||
}
|
||||
|
||||
// Prepare the horizon Output(uint32)
|
||||
TensorShape output_shape_horizon({static_cast<int64_t>(num_output_rows), 1});
|
||||
Tensor* output_tensor_horizon(ctx->Output(input_node_1_count + num_pivot_output_columns - static_cast<int>(num_pivot_columns), output_shape_horizon));
|
||||
uint32_t* output_data_horizon = output_tensor_horizon->MutableData<uint32_t>();
|
||||
|
||||
std::copy(horizon_output_helper.begin(), horizon_output_helper.end(), output_data_horizon);
|
||||
}
|
||||
};
|
||||
|
||||
class ForecastingPivotTransformer final : public OpKernel {
|
||||
public:
|
||||
explicit ForecastingPivotTransformer(const OpKernelInfo& info) : OpKernel(info) {
|
||||
explicit ForecastingPivotTransformer(const OpKernelInfo& info) :
|
||||
OpKernel(info), _num_pivot_columns(info.GetAttrOrDefault("num_pivot_columns", static_cast<int64_t>(0))) {
|
||||
}
|
||||
|
||||
Status Compute(OpKernelContext* ctx) const override {
|
||||
utils::MLTypeCallDispatcher<ForecastingPivotTransformerImpl, float, double>
|
||||
t_disp(ctx->Input<Tensor>(1)->GetElementType());
|
||||
t_disp.Invoke(ctx);
|
||||
t_disp.Invoke(ctx, _num_pivot_columns);
|
||||
|
||||
return Status::OK();
|
||||
}
|
||||
private:
|
||||
const int64_t _num_pivot_columns;
|
||||
};
|
||||
|
||||
ONNX_OPERATOR_KERNEL_EX(
|
||||
|
|
@ -103,9 +194,18 @@ ONNX_OPERATOR_KERNEL_EX(
|
|||
kCpuExecutionProvider,
|
||||
KernelDefBuilder()
|
||||
.TypeConstraint("T0", DataTypeImpl::GetTensorType<uint8_t>())
|
||||
.TypeConstraint("T", {DataTypeImpl::GetTensorType<float>(),
|
||||
DataTypeImpl::GetTensorType<double>()
|
||||
}),
|
||||
.TypeConstraint("T", {DataTypeImpl::GetTensorType<int8_t>(),
|
||||
DataTypeImpl::GetTensorType<uint8_t>(),
|
||||
DataTypeImpl::GetTensorType<int16_t>(),
|
||||
DataTypeImpl::GetTensorType<uint16_t>(),
|
||||
DataTypeImpl::GetTensorType<int32_t>(),
|
||||
DataTypeImpl::GetTensorType<uint32_t>(),
|
||||
DataTypeImpl::GetTensorType<int64_t>(),
|
||||
DataTypeImpl::GetTensorType<uint64_t>(),
|
||||
DataTypeImpl::GetTensorType<float>(),
|
||||
DataTypeImpl::GetTensorType<double>(),
|
||||
DataTypeImpl::GetTensorType<bool>(),
|
||||
DataTypeImpl::GetTensorType<std::string>()}),
|
||||
ForecastingPivotTransformer);
|
||||
|
||||
} // namespace featurizers
|
||||
|
|
|
|||
|
|
@ -29,50 +29,135 @@ std::vector<uint8_t> GetStream() {
|
|||
} // namespace
|
||||
|
||||
TEST(FeaturizersTests, ForecastingPivotTransformer_2_Inputs) {
|
||||
auto stream = GetStream<float>();
|
||||
auto stream = GetStream<double>();
|
||||
auto dim = static_cast<int64_t>(stream.size());
|
||||
OpTester test("ForecastingPivotTransformer", 1, onnxruntime::kMSFeaturizersDomain);
|
||||
test.AddAttribute<int64_t>("num_pivot_columns", static_cast<int64_t>(2));
|
||||
test.AddInput<uint8_t>("State", {dim}, stream);
|
||||
test.AddInput<double>("Input_1", {2, 3, 4}, {1, 6, 3, 9,
|
||||
2, 4, 5, 8,
|
||||
NS::Traits<float>::CreateNullValue(), NS::Traits<float>::CreateNullValue(), 7, 10,
|
||||
1, 6, 3, 9,
|
||||
2, 4, 5, 8,
|
||||
NS::Traits<float>::CreateNullValue(), NS::Traits<float>::CreateNullValue(), 7, 10});
|
||||
test.AddInput<double>("Input_2", {2, 2, 4}, {2, NS::Traits<float>::CreateNullValue(), 5, 6,
|
||||
2, NS::Traits<float>::CreateNullValue(), 3, 4,
|
||||
2, NS::Traits<float>::CreateNullValue(), 5, 6,
|
||||
2, NS::Traits<float>::CreateNullValue(), 3, 4});
|
||||
test.AddOutput<double>("Output", {4, 5}, {3, 5, 7, 5, 3,
|
||||
9, 8, 10, 6, 4,
|
||||
3, 5, 7, 5, 3,
|
||||
9, 8, 10, 6, 4});
|
||||
NS::Traits<double>::CreateNullValue(), NS::Traits<double>::CreateNullValue(), 7, 10,
|
||||
1, 6, 9, 3,
|
||||
2, 4, 8, 5,
|
||||
NS::Traits<double>::CreateNullValue(), NS::Traits<double>::CreateNullValue(), 10, 7});
|
||||
test.AddInput<double>("Input_2", {2, 2, 4}, {2, NS::Traits<double>::CreateNullValue(), 5, 6,
|
||||
2, NS::Traits<double>::CreateNullValue(), 3, 4,
|
||||
2, NS::Traits<double>::CreateNullValue(), 5, 6,
|
||||
2, NS::Traits<double>::CreateNullValue(), 3, 4});
|
||||
test.AddOutput<double>("Output_1", {4, 1}, {3, 9, 9, 3});
|
||||
test.AddOutput<double>("Output_2", {4, 1}, {5, 8, 8, 5});
|
||||
test.AddOutput<double>("Output_3", {4, 1}, {7, 10, 10, 7});
|
||||
test.AddOutput<double>("Output_4", {4, 1}, {5, 6, 5, 6});
|
||||
test.AddOutput<double>("Output_5", {4, 1}, {3, 4, 3, 4});
|
||||
//horizon output
|
||||
test.AddOutput<uint32_t>("Output_6", {4, 1}, {2, 1, 2, 1});
|
||||
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(FeaturizersTests, ForecastingPivotTransformer_3_Inputs) {
|
||||
auto stream = GetStream<float>();
|
||||
TEST(FeaturizersTests, ForecastingPivotTransformer_4_Inputs) {
|
||||
auto stream = GetStream<double>();
|
||||
auto dim = static_cast<int64_t>(stream.size());
|
||||
OpTester test("ForecastingPivotTransformer", 1, onnxruntime::kMSFeaturizersDomain);
|
||||
test.AddAttribute<int64_t>("num_pivot_columns", static_cast<int64_t>(2));
|
||||
test.AddInput<uint8_t>("State", {dim}, stream);
|
||||
test.AddInput<double>("Input_1", {2, 3, 4}, {1, 6, 3, 9,
|
||||
2, 4, 5, 8,
|
||||
NS::Traits<float>::CreateNullValue(), NS::Traits<float>::CreateNullValue(), 7, 10,
|
||||
NS::Traits<double>::CreateNullValue(), NS::Traits<double>::CreateNullValue(), 7, 10,
|
||||
1, 6, 3, 9,
|
||||
2, 4, 5, 8,
|
||||
NS::Traits<float>::CreateNullValue(), NS::Traits<float>::CreateNullValue(), 7, 10});
|
||||
test.AddInput<double>("Input_2", {2, 2, 4}, {2, NS::Traits<float>::CreateNullValue(), 5, 6,
|
||||
2, NS::Traits<float>::CreateNullValue(), 3, 4,
|
||||
2, NS::Traits<float>::CreateNullValue(), 5, 6,
|
||||
2, NS::Traits<float>::CreateNullValue(), 3, 4});
|
||||
test.AddInput<double>("Input_3", {2, 1, 4}, {0, 0, 0, 0,
|
||||
0, 0, 0, 0});
|
||||
test.AddOutput<double>("Output", {4, 6}, {3, 5, 7, 5, 3, 0,
|
||||
9, 8, 10, 6, 4, 0,
|
||||
3, 5, 7, 5, 3, 0,
|
||||
9, 8, 10, 6, 4, 0});
|
||||
NS::Traits<double>::CreateNullValue(), NS::Traits<double>::CreateNullValue(), 7, 10});
|
||||
test.AddInput<double>("Input_2", {2, 2, 4}, {2, NS::Traits<double>::CreateNullValue(), 5, 6,
|
||||
2, NS::Traits<double>::CreateNullValue(), 3, 4,
|
||||
2, NS::Traits<double>::CreateNullValue(), 5, 6,
|
||||
2, NS::Traits<double>::CreateNullValue(), 3, 4});
|
||||
|
||||
test.AddInput<std::string>("Input_3", {2, 1, 4}, {"7", "7", "7", "7",
|
||||
"9", "9", "9", "9"});
|
||||
test.AddInput<double>("Input_4", {2, 4}, {-7, -7, -7, -7,
|
||||
-9, -9, -9, -9});
|
||||
|
||||
//pivot output
|
||||
test.AddOutput<double>("Output_1", {4, 1}, {3, 9, 3, 9});
|
||||
test.AddOutput<double>("Output_2", {4, 1}, {5, 8, 5, 8});
|
||||
test.AddOutput<double>("Output_3", {4, 1}, {7, 10, 7, 10});
|
||||
test.AddOutput<double>("Output_4", {4, 1}, {5, 6, 5, 6});
|
||||
test.AddOutput<double>("Output_5", {4, 1}, {3, 4, 3, 4});
|
||||
|
||||
//non-pivot output
|
||||
test.AddOutput<std::string>("Output_6", {4, 4}, {"7", "7", "7", "7",
|
||||
"7", "7", "7", "7",
|
||||
"9", "9", "9", "9",
|
||||
"9", "9", "9", "9"});
|
||||
test.AddOutput<double>("Output_7", {4, 4}, {-7, -7, -7, -7,
|
||||
-7, -7, -7, -7,
|
||||
-9, -9, -9, -9,
|
||||
-9, -9, -9, -9});
|
||||
//horizon output
|
||||
test.AddOutput<uint32_t>("Output_8", {4, 1}, {2, 1, 2, 1});
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(FeaturizersTests, ForecastingPivotTransformer_1_Input_1) {
|
||||
auto stream = GetStream<double>();
|
||||
auto dim = static_cast<int64_t>(stream.size());
|
||||
OpTester test("ForecastingPivotTransformer", 1, onnxruntime::kMSFeaturizersDomain);
|
||||
test.AddAttribute<int64_t>("num_pivot_columns", static_cast<int64_t>(1));
|
||||
test.AddInput<uint8_t>("State", {dim}, stream);
|
||||
test.AddInput<double>("Input_1", {2, 1, 2}, {1, 6, 3, 9});
|
||||
test.AddOutput<double>("Output_1", {4, 1}, {1, 6, 3, 9});
|
||||
|
||||
//horizon output
|
||||
test.AddOutput<uint32_t>("Output_2", {4, 1}, {2, 1, 2, 1});
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(FeaturizersTests, ForecastingPivotTransformer_1_Input_2) {
|
||||
auto stream = GetStream<double>();
|
||||
auto dim = static_cast<int64_t>(stream.size());
|
||||
OpTester test("ForecastingPivotTransformer", 1, onnxruntime::kMSFeaturizersDomain);
|
||||
test.AddAttribute<int64_t>("num_pivot_columns", static_cast<int64_t>(1));
|
||||
test.AddInput<uint8_t>("State", {dim}, stream);
|
||||
test.AddInput<double>("Input_1", {2, 1, 2}, {1, NS::Traits<double>::CreateNullValue(),
|
||||
3, 9});
|
||||
test.AddOutput<double>("Output_1", {3, 1}, {1, 3, 9});
|
||||
|
||||
//horizon output
|
||||
test.AddOutput<uint32_t>("Output_2", {3, 1}, {2, 2, 1});
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(FeaturizersTests, ForecastingPivotTransformer_1_Input_3) {
|
||||
auto stream = GetStream<double>();
|
||||
auto dim = static_cast<int64_t>(stream.size());
|
||||
OpTester test("ForecastingPivotTransformer", 1, onnxruntime::kMSFeaturizersDomain);
|
||||
test.AddAttribute<int64_t>("num_pivot_columns", static_cast<int64_t>(1));
|
||||
test.AddInput<uint8_t>("State", {dim}, stream);
|
||||
test.AddInput<double>("Input_1", {1, 3, 4}, {1, 4, 6, NS::Traits<double>::CreateNullValue(),
|
||||
2, 5, NS::Traits<double>::CreateNullValue(), NS::Traits<double>::CreateNullValue(),
|
||||
3, NS::Traits<double>::CreateNullValue(), NS::Traits<double>::CreateNullValue(), 7});
|
||||
test.AddOutput<double>("Output_1", {1, 1}, {1});
|
||||
test.AddOutput<double>("Output_2", {1, 1}, {2});
|
||||
test.AddOutput<double>("Output_3", {1, 1}, {3});
|
||||
//horizon output
|
||||
test.AddOutput<uint32_t>("Output_4", {1, 1}, {4});
|
||||
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(FeaturizersTests, ForecastingPivotTransformer_1_Input_Horizon) {
|
||||
auto stream = GetStream<double>();
|
||||
auto dim = static_cast<int64_t>(stream.size());
|
||||
OpTester test("ForecastingPivotTransformer", 1, onnxruntime::kMSFeaturizersDomain);
|
||||
test.AddAttribute<int64_t>("num_pivot_columns", static_cast<int64_t>(1));
|
||||
test.AddInput<uint8_t>("State", {dim}, stream);
|
||||
test.AddInput<double>("Input_1", {3, 1, 6}, {1, NS::Traits<double>::CreateNullValue(), 3, NS::Traits<double>::CreateNullValue(), 5, NS::Traits<double>::CreateNullValue(),
|
||||
NS::Traits<double>::CreateNullValue(), 2, 3, NS::Traits<double>::CreateNullValue(), 5, 6,
|
||||
1, 2, 3, NS::Traits<double>::CreateNullValue(), NS::Traits<double>::CreateNullValue(), NS::Traits<double>::CreateNullValue()});
|
||||
test.AddOutput<double>("Output_1", {10, 1}, {1, 3, 5, 2, 3, 5, 6, 1, 2, 3});
|
||||
|
||||
//horizon output
|
||||
test.AddOutput<uint32_t>("Output_2", {10, 1}, {6, 4, 2, 5, 4, 2, 1, 6, 5, 4});
|
||||
test.Run();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue