mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-12 17:57:38 +00:00
CPU GRU and LSTM Ops: Address corner case where output is uninitialized (#1193)
* Updated CPU GRU to zero Y output between max specified sequence length and max sequence length implied by input shape. * Updated CPU LSTM to zero Y output between max specified sequence length and max sequence length implied by input shape. * Disabled LSTMTest.ONNXRuntime_TestLSTMSequenceLengthShorterThanInputSequenceLength for nGraph execution provider and added TODO to investigate failure.
This commit is contained in:
parent
24d6b0f5c4
commit
0b9b429fe1
4 changed files with 94 additions and 4 deletions
|
|
@ -808,6 +808,20 @@ void UniDirectionalGru<T>::Compute(const gsl::span<const T>& inputs_arg,
|
|||
}
|
||||
}
|
||||
|
||||
// zero any values beyond the evaluated steps
|
||||
if (output_sequence && max_sequence_length < seq_length_) {
|
||||
if (output_step_length == batch_size_ * hidden_size_) { // contiguous
|
||||
const auto span_to_zero = outputs.subspan(
|
||||
max_sequence_length * output_step_length, (seq_length_ - max_sequence_length) * output_step_length);
|
||||
std::fill_n(span_to_zero.begin(), span_to_zero.size(), T{});
|
||||
} else {
|
||||
for (int i = max_sequence_length; i < seq_length_; ++i) { // non-contiguous
|
||||
const auto span_to_zero = outputs.subspan(i * output_step_length, batch_size_ * hidden_size_);
|
||||
std::fill_n(span_to_zero.begin(), span_to_zero.size(), T{});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (output_sequence && direction_ == kReverse) {
|
||||
ReverseSequence<T>(outputs, original_outputs,
|
||||
sequence_lengths, seq_length_,
|
||||
|
|
|
|||
|
|
@ -971,6 +971,20 @@ void UniDirectionalLstm<T>::Compute(const gsl::span<const T>& inputs_arg,
|
|||
}
|
||||
}
|
||||
|
||||
// zero any values beyond the evaluated steps
|
||||
if (output_sequence && max_sequence_length < seq_length_) {
|
||||
if (output_step_length == batch_size_ * hidden_size_) { // contiguous
|
||||
const auto span_to_zero = outputs.subspan(
|
||||
max_sequence_length * output_step_length, (seq_length_ - max_sequence_length) * output_step_length);
|
||||
std::fill_n(span_to_zero.begin(), span_to_zero.size(), T{});
|
||||
} else {
|
||||
for (int i = max_sequence_length; i < seq_length_; ++i) { // non-contiguous
|
||||
const auto span_to_zero = outputs.subspan(i * output_step_length, batch_size_ * hidden_size_);
|
||||
std::fill_n(span_to_zero.begin(), span_to_zero.size(), T{});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (output_sequence && direction_ == Direction::kReverse)
|
||||
ReverseSequence<T>(outputs, original_outputs, sequence_lengths, seq_length_,
|
||||
batch_size_, hidden_size_, num_directions);
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ void DefaultActivationsSimpleWeightsWithBias(std::string direction,
|
|||
|
||||
RunGruTest(X_data, W_data, R_data, Y_data, {}, input_size, batch_size, hidden_size, seq_length,
|
||||
&B_data, nullptr, nullptr, direction, 999.f, /* output_sequence*/ true, linear_before_reset);
|
||||
} // namespace test
|
||||
}
|
||||
|
||||
TEST(GRUTest, ForwardDefaultActivationsSimpleWeightsWithBiasBatchParallel) {
|
||||
std::vector<float> Y_data{
|
||||
|
|
@ -336,7 +336,7 @@ class DeepCpuGruOpTestContext {
|
|||
std::vector<float> gru_input_weights_;
|
||||
std::vector<float> gru_recurrent_weights_;
|
||||
std::vector<float> gru_bias_;
|
||||
}; // namespace test
|
||||
};
|
||||
|
||||
DeepCpuGruOpTestContext::DeepCpuGruOpTestContext(const std::string direction,
|
||||
const std::vector<std::string>& activations,
|
||||
|
|
@ -459,7 +459,7 @@ void DeepCpuGruOpTestContext::RunTest(const std::vector<float>& X,
|
|||
const std::vector<float>& expected_Y,
|
||||
const std::vector<float>& expected_Y_h,
|
||||
const bool linear_before_reset) {
|
||||
//run with and without output_sequence
|
||||
//run with and without output_sequence
|
||||
::onnxruntime::test::RunGruTest(X, gru_input_weights_, gru_recurrent_weights_,
|
||||
expected_Y, expected_Y_h,
|
||||
input_size_, batch_size, hidden_dim_, seq_length,
|
||||
|
|
@ -469,7 +469,7 @@ void DeepCpuGruOpTestContext::RunTest(const std::vector<float>& X,
|
|||
direction_,
|
||||
9999999999.f,
|
||||
/*output_sequence*/ true,
|
||||
linear_before_reset,
|
||||
linear_before_reset,
|
||||
activation_func_names_,
|
||||
alphas_,
|
||||
betas_);
|
||||
|
|
@ -819,6 +819,35 @@ TEST(GRUTest, ONNXRuntime_TestGRUOpSequenceLengthWithPartialZero) {
|
|||
ctx.RunTest(X, batch_size, seq_length, sequence_length, &initial_h, expected_Y, expected_Y_h);
|
||||
}
|
||||
|
||||
TEST(GRUTest, ONNXRuntime_TestGRUOpSequenceLengthShorterThanInputSequenceLength) {
|
||||
const std::string direction = "bidirectional";
|
||||
const std::vector<std::string> activations = {"sigmoid", "tanh", "sigmoid", "tanh"};
|
||||
|
||||
DeepCpuGruOpTestContext ctx(direction, activations);
|
||||
|
||||
const int batch = 1;
|
||||
const int seq_length = 2;
|
||||
|
||||
std::vector<float> X = {-0.455351f, -0.276391f,
|
||||
-0.185934f, -0.269585f};
|
||||
|
||||
std::vector<int> sequence_lengths = {1};
|
||||
|
||||
std::vector<float> initial_h = {0.0f, 0.0f,
|
||||
-0.04566499f, 0.04621252f};
|
||||
|
||||
std::vector<float> expected_Y = {-0.03255286f, 0.0774838f,
|
||||
-0.05469977f, 0.1004222f,
|
||||
|
||||
0.0f, 0.0f,
|
||||
0.0f, 0.0f};
|
||||
|
||||
std::vector<float> expected_Y_h = {-0.03255286f, 0.0774838f,
|
||||
-0.05469977f, 0.1004222f};
|
||||
|
||||
ctx.RunTest(X, batch, seq_length, sequence_lengths, &initial_h, expected_Y, expected_Y_h);
|
||||
}
|
||||
|
||||
TEST(GRUTest, ONNXRuntime_TestGRUOpSequenceLengthAllZeros) {
|
||||
const std::string direction = "forward";
|
||||
const std::vector<std::string> activations = {"sigmoid", "tanh"};
|
||||
|
|
|
|||
|
|
@ -1059,5 +1059,38 @@ TEST(LSTMTest, ONNXRuntime_TestLSTMSequenceLengthPartialZeros) {
|
|||
&sequence_length, use_bias, use_peepholes);
|
||||
}
|
||||
|
||||
// TODO this test fails for nGraph - need to investigate why
|
||||
#ifndef USE_NGRAPH
|
||||
TEST(LSTMTest, ONNXRuntime_TestLSTMSequenceLengthShorterThanInputSequenceLength) {
|
||||
const int seq_len = 2;
|
||||
const int batch_size = 1;
|
||||
|
||||
std::vector<float> X_data = {-0.455351f, -0.276391f,
|
||||
-0.185934f, -0.269585f};
|
||||
|
||||
std::vector<int> sequence_length = {1};
|
||||
|
||||
std::vector<float> initial_h = {0.0f, 0.0f,
|
||||
-0.0306872f, 0.028035f};
|
||||
|
||||
std::vector<float> initial_c = {0.0f, 0.0f,
|
||||
-0.07243599f, 0.0467052f};
|
||||
|
||||
std::vector<float> Y_data = {-0.0251062f, 0.0561262f,
|
||||
-0.0318928f, 0.0762679f,
|
||||
|
||||
0.0f, 0.0f,
|
||||
0.0f, 0.0f};
|
||||
|
||||
std::vector<float> Y_h_data = {-0.0251062f, 0.0561262f,
|
||||
-0.0318928f, 0.0762679f};
|
||||
|
||||
std::string direction = "bidirectional";
|
||||
|
||||
LstmOpContext2x1x2x2 context(direction);
|
||||
context.RunTest(X_data, batch_size, seq_len, &initial_h, &initial_c, Y_data, Y_h_data, {}, &sequence_length);
|
||||
}
|
||||
#endif // USE_NGRAPH
|
||||
|
||||
} // namespace test
|
||||
} // namespace onnxruntime
|
||||
|
|
|
|||
Loading…
Reference in a new issue