//Code generated automatically by TMVA for Inference of Model file [LinearModel.onnx] at [Tue May 19 20:24:05 2026] #ifndef ROOT_TMVA_SOFIE_LINEARMODEL #define ROOT_TMVA_SOFIE_LINEARMODEL #include #include #include #include "TMVA/SOFIE_common.hxx" #include namespace TMVA_SOFIE_LinearModel{ namespace BLAS{ extern "C" void sgemv_(const char * trans, const int * m, const int * n, const float * alpha, const float * A, const int * lda, const float * X, const int * incx, const float * beta, const float * Y, const int * incy); extern "C" void sgemm_(const char * transa, const char * transb, const int * m, const int * n, const int * k, const float * alpha, const float * A, const int * lda, const float * B, const int * ldb, const float * beta, float * C, const int * ldc); }//BLAS struct Session; inline void doInfer(Session const &session, float const* tensor_input, float *tensor_output ); struct Session { // initialized (weights and constant) tensors std::vector fTensor_4weight = std::vector(16); float * tensor_4weight = fTensor_4weight.data(); std::vector fTensor_2bias = std::vector(8); float * tensor_2bias = fTensor_2bias.data(); std::vector fTensor_4bias = std::vector(2); float * tensor_4bias = fTensor_4bias.data(); std::vector fTensor_2weight = std::vector(128); float * tensor_2weight = fTensor_2weight.data(); std::vector fTensor_0bias = std::vector(16); float * tensor_0bias = fTensor_0bias.data(); std::vector fTensor_0weight = std::vector(512); float * tensor_0weight = fTensor_0weight.data(); //--- Allocating session memory pool to be used for allocating intermediate tensors std::vector fIntermediateMemoryPool = std::vector(96); // --- Positioning intermediate tensor memory -- // Allocating memory for intermediate tensor relu with size 64 bytes float* tensor_relu = reinterpret_cast(fIntermediateMemoryPool.data() + 0); // Allocating memory for intermediate tensor relu_1 with size 32 bytes float* tensor_relu_1 = reinterpret_cast(fIntermediateMemoryPool.data() + 64); // Allocating memory for intermediate tensor linear_2 with size 8 bytes float* tensor_linear_2 = reinterpret_cast(fIntermediateMemoryPool.data() + 56); // Allocating memory for intermediate tensor output with size 8 bytes float* tensor_output = reinterpret_cast(fIntermediateMemoryPool.data() + 48); Session(std::string filename ="LinearModel.dat") { //--- reading weights from file std::ifstream f; f.open(filename); if (!f.is_open()) { throw std::runtime_error("tmva-sofie failed to open file " + filename + " for input weights"); } using TMVA::Experimental::SOFIE::ReadTensorFromStream; ReadTensorFromStream(f, tensor_4weight, "tensor_4weight", 16); ReadTensorFromStream(f, tensor_2bias, "tensor_2bias", 8); ReadTensorFromStream(f, tensor_4bias, "tensor_4bias", 2); ReadTensorFromStream(f, tensor_2weight, "tensor_2weight", 128); ReadTensorFromStream(f, tensor_0bias, "tensor_0bias", 16); ReadTensorFromStream(f, tensor_0weight, "tensor_0weight", 512); f.close(); } std::vector infer(float const* tensor_input){ std::vector output_tensor_output(2); doInfer(*this, tensor_input, output_tensor_output.data() ); return {output_tensor_output}; } }; // end of Session // Input tensor dimensions using TMVA::Experimental::SOFIE::SingleDim; using TMVA::Experimental::SOFIE::TensorDims; using TMVA::Experimental::SOFIE::makeDims; constexpr std::array dim_input{SingleDim{1}, SingleDim{32}}; constexpr std::array inputTensorDims{ makeDims(dim_input) }; constexpr bool hasDynamicInputTensors{false}; // Output tensor dimensions constexpr std::array dim_output{SingleDim{1}, SingleDim{2}}; constexpr std::array outputTensorDims{ makeDims(dim_output) }; constexpr bool hasDynamicOutputTensors{false}; inline void doInfer(Session const &session, float const* tensor_input, float *tensor_output ) { auto &tensor_0bias = session.tensor_0bias; auto &tensor_0weight = session.tensor_0weight; auto &tensor_2bias = session.tensor_2bias; auto &tensor_2weight = session.tensor_2weight; auto &tensor_4bias = session.tensor_4bias; auto &tensor_4weight = session.tensor_4weight; auto &tensor_linear_2 = session.tensor_linear_2; auto &tensor_relu = session.tensor_relu; auto &tensor_relu_1 = session.tensor_relu_1; //--------- Gemm op_0 { 1 , 32 } * { 16 , 32 } -> { 1 , 16 } for (size_t j = 0; j < 1; j++) { size_t y_index = 16 * j; TMVA::Experimental::SOFIE::Copy(tensor_relu + y_index, tensor_0bias, 16); } TMVA::Experimental::SOFIE::Gemm_Call(tensor_relu, true, false, 16, 1, 32, 1, tensor_0weight, tensor_input, 1,nullptr); //--- applying RELU to output TMVA::Experimental::SOFIE::Relu(tensor_relu, tensor_relu, 16); //--------- Gemm op_1 { 1 , 16 } * { 8 , 16 } -> { 1 , 8 } for (size_t j = 0; j < 1; j++) { size_t y_index = 8 * j; TMVA::Experimental::SOFIE::Copy(tensor_relu_1 + y_index, tensor_2bias, 8); } TMVA::Experimental::SOFIE::Gemm_Call(tensor_relu_1, true, false, 8, 1, 16, 1, tensor_2weight, tensor_relu, 1,nullptr); //--- applying RELU to output TMVA::Experimental::SOFIE::Relu(tensor_relu_1, tensor_relu_1, 8); //--------- Gemm op_2 { 1 , 8 } * { 2 , 8 } -> { 1 , 2 } for (size_t j = 0; j < 1; j++) { size_t y_index = 2 * j; TMVA::Experimental::SOFIE::Copy(tensor_linear_2 + y_index, tensor_4bias, 2); } TMVA::Experimental::SOFIE::Gemm_Call(tensor_linear_2, true, false, 2, 1, 8, 1, tensor_4weight, tensor_relu_1, 1,nullptr); ///------- Softmax op_3 ---> { 1 , 2 } //----- softmax axis is last one - 1 for (int i = 0; i < 1; ++i) { size_t offset = i * 2; float const * x_ptr = &tensor_linear_2[offset]; float * y_ptr = &tensor_output[offset]; float vmax = x_ptr[0]; for (int j = 1; j < 2; ++j) { if (x_ptr[j] > vmax) vmax = x_ptr[j]; } float sum = 0.0; for (int j = 0; j < 2; ++j) { y_ptr[j] = std::exp(x_ptr[j] - vmax); sum += y_ptr[j]; } float inv_sum = 1.0f / sum; for (int j = 0; j < 2; ++j) { y_ptr[j] *= inv_sum; } } } } //TMVA_SOFIE_LinearModel #endif // ROOT_TMVA_SOFIE_LINEARMODEL