mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-30 20:18:08 +00:00
Add Features to ShortGrainDropper for ONNX export (#3628)
* add features to short_grain_dropper for ONNX export * update FeaturizersLibrary * fix warnings
This commit is contained in:
parent
70b554cc85
commit
7837c7efc3
3 changed files with 167 additions and 33 deletions
|
|
@ -1748,14 +1748,28 @@ void RegisterShortGrainDropperFeaturizerVer1() {
|
|||
"T0")
|
||||
.Input(
|
||||
1,
|
||||
"Input",
|
||||
"String tensor of shape [R][K].",
|
||||
"GrainInput",
|
||||
"String tensor of shape [R][K]. Grain-related tensor",
|
||||
"T1")
|
||||
.Input(
|
||||
2,
|
||||
"Input",
|
||||
"Variadic number of Input containing tensors of different size. Non-Grain-related tensors.",
|
||||
"T",
|
||||
ONNX_NAMESPACE::OpSchema::FormalParameterOption::Variadic,
|
||||
false)
|
||||
.Output(
|
||||
0,
|
||||
"GrainOutput",
|
||||
"String tensor of shape [P][K], P <= R. Grain-related tensor after imputed(dropped)",
|
||||
"T1")
|
||||
.Output(
|
||||
1,
|
||||
"Output",
|
||||
"Bool tensor of shape [R]",
|
||||
"T2")
|
||||
"Variadic number of Input containing tensors of different size. Non-Grain-related tensors after imputed(dropped).",
|
||||
"T",
|
||||
ONNX_NAMESPACE::OpSchema::FormalParameterOption::Variadic,
|
||||
false)
|
||||
.TypeConstraint(
|
||||
"T0",
|
||||
{"tensor(uint8)"},
|
||||
|
|
@ -1765,21 +1779,29 @@ void RegisterShortGrainDropperFeaturizerVer1() {
|
|||
{"tensor(string)"},
|
||||
"No information is available")
|
||||
.TypeConstraint(
|
||||
"T2",
|
||||
{"tensor(bool)"},
|
||||
"T",
|
||||
{"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) {
|
||||
propagateElemTypeFromDtypeToOutput(ctx, ONNX_NAMESPACE::TensorProto_DataType_BOOL, 0);
|
||||
propagateElemTypeFromDtypeToOutput(ctx, ONNX_NAMESPACE::TensorProto_DataType_STRING, 0);
|
||||
if (hasInputShape(ctx, 1)) {
|
||||
const auto& input_shape = getInputShape(ctx, 1);
|
||||
if (input_shape.dim_size() != 2) {
|
||||
fail_shape_inference("Expecting Input1 to have 2 dimensions");
|
||||
}
|
||||
ONNX_NAMESPACE::TensorShapeProto shape;
|
||||
*shape.add_dim() = input_shape.dim(0);
|
||||
shape.add_dim();
|
||||
*shape.add_dim() = input_shape.dim(1);
|
||||
ONNX_NAMESPACE::updateOutputShape(ctx, 0, shape);
|
||||
}
|
||||
if (hasInputShape(ctx, 2)) {
|
||||
const auto& input_shape = getInputShape(ctx, 2);
|
||||
if (input_shape.dim_size() != 2) {
|
||||
fail_shape_inference("Expecting Input2 to have 2 dimensions");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,22 @@ namespace NS = Microsoft::Featurizer;
|
|||
namespace onnxruntime {
|
||||
namespace featurizers {
|
||||
|
||||
template <typename T>
|
||||
struct CopyNonDroppedColumnsImpl {
|
||||
void operator()(const Tensor* variadic_input_tensor, Tensor* output_after_drop_tensor,
|
||||
const std::vector<bool>& rows_to_drop, int64_t input_row_size) const {
|
||||
const T* input_data(variadic_input_tensor->template Data<T>());
|
||||
T* output_after_drop_data = output_after_drop_tensor->MutableData<T>();
|
||||
|
||||
for (int row_idx = 0; row_idx < static_cast<int>(rows_to_drop.size()); ++row_idx) {
|
||||
if (!rows_to_drop[row_idx]) {
|
||||
output_after_drop_data = std::copy(input_data, input_data + input_row_size, output_after_drop_data);
|
||||
}
|
||||
input_data += input_row_size;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void ShortGrainDropperTransformerImpl(OpKernelContext* ctx) {
|
||||
// Create the transformer
|
||||
Microsoft::Featurizer::Featurizers::ShortGrainDropperTransformer transformer(
|
||||
|
|
@ -23,26 +39,61 @@ void ShortGrainDropperTransformerImpl(OpKernelContext* ctx) {
|
|||
return Microsoft::Featurizer::Featurizers::ShortGrainDropperTransformer(archive);
|
||||
}());
|
||||
|
||||
// Get the input
|
||||
// Get the Grain input
|
||||
const auto* input_tensor = ctx->Input<Tensor>(1);
|
||||
const std::string* input_data = input_tensor->template Data<std::string>();
|
||||
|
||||
// Prepare the output
|
||||
const int64_t input_rows_num = input_tensor->Shape()[0];
|
||||
const int64_t strings_num = input_tensor->Shape()[1];
|
||||
TensorShape rows_shape({input_rows_num});
|
||||
Tensor* output_tensor(ctx->Output(0, rows_shape));
|
||||
bool* output_data(output_tensor->MutableData<bool>());
|
||||
|
||||
// Transform
|
||||
ORT_ENFORCE(input_rows_num > 0, "input_rows_num > 0");
|
||||
|
||||
// Record which row to drop
|
||||
std::vector<bool> rows_to_drop;
|
||||
// Transform
|
||||
std::vector<std::string> input_data_vec;
|
||||
input_data_vec.reserve(strings_num);
|
||||
for (int64_t rows_idx = 0; rows_idx < input_rows_num; ++rows_idx) {
|
||||
input_data_vec.clear();
|
||||
std::copy(input_data, input_data + strings_num, std::back_inserter(input_data_vec));
|
||||
output_data[rows_idx] = transformer.execute(input_data_vec);
|
||||
rows_to_drop.push_back(transformer.execute(input_data_vec));
|
||||
input_data += strings_num;
|
||||
}
|
||||
|
||||
// Calculate number of remaining rows
|
||||
int remaining_rows_num = static_cast<int>(std::count(rows_to_drop.begin(), rows_to_drop.end(), false));
|
||||
|
||||
ORT_ENFORCE(remaining_rows_num > 0, "remaining_rows_num > 0");
|
||||
|
||||
// Prepare the Grain output
|
||||
TensorShape grain_output_shape({remaining_rows_num, strings_num});
|
||||
Tensor* grain_output_tensor(ctx->Output(0, grain_output_shape));
|
||||
std::string* grain_output_data(grain_output_tensor->MutableData<std::string>());
|
||||
const std::string* input_grain_data = input_tensor->template Data<std::string>();
|
||||
for (int rows_idx = 0; rows_idx < static_cast<int>(input_rows_num); ++rows_idx) {
|
||||
if (!rows_to_drop[rows_idx]) {
|
||||
grain_output_data = std::copy(input_grain_data, input_grain_data + strings_num, grain_output_data);
|
||||
}
|
||||
input_grain_data += strings_num;
|
||||
}
|
||||
|
||||
// Prepare other outputs. input(2)->output(1), input(3)->output(2), ...
|
||||
const int variadic_input_start_id = ctx->NumVariadicInputs(0) + ctx->NumVariadicInputs(1);
|
||||
const int variadic_input_end_id = variadic_input_start_id + ctx->NumVariadicInputs(2);
|
||||
for (int input_id = variadic_input_start_id; input_id < variadic_input_end_id; ++input_id) {
|
||||
|
||||
const auto* variadic_input_tensor(ctx->Input<Tensor>(input_id)); //2-d tensor
|
||||
const int64_t input_row_size = variadic_input_tensor->Shape()[1];
|
||||
|
||||
TensorShape output_after_drop_shape({static_cast<int64_t>(remaining_rows_num), input_row_size});
|
||||
Tensor* output_after_drop_tensor(ctx->Output(input_id - 1, output_after_drop_shape));
|
||||
|
||||
const auto elem_type = variadic_input_tensor->GetElementType();
|
||||
|
||||
utils::MLTypeCallDispatcher<CopyNonDroppedColumnsImpl,
|
||||
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(variadic_input_tensor, output_after_drop_tensor, rows_to_drop, input_row_size);
|
||||
}
|
||||
};
|
||||
|
||||
class ShortGrainDropperTransformer final : public OpKernel {
|
||||
|
|
@ -62,7 +113,19 @@ ONNX_OPERATOR_KERNEL_EX(
|
|||
kCpuExecutionProvider,
|
||||
KernelDefBuilder()
|
||||
.TypeConstraint("T0", DataTypeImpl::GetTensorType<uint8_t>())
|
||||
.TypeConstraint("T1", DataTypeImpl::GetTensorType<std::string>()),
|
||||
.TypeConstraint("T1", DataTypeImpl::GetTensorType<std::string>())
|
||||
.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>()}),
|
||||
ShortGrainDropperTransformer);
|
||||
|
||||
} // namespace featurizers
|
||||
|
|
|
|||
|
|
@ -25,27 +25,27 @@ std::vector<uint8_t> GetStream(EstimatorT& estimator, const std::vector<std::vec
|
|||
|
||||
} // namespace
|
||||
|
||||
TEST(FeaturizersTests, ShortGrainDropperTransformer_Has_CV) {
|
||||
TEST(FeaturizersTests, ShortGrainDropperTransformer_Min_4) {
|
||||
|
||||
EstimatorT estimator(NS::CreateTestAnnotationMapsPtr(1), 0, 4);
|
||||
|
||||
std::vector<std::vector<std::vector<std::string>>> trainingBatches = NS::TestHelpers::make_vector<std::vector<std::vector<std::string>>>(
|
||||
NS::TestHelpers::make_vector<std::vector<std::string>>(
|
||||
NS::TestHelpers::make_vector<std::string>("a", "b"), //false
|
||||
NS::TestHelpers::make_vector<std::string>("a", "b"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "b"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "b"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "b"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "b"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "c"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "c"), //false
|
||||
NS::TestHelpers::make_vector<std::string>("a", "c"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "c"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "c"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "d"), //true
|
||||
NS::TestHelpers::make_vector<std::string>("a", "d"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "d"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "d"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "e"), //true
|
||||
NS::TestHelpers::make_vector<std::string>("a", "e"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "e"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "f")
|
||||
NS::TestHelpers::make_vector<std::string>("a", "f") //true
|
||||
)
|
||||
);
|
||||
|
||||
|
|
@ -53,33 +53,38 @@ TEST(FeaturizersTests, ShortGrainDropperTransformer_Has_CV) {
|
|||
auto dim = static_cast<int64_t>(stream.size());
|
||||
OpTester test("ShortGrainDropperTransformer", 1, onnxruntime::kMSFeaturizersDomain);
|
||||
test.AddInput<uint8_t>("State", {dim}, stream);
|
||||
test.AddInput<std::string>("Input", {6, 2}, {"a", "b", "a", "c", "a", "d", "a", "e", "a", "f", "a", "g"});
|
||||
test.AddOutput<bool>("Output", {6}, {false, false, true, true, true, true});
|
||||
test.AddInput<std::string>("GrainInput", {6, 2}, {"a", "b", "a", "c", "a", "d", "a", "e", "a", "f", "a", "g"});
|
||||
test.AddInput<std::string>("Non_GrainInput_1", {6, 2}, {"c", "c", "d", "d", "e", "e", "e", "e", "e", "e", "e", "e"});
|
||||
test.AddInput<double>("Non_GrainInput_2", {6, 1}, {1, 2, 3, 4, 5, 6});
|
||||
|
||||
test.AddOutput<std::string>("GrainOutput", {2, 2}, {"a", "b", "a", "c"});
|
||||
test.AddOutput<std::string>("Non_GrainOutput_1", {2, 2}, {"c", "c", "d", "d"});
|
||||
test.AddOutput<double>("Non_GrainOutput_2", {2, 1}, {1, 2});
|
||||
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(FeaturizersTests, ShortGrainDropperTransformer_No_CV) {
|
||||
TEST(FeaturizersTests, ShortGrainDropperTransformer_Min_3) {
|
||||
|
||||
EstimatorT estimator(NS::CreateTestAnnotationMapsPtr(1), 0, 3);
|
||||
|
||||
std::vector<std::vector<std::vector<std::string>>> trainingBatches = NS::TestHelpers::make_vector<std::vector<std::vector<std::string>>>(
|
||||
NS::TestHelpers::make_vector<std::vector<std::string>>(
|
||||
NS::TestHelpers::make_vector<std::string>("a", "b"), //false
|
||||
NS::TestHelpers::make_vector<std::string>("a", "b"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "b"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "b"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "b"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "b"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "c"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "c"), //false
|
||||
NS::TestHelpers::make_vector<std::string>("a", "c"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "c"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "c"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "d"), //false
|
||||
NS::TestHelpers::make_vector<std::string>("a", "d"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "d"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "d"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "e"), //true
|
||||
NS::TestHelpers::make_vector<std::string>("a", "e"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "e"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "f")
|
||||
NS::TestHelpers::make_vector<std::string>("a", "f") //true
|
||||
)
|
||||
);
|
||||
|
||||
|
|
@ -87,8 +92,52 @@ TEST(FeaturizersTests, ShortGrainDropperTransformer_No_CV) {
|
|||
auto dim = static_cast<int64_t>(stream.size());
|
||||
OpTester test("ShortGrainDropperTransformer", 1, onnxruntime::kMSFeaturizersDomain);
|
||||
test.AddInput<uint8_t>("State", {dim}, stream);
|
||||
test.AddInput<std::string>("Input", {6, 2}, {"a", "b", "a", "c", "a", "d", "a", "e", "a", "f", "a", "g"});
|
||||
test.AddOutput<bool>("Output", {6}, {false, false, false, true, true, true});
|
||||
test.AddInput<std::string>("GrainInput", {6, 2}, {"a", "b", "a", "c", "a", "d", "a", "e", "a", "f", "a", "g"});
|
||||
test.AddInput<std::string>("Non_GrainInput_1", {6, 2}, {"c", "c", "d", "d", "e", "e", "e", "e", "e", "e", "e", "e"});
|
||||
test.AddInput<double>("Non_GrainInput_2", {6, 1}, {1, 2, 3, 4, 5, 6});
|
||||
|
||||
test.AddOutput<std::string>("GrainOutput", {3, 2}, {"a", "b", "a", "c", "a", "d"});
|
||||
test.AddOutput<std::string>("Non_GrainOutput_1", {3, 2}, {"c", "c", "d", "d", "e", "e"});
|
||||
test.AddOutput<double>("Non_GrainOutput_2", {3, 1}, {1, 2, 3});
|
||||
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(FeaturizersTests, ShortGrainDropperTransformer_Min_2) {
|
||||
|
||||
EstimatorT estimator(NS::CreateTestAnnotationMapsPtr(1), 0, 2);
|
||||
|
||||
std::vector<std::vector<std::vector<std::string>>> trainingBatches = NS::TestHelpers::make_vector<std::vector<std::vector<std::string>>>(
|
||||
NS::TestHelpers::make_vector<std::vector<std::string>>(
|
||||
NS::TestHelpers::make_vector<std::string>("a", "b"), //false
|
||||
NS::TestHelpers::make_vector<std::string>("a", "b"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "b"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "b"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "b"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "c"), //false
|
||||
NS::TestHelpers::make_vector<std::string>("a", "c"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "c"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "c"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "d"), //false
|
||||
NS::TestHelpers::make_vector<std::string>("a", "d"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "d"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "e"), //false
|
||||
NS::TestHelpers::make_vector<std::string>("a", "e"),
|
||||
NS::TestHelpers::make_vector<std::string>("a", "f") //true
|
||||
)
|
||||
);
|
||||
|
||||
auto stream = GetStream(estimator, trainingBatches);
|
||||
auto dim = static_cast<int64_t>(stream.size());
|
||||
OpTester test("ShortGrainDropperTransformer", 1, onnxruntime::kMSFeaturizersDomain);
|
||||
test.AddInput<uint8_t>("State", {dim}, stream);
|
||||
test.AddInput<std::string>("GrainInput", {6, 2}, {"a", "b", "a", "c", "a", "d", "a", "e", "a", "f", "a", "g"});
|
||||
test.AddInput<std::string>("Non_GrainInput_1", {6, 2}, {"c", "c", "d", "d", "e", "e", "e", "e", "e", "e", "e", "e"});
|
||||
test.AddInput<double>("Non_GrainInput_2", {6, 1}, {1, 2, 3, 4, 5, 6});
|
||||
|
||||
test.AddOutput<std::string>("GrainOutput", {4, 2}, {"a", "b", "a", "c", "a", "d", "a", "e"});
|
||||
test.AddOutput<std::string>("Non_GrainOutput_1", {4, 2}, {"c", "c", "d", "d", "e", "e", "e", "e"});
|
||||
test.AddOutput<double>("Non_GrainOutput_2", {4, 1}, {1, 2, 3, 4});
|
||||
|
||||
test.Run();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue