diff --git a/README/ReleaseNotes/v642/index.md b/README/ReleaseNotes/v642/index.md index 284cce2292028..84d9da67a7ba8 100644 --- a/README/ReleaseNotes/v642/index.md +++ b/README/ReleaseNotes/v642/index.md @@ -49,6 +49,7 @@ The following people have contributed to this new version: * Several enums that are redundant with `ROOT::ESTLType` are deprecated and will be removed in ROOT 6.44: `TClassEdit::ESTLType`, `TDictionary::ESTLType`, `TStreamerElement::ESTLType`. Please use `ROOT::ESTLType` instead. * The inclusion by external projects of Makefile templates contained within ROOT is deprecated in 6.42, a warning will be raised if you use them. These files will be removed in ROOT 7. * The conversion from Python set to **RooArgSet** is deprecated and won't work anymore in ROOT 6.44. The problem is that Python sets are unordered while RooArgSets are ordered, and this mismatch can lead to subtle problems later on. Prefer conversion from Python lists or tuples, which are ordered too. +* The ROOT IO capability for the `TMVA::Experimental::SOFIE::RModel` has been removed. Users should not be encouraged to serialize models in experimental classes. For the serialization of ONNX models one can already use ONNX directly, and even serialize the ONNX bytes to a ROOT file if required. ## Python Interface diff --git a/tmva/sofie/inc/LinkDef.h b/tmva/sofie/inc/LinkDef.h index 734d04aebd630..d9caa90f7e687 100644 --- a/tmva/sofie/inc/LinkDef.h +++ b/tmva/sofie/inc/LinkDef.h @@ -9,7 +9,7 @@ #pragma link C++ namespace TMVA::Experimental::SOFIE; #pragma link C++ class TMVA::Experimental::SOFIE::RModel_Base+; -#pragma link C++ class TMVA::Experimental::SOFIE::RModel-; +#pragma link C++ class TMVA::Experimental::SOFIE::RModel+; #pragma link C++ class TMVA::Experimental::SOFIE::ROperator+; #pragma link C++ struct TMVA::Experimental::SOFIE::InitializedTensor+; #pragma link C++ struct TMVA::Experimental::SOFIE::TensorInfo+; diff --git a/tmva/sofie/inc/TMVA/RModel.hxx b/tmva/sofie/inc/TMVA/RModel.hxx index ab03b39fb49a6..7812e4a61087f 100644 --- a/tmva/sofie/inc/TMVA/RModel.hxx +++ b/tmva/sofie/inc/TMVA/RModel.hxx @@ -234,8 +234,8 @@ public: } bool UseVDT() const { return fUseVDT;} - // Use the ClassDef macro to allow definition of custom streaming - ClassDefNV(RModel, 4); + // RModel is an internal representation that doesn't support ROOT IO (if you need model IO, use ONNX directly). + ClassDefNV(RModel, 0); }; // need to implement here templated member functions and its specialization diff --git a/tmva/sofie/inc/TMVA/SOFIE_common.hxx b/tmva/sofie/inc/TMVA/SOFIE_common.hxx index e8fbc6ee82720..09f247eed24d2 100644 --- a/tmva/sofie/inc/TMVA/SOFIE_common.hxx +++ b/tmva/sofie/inc/TMVA/SOFIE_common.hxx @@ -312,49 +312,12 @@ public: return static_cast(fData.get()); } - void CastSharedToPersistent() - { - // We only calculate fSize here, because it is only used for IO to know - // the size of the persistent data. - fSize = 1; - for (std::size_t item : fShape) { - fSize *= static_cast(item); - } - // get size in bytes - fSize *= GetTypeSize(fType); - fPersistentData = static_cast(fData.get()); - } - void CastPersistentToShared() - { - // If there is no persistent data, do nothing - if (fSize == 0 || fPersistentData == nullptr) { - return; - } - - // Nothing to be done if the pointed-to data is the same - if (fPersistentData == static_cast(fData.get())) { - return; - } - - // Initialize the shared_ptr - fData = std::shared_ptr{malloc(fSize), free}; - std::memcpy(fData.get(), fPersistentData, fSize); - - // Make sure the data read from disk doesn't leak and delete the - // persistent data - delete[] fPersistentData; - fPersistentData = nullptr; - fSize = 0; - } - private: bool fConstant = false; ///< Flag specifying if tensor is a Constant one (coming from a Constant operator) bool fIsNotWritable = false; ///< Flag to indicate that tensor values do not need to be written as weight or generated code ETensorType fType; ///< Encodes the type of the data std::vector fShape; ///< The shape of the data in terms of elements in each dimension std::shared_ptr fData; /// diff --git a/tmva/sofie/src/RModel.cxx b/tmva/sofie/src/RModel.cxx index 15b3af4a9678d..624914d1cbbee 100644 --- a/tmva/sofie/src/RModel.cxx +++ b/tmva/sofie/src/RModel.cxx @@ -1978,19 +1978,4 @@ void RModel::OutputGenerated(std::string filename, bool append) { } } -void RModel::Streamer(TBuffer &R__b) { - if (R__b.IsReading()) { - RModel::Class()->ReadBuffer(R__b, this); - for (auto & i : fInitializedTensors) { - i.second.CastPersistentToShared(); - } - } - else { - for (auto & i : fInitializedTensors) { - i.second.CastSharedToPersistent(); - } - RModel::Class()->WriteBuffer(R__b, this); - } -} - } // namespace SOFIE::Experimental::TMVA diff --git a/tmva/sofie/test/CMakeLists.txt b/tmva/sofie/test/CMakeLists.txt index 2012cb32b90a0..9c29fbc6e474d 100644 --- a/tmva/sofie/test/CMakeLists.txt +++ b/tmva/sofie/test/CMakeLists.txt @@ -30,7 +30,6 @@ foreach(onnx_file ${ONNX_FILES}) endforeach() string(REPLACE ";" ";\n" EMIT_CAPTURES "${ALL_CAPTURES}") configure_file(EmitFromONNX.cxx.in EmitFromONNX_all.cxx @ONLY) -configure_file(EmitFromRoot.cxx.in EmitFromRoot_all.cxx @ONLY) ROOTTEST_GENERATE_EXECUTABLE(emitFromONNX EmitFromONNX_all.cxx LIBRARIES protobuf::libprotobuf ROOTTMVASofie ROOTTMVASofieParser @@ -64,34 +63,7 @@ if (BLAS_FOUND) # we need BLAS for compiling the models endif() endif() -# For testing serialisation of RModel object - -ROOTTEST_GENERATE_EXECUTABLE(emitFromROOT EmitFromRoot_all.cxx - LIBRARIES protobuf::libprotobuf RIO ROOTTMVASofie ROOTTMVASofieParser - FIXTURES_SETUP sofie-compile-models-onnx-root -) -# silence protobuf warnings seen in version 3.0 and 3.6. Not needed from protobuf version 3.17 -target_compile_options(emitFromROOT PRIVATE -Wno-unused-parameter -Wno-array-bounds) - -# Automatic compilation of headers from root files -ROOTTEST_ADD_TEST(SofieCompileModels_ROOT - COMMAND ${CMAKE_COMMAND} -E env ROOTIGNOREPREFIX=1 ./emitFromROOT - FIXTURES_REQUIRED sofie-compile-models-onnx-root - FIXTURES_SETUP sofie-compile-models-root -) - if (BLAS_FOUND) - # Creating a Google Test for Serialisation of RModel - ROOT_EXECUTABLE(TestCustomModelsFromROOT TestCustomModelsFromROOT.cxx - LIBRARIES - Core - GTest::gtest - GTest::gtest_main - ) - ROOTTEST_ADD_TEST(TestCustomModelsFromROOT - EXEC ./TestCustomModelsFromROOT - FIXTURES_REQUIRED sofie-compile-models-root) - if (clad) # Creating a Google Test for the automatic differentiation of Gemm_Call ROOT_ADD_GTEST(TestGemmDerivative TestGemmDerivative.cxx LIBRARIES Core BLAS::BLAS) diff --git a/tmva/sofie/test/EmitFromRoot.cxx.in b/tmva/sofie/test/EmitFromRoot.cxx.in deleted file mode 100644 index af5d1b20e4715..0000000000000 --- a/tmva/sofie/test/EmitFromRoot.cxx.in +++ /dev/null @@ -1,48 +0,0 @@ -// Author: Sanjiban Sengupta, 2021 -// Description: -// This is to test the Serialisation of RModel class -// defined in SOFIE. The program is run when the -// target 'TestCustomModelsFromROOT' is built. The program -// generates the required .hxx file after reading a written -// ROOT file which stores the object of the RModel class. - -#include "TMVA/RModel.hxx" -#include "TMVA/RModelParser_ONNX.hxx" -#include "TFile.h" - -using namespace TMVA::Experimental::SOFIE; - -int EmitModel(std::string inputfile, std::string outname){ - - RModelParser_ONNX parser; - RModel model = parser.Parse(inputfile); - TFile fileWrite((outname+"_FromROOT.root").c_str(),"RECREATE"); - fileWrite.WriteObject(&model, "model"); - fileWrite.Close(); - TFile fileRead((outname+"_FromROOT.root").c_str(),"READ"); - RModel *modelPtr; - fileRead.GetObject("model",modelPtr); - fileRead.Close(); - if (outname.find("Linear_") != std::string::npos) { - // use Session and weight file for linear model with large weights - if (outname.find("Linear_32") != std::string::npos) return 0; // skip test - if (outname.find("Linear_64") != std::string::npos) return 0; // skip test - modelPtr->Generate(Options::kRootBinaryWeightFile); - } - else if (outname.find("LinearWith") != std::string::npos) { - // in this case we don't write session class but not weight file - modelPtr->Generate(Options::kNoWeightFile); - } - else { - // in this case we don't write session class and not weight file - modelPtr->Generate(Options::kNoSession | Options::kNoWeightFile); - } - modelPtr->OutputGenerated(outname+"_FromROOT.hxx"); - return 0; -} - -int main(int argc, char *argv[]){ - -@EMIT_CAPTURES@ ; - -} diff --git a/tmva/sofie/test/TestCustomModelsFromROOT.cxx b/tmva/sofie/test/TestCustomModelsFromROOT.cxx deleted file mode 100644 index b95a7b3290908..0000000000000 --- a/tmva/sofie/test/TestCustomModelsFromROOT.cxx +++ /dev/null @@ -1,859 +0,0 @@ -constexpr auto modelHeaderSuffix = "_FromROOT.hxx"; -constexpr auto modelDataSuffix = "_FromROOT.root"; -#include "test_helpers.h" - -#include "input_models/references/Linear_16.ref.hxx" -// #include "input_models/references/Linear_32.ref.hxx" -// #include "input_models/references/Linear_64.ref.hxx" -#include "input_models/references/LinearWithSelu.ref.hxx" -#include "input_models/references/LinearWithSigmoid.ref.hxx" -#include "input_models/references/ConvWithPadding.ref.hxx" -#include "input_models/references/ConvWithoutPadding.ref.hxx" -#include "input_models/references/ConvWithAutopadSameLower.ref.hxx" -#include "input_models/references/ConvWithStridesPadding.ref.hxx" -#include "input_models/references/ConvWithStridesNoPadding.ref.hxx" -#include "input_models/references/ConvWithAsymmetricPadding.ref.hxx" -#include "input_models/references/RNNBatchwise.ref.hxx" -#include "input_models/references/RNNBidirectional.ref.hxx" -#include "input_models/references/RNNBidirectionalBatchwise.ref.hxx" -#include "input_models/references/RNNDefaults.ref.hxx" -#include "input_models/references/RNNSeqLength.ref.hxx" -#include "input_models/references/RNNSequence.ref.hxx" -#include "input_models/references/RNNSequenceBatchwise.ref.hxx" -#include "input_models/references/LSTMBatchwise.ref.hxx" -#include "input_models/references/LSTMBidirectional.ref.hxx" -#include "input_models/references/LSTMDefaults.ref.hxx" -#include "input_models/references/LSTMInitialBias.ref.hxx" -#include "input_models/references/LSTMPeepholes.ref.hxx" -#include "input_models/references/GRUBatchwise.ref.hxx" -#include "input_models/references/GRUBidirectional.ref.hxx" -#include "input_models/references/GRUDefaults.ref.hxx" -#include "input_models/references/GRUInitialBias.ref.hxx" -#include "input_models/references/GRUSeqLength.ref.hxx" -#include "input_models/references/RangeFloat.ref.hxx" -#include "input_models/references/RangeInt.ref.hxx" - -#include "gtest/gtest.h" - -TEST(ROOT, Linear16) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(1600); - std::fill_n(input.data(), input.size(), 1.0f); - - ASSERT_INCLUDE_AND_RUN(std::vector, "Linear_16", input); - - // Testing the actual and expected output sizes - EXPECT_EQ(output.size(), std::size(Linear_16_ExpectedOutput::all_ones)); - - float *correct = Linear_16_ExpectedOutput::all_ones; - - // Testing the actual and expected output values - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); - } -} - -/* -TEST(ROOT, Linear32) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(3200); - std::fill_n(input.data(), input.size(), 1.0f); - ASSERT_INCLUDE_AND_RUN(std::vector, "Linear_32", input); - - // Testing the actual and expected output sizes - EXPECT_EQ(output.size(), std::size(Linear_32_ExpectedOutput::all_ones)); - - float *correct = Linear_32_ExpectedOutput::all_ones; - - // Testing the actual and expected output values - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); - } -} - - -TEST(ROOT, Linear64) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(6400); - std::fill_n(input.data(), input.size(), 1.0f); - ASSERT_INCLUDE_AND_RUN(std::vector, "Linear_64", input); - - // Testing the actual and expected output values - EXPECT_EQ(output.size(), std::size(Linear_64_ExpectedOutput::all_ones)); - - float *correct = Linear_64_ExpectedOutput::all_ones; - - // Testing the actual and expected output values - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); - } -} -*/ - -TEST(ROOT, LinearWithSelu) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(48); - std::fill_n(input.data(), input.size(), 1.0f); - ASSERT_INCLUDE_AND_RUN(std::vector, "LinearWithSelu", input); - - // Checking output size - EXPECT_EQ(output.size(), std::size(LinearWithSelu_ExpectedOutput::all_ones)); - - float *correct = LinearWithSelu_ExpectedOutput::all_ones; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); - } -} - - -TEST(ROOT, LinearWithSigmoid) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(48); - std::fill_n(input.data(), input.size(), 1.0f); - ASSERT_INCLUDE_AND_RUN(std::vector, "LinearWithSigmoid", input); - - - // Checking output size - EXPECT_EQ(output.size(), std::size(LinearWithSigmoid_ExpectedOutput::all_ones)); - - float *correct = LinearWithSigmoid_ExpectedOutput::all_ones; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); - } -} - - -TEST(ROOT, ConvWithPadding) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(25); - std::iota(input.begin(), input.end(), 0.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector, "ConvWithPadding", input); - - // Checking output size - EXPECT_EQ(output.size(), std::size(ConvWithPadding_ExpectedOutput::all_ones)); - - float *correct = ConvWithPadding_ExpectedOutput::all_ones; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); - } -} - -TEST(ROOT, ConvWithoutPadding) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(25); - std::iota(input.begin(), input.end(), 0.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector, "ConvWithoutPadding", input); - - // Checking output size - EXPECT_EQ(output.size(), std::size(ConvWithoutPadding_ExpectedOutput::all_ones)); - - float *correct = ConvWithoutPadding_ExpectedOutput::all_ones; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); - } -} - - -TEST(ROOT, ConvWithAutopadSameLower) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(25); - std::iota(input.begin(), input.end(), 0.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector, "ConvWithAutopadSameLower", input); - - // Checking output size - EXPECT_EQ(output.size(), std::size(ConvWithAutopadSameLower_ExpectedOutput::all_ones)); - - float *correct = ConvWithAutopadSameLower_ExpectedOutput::all_ones; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); - } -} - - -TEST(ROOT, ConvWithStridesPadding) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(35); - std::iota(input.begin(), input.end(), 0.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector, "ConvWithStridesPadding", input); - - // Checking output size - EXPECT_EQ(output.size(), std::size(ConvWithStridesPadding_ExpectedOutput::all_ones)); - - float *correct = ConvWithStridesPadding_ExpectedOutput::all_ones; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); - } -} - - -TEST(ROOT, ConvWithStridesNoPadding) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(35); - std::iota(input.begin(), input.end(), 0.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector, "ConvWithStridesNoPadding", input); - - // Checking output size - EXPECT_EQ(output.size(), std::size(ConvWithStridesNoPadding_ExpectedOutput::all_ones)); - - float *correct = ConvWithStridesNoPadding_ExpectedOutput::all_ones; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); - } -} - -// disabled -TEST(DISABLED_ROOT, ConvWithAsymmetricPadding) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(35); - std::iota(input.begin(), input.end(), 0.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector, "ConvWithAsymmetricPadding", input); - - // Checking output size - EXPECT_EQ(output.size(), std::size(ConvWithAsymmetricPadding_ExpectedOutput::all_ones)); - - float *correct = ConvWithAsymmetricPadding_ExpectedOutput::all_ones; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); - } -} - -TEST(ROOT, RNNBatchwise) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(6); - std::iota(input.begin(), input.end(), 1.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector>, "RNNBatchwise", input); - std::vector output_y = output[0]; - std::vector output_yh = output[1]; - - // Checking output size - EXPECT_EQ(output_y.size(), std::size(RNNBatchwise_ExpectedOutput::all_ones)); - EXPECT_EQ(output_yh.size(), std::size(RNNBatchwise_ExpectedOutput::all_ones)); - - float *correct = RNNBatchwise_ExpectedOutput::all_ones; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_y[i] - correct[i]), TOLERANCE); - EXPECT_LE(std::abs(output_yh[i] - correct[i]), TOLERANCE); - } -} - -TEST(ROOT, RNNBidirectional) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input({0., 0.01, 0.02, 0.03, 0.04, 0.05, - 0.06, 0.07, 0.08, 0.09, 0.1, 0.11, - 0.12, 0.13, 0.14, 0.15, 0.16, 0.17}); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector>, "RNNBidirectional", input); - std::vector output_y = output[0]; - std::vector output_yh = output[1]; - - // Checking output size - EXPECT_EQ(output_y.size(), std::size(RNNBidirectional_ExpectedOutput::all_ones_y)); - - float *correct_y = RNNBidirectional_ExpectedOutput::all_ones_y; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_y[i] - correct_y[i]), TOLERANCE); - } - - // Checking output size - EXPECT_EQ(output_yh.size(), std::size(RNNBidirectional_ExpectedOutput::all_ones_yh)); - - float *correct_yh = RNNBidirectional_ExpectedOutput::all_ones_yh; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_yh[i] - correct_yh[i]), TOLERANCE); - } -} - -TEST(ROOT, RNNBidirectionalBatchwise) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input({ - 0, 0.01, 0.06, 0.07, 0.12, 0.13, - 0.02, 0.03, 0.08, 0.09, 0.14, 0.15, - 0.04, 0.05, 0.1, 0.11, 0.16, 0.17}); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector>, "RNNBidirectionalBatchwise", input); - std::vector output_y = output[0]; - std::vector output_yh = output[1]; - - // Checking output size - EXPECT_EQ(output_y.size(), std::size(RNNBidirectionalBatchwise_ExpectedOutput::all_ones_y)); - - float *correct_y = RNNBidirectionalBatchwise_ExpectedOutput::all_ones_y; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_y[i] - correct_y[i]), TOLERANCE); - } - - // Checking output size - EXPECT_EQ(output_yh.size(), std::size(RNNBidirectionalBatchwise_ExpectedOutput::all_ones_yh)); - - float *correct_yh = RNNBidirectionalBatchwise_ExpectedOutput::all_ones_yh; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_yh[i] - correct_yh[i]), TOLERANCE); - } -} - -TEST(ROOT, RNNDefaults) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(9); - std::iota(input.begin(), input.end(), 1.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector>, "RNNDefaults", input); - std::vector output_y = output[0]; - std::vector output_yh = output[1]; - - // Checking output size - EXPECT_EQ(output_y.size(), std::size(RNNDefaults_ExpectedOutput::all_ones_y)); - - float *correct_y = RNNDefaults_ExpectedOutput::all_ones_y; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_y[i] - correct_y[i]), TOLERANCE); - } - - // Checking output size - EXPECT_EQ(output_yh.size(), std::size(RNNDefaults_ExpectedOutput::all_ones_yh)); - - float *correct_yh = RNNDefaults_ExpectedOutput::all_ones_yh; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_yh[i] - correct_yh[i]), TOLERANCE); - } -} - -TEST(ROOT, RNNSeqLength) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(18); - std::iota(input.begin(), input.end(), 1.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector>, "RNNSeqLength", input); - std::vector output_y = output[0]; - std::vector output_yh = output[1]; - - // Checking output size - EXPECT_EQ(output_y.size(), std::size(RNNSeqLength_ExpectedOutput::all_ones_y)); - - float *correct_y = RNNSeqLength_ExpectedOutput::all_ones_y; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_y[i] - correct_y[i]), TOLERANCE); - } - - // Checking output size - EXPECT_EQ(output_yh.size(), std::size(RNNSeqLength_ExpectedOutput::all_ones_yh)); - - float *correct_yh = RNNSeqLength_ExpectedOutput::all_ones_yh; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_yh[i] - correct_yh[i]), TOLERANCE); - } -} - -TEST(ROOT, RNNSequence) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input({ - 0.01, -0.01, 0.08, 0.09, 0.001, - 0.09, -0.7, -0.35, 0.0, 0.001, - 0.16, -0.19, 0.003, 0.0, 0.0001, - 0.05, -0.09, 0.013, 0.5, 0.005, - 0.2, -0.05, 0.062, -0.04, -0.04, - 0.0, 0.0, 0.0, 0.0, 0.0, - 0.06, 0.087, 0.01, 0.3, -0.001, - 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0}); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector>, "RNNSequence", input); - std::vector output_y = output[0]; - std::vector output_yh = output[1]; - - // Checking output size - EXPECT_EQ(output_y.size(), std::size(RNNSequence_ExpectedOutput::all_ones_y)); - - float *correct_y = RNNSequence_ExpectedOutput::all_ones_y; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_y[i] - correct_y[i]), TOLERANCE); - } - - // Checking output size - EXPECT_EQ(output_yh.size(), std::size(RNNSequence_ExpectedOutput::all_ones_yh)); - - float *correct_yh = RNNSequence_ExpectedOutput::all_ones_yh; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_yh[i] - correct_yh[i]), TOLERANCE); - } -} - -TEST(ROOT, RNNSequenceBatchwise) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input({ - 0.01, -0.01, 0.08, 0.09, 0.001, - 0.05, -0.09, 0.013, 0.5, 0.005, - 0.06, 0.087, 0.01, 0.3, -0.001, - 0.09, -0.7, -0.35, 0.0, 0.001, - 0.2, -0.05, 0.062, -0.04, -0.04, - 0.0, 0.0, 0.0, 0.0, 0.0, - 0.16, -0.19, 0.003, 0.0, 0.0001, - 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0}); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector>, "RNNSequenceBatchwise", input); - std::vector output_y = output[0]; - std::vector output_yh = output[1]; - - // Checking output size - EXPECT_EQ(output_y.size(), std::size(RNNSequenceBatchwise_ExpectedOutput::all_ones_y)); - - float *correct_y = RNNSequenceBatchwise_ExpectedOutput::all_ones_y; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_y[i] - correct_y[i]), TOLERANCE); - } - - // Checking output size - EXPECT_EQ(output_yh.size(), std::size(RNNSequenceBatchwise_ExpectedOutput::all_ones_yh)); - - float *correct_yh = RNNSequenceBatchwise_ExpectedOutput::all_ones_yh; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_yh[i] - correct_yh[i]), TOLERANCE); - } -} - -TEST(ROOT, LSTMBatchwise) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(6); - std::iota(input.begin(), input.end(), 1.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector>, "LSTMBatchwise", input); - std::vector output_y = output[0]; - std::vector output_yh = output[1]; - - // Checking output size - EXPECT_EQ(output_y.size(), std::size(LSTMBatchwise_ExpectedOutput::all_ones)); - - float *correct = LSTMBatchwise_ExpectedOutput::all_ones; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_y[i] - correct[i]), TOLERANCE); - } - - // Checking output size - EXPECT_EQ(output_yh.size(), std::size(LSTMBatchwise_ExpectedOutput::all_ones)); - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_yh[i] - correct[i]), TOLERANCE); - } -} - -TEST(ROOT, LSTMBidirectional) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(6); - std::iota(input.begin(), input.end(), 1.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector>, "LSTMBidirectional", input); - std::vector output_y = output[0]; - std::vector output_yh = output[1]; - std::vector output_yc = output[2]; - - // Checking output size - EXPECT_EQ(output_y.size(), std::size(LSTMBidirectional_ExpectedOutput::all_ones_y)); - - float *correct_y = LSTMBidirectional_ExpectedOutput::all_ones_y; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_y[i] - correct_y[i]), TOLERANCE); - } - - // Checking output size - EXPECT_EQ(output_yh.size(), std::size(LSTMBidirectional_ExpectedOutput::all_ones_yh)); - - float *correct_yh = LSTMBidirectional_ExpectedOutput::all_ones_yh; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_yh[i] - correct_yh[i]), TOLERANCE); - } - - // Checking output size - EXPECT_EQ(output_yc.size(), std::size(LSTMBidirectional_ExpectedOutput::all_ones_yc)); - - float *correct_yc = LSTMBidirectional_ExpectedOutput::all_ones_yc; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_yc[i] - correct_yc[i]), TOLERANCE); - } -} - -TEST(ROOT, LSTMDefaults) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(6); - std::iota(input.begin(), input.end(), 1.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector>, "LSTMDefaults", input); - std::vector output_y = output[0]; - std::vector output_yh = output[1]; - - // Checking output size - EXPECT_EQ(output_y.size(), std::size(LSTMDefaults_ExpectedOutput::all_ones_y)); - - float *correct_y = LSTMDefaults_ExpectedOutput::all_ones_y; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_y[i] - correct_y[i]), TOLERANCE); - } - - // Checking output size - EXPECT_EQ(output_yh.size(), std::size(LSTMDefaults_ExpectedOutput::all_ones_yh)); - - float *correct_yh = LSTMDefaults_ExpectedOutput::all_ones_yh; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_yh[i] - correct_yh[i]), TOLERANCE); - } -} - -TEST(ROOT, LSTMInitialBias) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(9); - std::iota(input.begin(), input.end(), 1.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector>, "LSTMInitialBias", input); - std::vector output_y = output[0]; - std::vector output_yh = output[1]; - - // Checking output size - EXPECT_EQ(output_y.size(), std::size(LSTMInitialBias_ExpectedOutput::all_ones_y)); - - float *correct_y = LSTMInitialBias_ExpectedOutput::all_ones_y; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_y[i] - correct_y[i]), TOLERANCE); - } - - // Checking output size - EXPECT_EQ(output_yh.size(), std::size(LSTMInitialBias_ExpectedOutput::all_ones_yh)); - - float *correct_yh = LSTMInitialBias_ExpectedOutput::all_ones_yh; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_yh[i] - correct_yh[i]), TOLERANCE); - } -} - -TEST(ROOT, LSTMPeepholes) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(8); - std::iota(input.begin(), input.end(), 1.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector>, "LSTMPeepholes", input); - std::vector output_y = output[0]; - std::vector output_yh = output[1]; - - // Checking output size - EXPECT_EQ(output_y.size(), std::size(LSTMPeepholes_ExpectedOutput::all_ones)); - - float *correct = LSTMPeepholes_ExpectedOutput::all_ones; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_y[i] - correct[i]), TOLERANCE); - } - - // Checking output size - EXPECT_EQ(output_yh.size(), std::size(LSTMPeepholes_ExpectedOutput::all_ones)); - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_yh[i] - correct[i]), TOLERANCE); - } -} - -TEST(ROOT, GRUBatchwise) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(6); - std::iota(input.begin(), input.end(), 1.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector>, "GRUBatchwise", input); - std::vector output_y = output[0]; - std::vector output_yh = output[1]; - - // Checking output size - EXPECT_EQ(output_y.size(), std::size(GRUBatchwise_ExpectedOutput::all_ones)); - - float *correct = GRUBatchwise_ExpectedOutput::all_ones; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_y[i] - correct[i]), TOLERANCE); - } - - // Checking output size - EXPECT_EQ(output_yh.size(), std::size(GRUBatchwise_ExpectedOutput::all_ones)); - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_yh[i] - correct[i]), TOLERANCE); - } -} - -TEST(ROOT, GRUBidirectional) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(6); - std::iota(input.begin(), input.end(), 1.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector>, "GRUBidirectional", input); - std::vector output_y = output[0]; - std::vector output_yh = output[1]; - - // Checking output size - EXPECT_EQ(output_y.size(), std::size(GRUBidirectional_ExpectedOutput::all_ones)); - - float *correct = GRUBidirectional_ExpectedOutput::all_ones; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_y[i] - correct[i]), TOLERANCE); - } - - // Checking output size - EXPECT_EQ(output_yh.size(), std::size(GRUBidirectional_ExpectedOutput::all_ones)); - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_yh[i] - correct[i]), TOLERANCE); - } -} - -TEST(ROOT, GRUDefaults) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(6); - std::iota(input.begin(), input.end(), 1.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector>, "GRUDefaults", input); - std::vector output_y = output[0]; - std::vector output_yh = output[1]; - - // Checking output size - EXPECT_EQ(output_y.size(), std::size(GRUDefaults_ExpectedOutput::all_ones)); - - float *correct = GRUDefaults_ExpectedOutput::all_ones; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_y[i] - correct[i]), TOLERANCE); - } - - // Checking output size - EXPECT_EQ(output_yh.size(), std::size(GRUDefaults_ExpectedOutput::all_ones)); - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_yh[i] - correct[i]), TOLERANCE); - } -} - -TEST(ROOT, GRUInitialBias) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(9); - std::iota(input.begin(), input.end(), 1.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector>, "GRUInitialBias", input); - std::vector output_y = output[0]; - std::vector output_yh = output[1]; - - // Checking output size - EXPECT_EQ(output_y.size(), std::size(GRUInitialBias_ExpectedOutput::all_ones)); - - float *correct = GRUInitialBias_ExpectedOutput::all_ones; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_y[i] - correct[i]), TOLERANCE); - } - - // Checking output size - EXPECT_EQ(output_yh.size(), std::size(GRUInitialBias_ExpectedOutput::all_ones)); - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); ++i) { - EXPECT_LE(std::abs(output_yh[i] - correct[i]), TOLERANCE); - } -} - -TEST(ROOT, GRUSeqLength) -{ - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // Preparing the standard all-ones input - std::vector input(18); - std::iota(input.begin(), input.end(), 1.0f); - ASSERT_INCLUDE_AND_RUN_NO_SESSION(std::vector>, "GRUSeqLength", input); - std::vector output_y = output[0]; - std::vector output_yh = output[1]; - - // Checking output size - EXPECT_EQ(output_y.size(), std::size(GRUSeqLength_ExpectedOutput::all_ones_y)); - - float *correct_y = GRUSeqLength_ExpectedOutput::all_ones_y; - - // Checking every output value, one by one - for (size_t i = 0; i < output_y.size(); ++i) { - EXPECT_LE(std::abs(output_y[i] - correct_y[i]), TOLERANCE); - } - - // Checking output size - EXPECT_EQ(output_yh.size(), std::size(GRUSeqLength_ExpectedOutput::all_ones_yh)); - - float *correct_yh = GRUSeqLength_ExpectedOutput::all_ones_yh; - - // Checking every output value, one by one - for (size_t i = 0; i < output_yh.size(); ++i) { - EXPECT_LE(std::abs(output_yh[i] - correct_yh[i]), TOLERANCE); - } -} - -TEST(ROOT, RangeFloat) { - constexpr float TOLERANCE = DEFAULT_TOLERANCE; - - // inputs - std::vector start{1.}; - std::vector limit{10.}; - std::vector delta{2.}; - ASSERT_INCLUDE_AND_RUN_SESSION_ARGS(std::vector, "RangeFloat", "\"\", 5", start, limit, delta); - - // Checking the output size - EXPECT_EQ(output.size(), std::size(RangeFloat_ExpectedOutput::outputs)); - - float* correct = RangeFloat_ExpectedOutput::outputs; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); i++) { - EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); - } -} - -TEST(ROOT, RangeInt) { - // inputs - std::vector start{1}; - std::vector limit{10}; - std::vector delta{2}; - ASSERT_INCLUDE_AND_RUN_SESSION_ARGS(std::vector, "RangeInt", "\"\", 5", start, limit, delta); - - // Checking the output size - EXPECT_EQ(output.size(), std::size(RangeInt_ExpectedOutput::outputs)); - - int64_t* correct = RangeInt_ExpectedOutput::outputs; - - // Checking every output value, one by one - for (size_t i = 0; i < output.size(); i++) { - EXPECT_EQ(output[i], correct[i]); - } -}