Skip to content

Commit 6027831

Browse files
committed
[tmva][sofie] Detect ONNX input files for tests at runtime
This means we don't need to do a clean CMake build everytime a new ONNX file is added anymore, as so far the ONNX files for tests were copied at configuration time with CMakes `configure_file`.
1 parent c12d50e commit 6027831

3 files changed

Lines changed: 67 additions & 28 deletions

File tree

tmva/sofie/test/CMakeLists.txt

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,38 +13,37 @@
1313
if (NOT ONNX_MODELS_DIR)
1414
set(ONNX_MODELS_DIR input_models)
1515
endif()
16+
get_filename_component(ONNX_MODELS_DIR "${ONNX_MODELS_DIR}" ABSOLUTE)
1617

17-
# Finding .onnx files to be parsed and creating the appropriate code to
18-
# parse all file. It is much faster to combine all parsing in a single executable
19-
# which will avoid initialization time (especially when using ROOT)
20-
set(CAPTURE_STR "EmitModel( \"@1\", \"@2\");")
21-
set(ALL_CAPTURES "")
22-
# Finding .onnx files to be parsed and creating the appropriate command
23-
file(GLOB ONNX_FILES "${ONNX_MODELS_DIR}/*.onnx")
24-
foreach(onnx_file ${ONNX_FILES})
25-
get_filename_component(fname ${onnx_file} NAME_WE)
26-
get_filename_component(fdir ${onnx_file} DIRECTORY)
27-
string(REPLACE "@1" ${onnx_file} cap ${CAPTURE_STR})
28-
string(REPLACE "@2" ${fname} cap ${cap})
29-
list(APPEND ALL_CAPTURES ${cap})
30-
endforeach()
31-
string(REPLACE ";" ";\n" EMIT_CAPTURES "${ALL_CAPTURES}")
32-
configure_file(EmitFromONNX.cxx.in EmitFromONNX_all.cxx @ONLY)
33-
34-
ROOTTEST_GENERATE_EXECUTABLE(emitFromONNX EmitFromONNX_all.cxx
18+
# The parsing of all .onnx files is combined in a single executable, which is
19+
# much faster than one process per model because it avoids the repeated
20+
# initialization time (especially when using ROOT).
21+
#
22+
# The list of models is globbed at build time by GenerateEmitFromONNX.cmake,
23+
# which (re-)generates EmitFromONNX_all.cxx right before the emitFromONNX
24+
# executable is built. Like this, adding or removing a model does not require
25+
# re-running CMake, and the generated file is only touched when the model list
26+
# actually changed, so no needless recompilation is triggered.
27+
set(EMIT_FROM_ONNX_SOURCE ${CMAKE_CURRENT_BINARY_DIR}/EmitFromONNX_all.cxx)
28+
add_custom_target(SofieEmitFromONNXSource
29+
COMMAND ${CMAKE_COMMAND}
30+
-DONNX_MODELS_DIR=${ONNX_MODELS_DIR}
31+
-DTEMPLATE_FILE=${CMAKE_CURRENT_SOURCE_DIR}/EmitFromONNX.cxx.in
32+
-DOUTPUT_FILE=${EMIT_FROM_ONNX_SOURCE}
33+
-P ${CMAKE_CURRENT_SOURCE_DIR}/GenerateEmitFromONNX.cmake
34+
BYPRODUCTS ${EMIT_FROM_ONNX_SOURCE}
35+
COMMENT "Updating EmitFromONNX_all.cxx from the ONNX models in ${ONNX_MODELS_DIR}")
36+
37+
ROOTTEST_GENERATE_EXECUTABLE(emitFromONNX ${EMIT_FROM_ONNX_SOURCE}
3538
LIBRARIES protobuf::libprotobuf ROOTTMVASofie ROOTTMVASofieParser
39+
DEPENDS SofieEmitFromONNXSource
3640
FIXTURES_SETUP sofie-compile-models-onnx-build)
3741

38-
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/input_models/ConvAddReluFuseBug.onnx
39-
${CMAKE_CURRENT_BINARY_DIR}/ConvAddReluFuseBug.onnx COPYONLY)
40-
ROOT_ADD_GTEST(TestParseConvAddFusion TestParseConvAddFusion.cxx
41-
LIBRARIES Core ROOTTMVASofie ROOTTMVASofieParser)
42-
4342
# silence protobuf warnings seen in version 3.0 and 3.6. Not needed from protobuf version 3.17
4443
target_compile_options(emitFromONNX PRIVATE -Wno-unused-parameter -Wno-array-bounds)
4544

4645
ROOTTEST_ADD_TEST(SofieCompileModels_ONNX
47-
COMMAND ${CMAKE_COMMAND} -E env ROOTIGNOREPREFIX=1 ./emitFromONNX ${onnx_file} ${CMAKE_CURRENT_BINARY_DIR}/${fname}
46+
COMMAND ${CMAKE_COMMAND} -E env ROOTIGNOREPREFIX=1 ./emitFromONNX
4847
FIXTURES_REQUIRED sofie-compile-models-onnx-build
4948
FIXTURES_SETUP sofie-compile-models-onnx
5049
)

tmva/sofie/test/EmitFromONNX.cxx.in

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@
99
#include "TMVA/RModel.hxx"
1010
#include "TMVA/RModelParser_ONNX.hxx"
1111

12+
#include <exception>
13+
#include <iostream>
14+
#include <string>
15+
16+
// Returns the number of failures (0 or 1), so that a model that fails to
17+
// parse doesn't prevent the emission of the remaining models.
1218
int EmitModel(std::string filename, std::string outname)
13-
{
19+
try {
1420
using namespace TMVA::Experimental::SOFIE;
1521

1622
std::cout << "parsing file ..." << filename << std::endl;
@@ -50,11 +56,15 @@ int EmitModel(std::string filename, std::string outname)
5056
}
5157

5258
return 0;
59+
} catch (std::exception const &e) {
60+
std::cerr << "Failed to emit model " << filename << ": " << e.what() << std::endl;
61+
return 1;
5362
}
5463

55-
int main(int argc, char *argv[])
64+
int main()
5665
{
66+
int nFailures = 0;
5767
// clang-format off
58-
@EMIT_CAPTURES@;
59-
// clang-format on
68+
@EMIT_CAPTURES@ // clang-format on
69+
return nFailures;
6070
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Copyright (C) 1995-2026, Rene Brun and Fons Rademakers.
2+
# All rights reserved.
3+
#
4+
# For the licensing terms see $ROOTSYS/LICENSE.
5+
# For the list of contributors see $ROOTSYS/README/CREDITS.
6+
7+
# Generate EmitFromONNX_all.cxx from all .onnx models found in ONNX_MODELS_DIR.
8+
#
9+
# This script is run at build time (see CMakeLists.txt in this directory), so
10+
# that newly added models are picked up without re-running CMake. The output
11+
# file is only touched when its content changed, to avoid needless
12+
# recompilation of the emitFromONNX executable.
13+
#
14+
# Expected variables:
15+
# ONNX_MODELS_DIR - directory containing the .onnx input models
16+
# TEMPLATE_FILE - path to EmitFromONNX.cxx.in
17+
# OUTPUT_FILE - path of the generated translation unit
18+
19+
file(GLOB onnx_files "${ONNX_MODELS_DIR}/*.onnx")
20+
list(SORT onnx_files)
21+
22+
set(EMIT_CAPTURES "")
23+
foreach(onnx_file IN LISTS onnx_files)
24+
get_filename_component(fname "${onnx_file}" NAME_WE)
25+
string(APPEND EMIT_CAPTURES " nFailures += EmitModel(\"${onnx_file}\", \"${fname}\");\n")
26+
endforeach()
27+
28+
configure_file("${TEMPLATE_FILE}" "${OUTPUT_FILE}.tmp" @ONLY)
29+
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${OUTPUT_FILE}.tmp" "${OUTPUT_FILE}")
30+
file(REMOVE "${OUTPUT_FILE}.tmp")

0 commit comments

Comments
 (0)