From 04762cf28d68d36274902e0ffcab3095bfbf273b Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Tue, 20 Sep 2022 10:02:15 +0200 Subject: [PATCH] generate-catalogue is gone (#1975) This is prep for meson in addition to simplifying (ie reducing) the amount of scripting we have. In the long run, I'd like to remove `BuildModules.cmake` too, but this might be superseded by meson and this PR is self-contained. # Changes - `modcc` accepts now a list of NMODL files - likewise, `modcc` is now able to spit out a catalogue.cpp file - remove the `generate-catalogue` script, simplify a-b-c - remove some options from `modcc` we never use - No longer allow external modcc --- CMakeLists.txt | 15 +- arbor/CMakeLists.txt | 9 +- arbor/include/arbor/mechcat.hpp | 1 - doc/dev/extending_catalogues.rst | 30 +- mechanisms/BuildModules.cmake | 181 +++++------- mechanisms/CMakeLists.txt | 39 +-- mechanisms/default/pas.mod | 1 - mechanisms/generate_catalogue | 170 ----------- modcc/CMakeLists.txt | 23 +- modcc/modcc.cpp | 275 ++++++++++++------ modcc/printer/cprinter.cpp | 2 +- scripts/build-catalogue.in | 7 +- test/unit-modcc/CMakeLists.txt | 4 +- test/unit/CMakeLists.txt | 80 ++--- test/unit/test_mechcat.cpp | 2 - test/unit/{mod => testing}/ca_linear.mod | 0 test/unit/{mod => testing}/celsius_test.mod | 0 test/unit/{mod => testing}/diam_test.mod | 0 .../{mod => testing}/fixed_ica_current.mod | 0 test/unit/{mod => testing}/gj0.mod | 0 test/unit/{mod => testing}/gj1.mod | 0 test/unit/{mod => testing}/linear_ca_conc.mod | 0 test/unit/{mod => testing}/non_linear.mod | 0 test/unit/{mod => testing}/param_as_state.mod | 0 .../{mod => testing}/point_ica_current.mod | 0 .../unit/{mod => testing}/post_events_syn.mod | 0 test/unit/{mod => testing}/read_cai_init.mod | 0 test/unit/{mod => testing}/read_eX.mod | 0 .../test0_kin_compartment.mod | 0 .../{mod => testing}/test0_kin_conserve.mod | 0 test/unit/{mod => testing}/test0_kin_diff.mod | 0 .../test0_kin_steadystate.mod | 0 .../test1_kin_compartment.mod | 0 .../{mod => testing}/test1_kin_conserve.mod | 0 test/unit/{mod => testing}/test1_kin_diff.mod | 0 .../test1_kin_steadystate.mod | 0 test/unit/{mod => testing}/test2_kin_diff.mod | 0 test/unit/{mod => testing}/test3_kin_diff.mod | 0 .../test4_kin_compartment.mod | 0 .../{mod => testing}/test5_nonlinear_diff.mod | 0 .../{mod => testing}/test6_nonlinear_diff.mod | 0 test/unit/{mod => testing}/test_ca.mod | 0 .../{mod => testing}/test_ca_read_valence.mod | 0 .../unit/{mod => testing}/test_cl_valence.mod | 0 test/unit/{mod => testing}/test_kin1.mod | 0 test/unit/{mod => testing}/test_kinlva.mod | 0 .../{mod => testing}/test_linear_init.mod | 0 .../test_linear_init_shuffle.mod | 0 .../{mod => testing}/test_linear_state.mod | 0 test/unit/{mod => testing}/write_Xi_Xo.mod | 0 .../{mod => testing}/write_cai_breakpoint.mod | 0 test/unit/{mod => testing}/write_eX.mod | 0 .../{mod => testing}/write_multiple_eX.mod | 0 test/unit/unit_test_catalogue.cpp | 89 +----- test/unit/unit_test_catalogue.hpp | 1 + 55 files changed, 326 insertions(+), 603 deletions(-) delete mode 100755 mechanisms/generate_catalogue rename test/unit/{mod => testing}/ca_linear.mod (100%) rename test/unit/{mod => testing}/celsius_test.mod (100%) rename test/unit/{mod => testing}/diam_test.mod (100%) rename test/unit/{mod => testing}/fixed_ica_current.mod (100%) rename test/unit/{mod => testing}/gj0.mod (100%) rename test/unit/{mod => testing}/gj1.mod (100%) rename test/unit/{mod => testing}/linear_ca_conc.mod (100%) rename test/unit/{mod => testing}/non_linear.mod (100%) rename test/unit/{mod => testing}/param_as_state.mod (100%) rename test/unit/{mod => testing}/point_ica_current.mod (100%) rename test/unit/{mod => testing}/post_events_syn.mod (100%) rename test/unit/{mod => testing}/read_cai_init.mod (100%) rename test/unit/{mod => testing}/read_eX.mod (100%) rename test/unit/{mod => testing}/test0_kin_compartment.mod (100%) rename test/unit/{mod => testing}/test0_kin_conserve.mod (100%) rename test/unit/{mod => testing}/test0_kin_diff.mod (100%) rename test/unit/{mod => testing}/test0_kin_steadystate.mod (100%) rename test/unit/{mod => testing}/test1_kin_compartment.mod (100%) rename test/unit/{mod => testing}/test1_kin_conserve.mod (100%) rename test/unit/{mod => testing}/test1_kin_diff.mod (100%) rename test/unit/{mod => testing}/test1_kin_steadystate.mod (100%) rename test/unit/{mod => testing}/test2_kin_diff.mod (100%) rename test/unit/{mod => testing}/test3_kin_diff.mod (100%) rename test/unit/{mod => testing}/test4_kin_compartment.mod (100%) rename test/unit/{mod => testing}/test5_nonlinear_diff.mod (100%) rename test/unit/{mod => testing}/test6_nonlinear_diff.mod (100%) rename test/unit/{mod => testing}/test_ca.mod (100%) rename test/unit/{mod => testing}/test_ca_read_valence.mod (100%) rename test/unit/{mod => testing}/test_cl_valence.mod (100%) rename test/unit/{mod => testing}/test_kin1.mod (100%) rename test/unit/{mod => testing}/test_kinlva.mod (100%) rename test/unit/{mod => testing}/test_linear_init.mod (100%) rename test/unit/{mod => testing}/test_linear_init_shuffle.mod (100%) rename test/unit/{mod => testing}/test_linear_state.mod (100%) rename test/unit/{mod => testing}/write_Xi_Xo.mod (100%) rename test/unit/{mod => testing}/write_cai_breakpoint.mod (100%) rename test/unit/{mod => testing}/write_eX.mod (100%) rename test/unit/{mod => testing}/write_multiple_eX.mod (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index a05ee6da..4d74fa0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -228,7 +228,6 @@ install(TARGETS arborio-public-deps EXPORT arborio-targets) configure_file(scripts/build-catalogue.in ${CMAKE_CURRENT_BINARY_DIR}/arbor-build-catalogue @ONLY) install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/arbor-build-catalogue DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES mechanisms/BuildModules.cmake DESTINATION ${ARB_INSTALL_DATADIR}) -install(FILES mechanisms/generate_catalogue DESTINATION ${ARB_INSTALL_DATADIR} PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) # External libraries in `ext` sub-directory: json, tinyopt and randon123. # Creates interface libraries `ext-json`, `ext-tinyopt` and `ext-random123` @@ -397,20 +396,10 @@ if (ARB_BACKTRACE) target_compile_definitions(arbor-private-deps INTERFACE WITH_BACKTRACE) endif() -# Build and use modcc unless explicit path given +# Build modcc flags #------------------------------------------------ -if(ARB_MODCC) - find_program(modcc NAMES ${ARB_MODCC} NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) - if(NOT modcc) - message(FATAL_ERROR "Unable to find modcc executable.") - endif() - set(ARB_WITH_EXTERNAL_MODCC TRUE) -else() - set(modcc $<TARGET_FILE:modcc>) - set(ARB_WITH_EXTERNAL_MODCC FALSE) -endif() - +set(modcc $<TARGET_FILE:modcc>) set(ARB_MODCC_FLAGS) if(ARB_VECTORIZE) list(APPEND ARB_MODCC_FLAGS "--simd") diff --git a/arbor/CMakeLists.txt b/arbor/CMakeLists.txt index 985767ad..0e79aefc 100644 --- a/arbor/CMakeLists.txt +++ b/arbor/CMakeLists.txt @@ -117,18 +117,15 @@ install(TARGETS arbor-private-headers EXPORT arbor-targets) # directory-local. add_subdirectory(../mechanisms "${CMAKE_BINARY_DIR}/mechanisms") -set_source_files_properties(${arbor_mechanism_sources} PROPERTIES GENERATED TRUE) +set_source_files_properties(${arbor-builtin-mechanisms} PROPERTIES GENERATED TRUE) if(ARB_WITH_CUDA_CLANG OR ARB_WITH_HIP_CLANG) set_source_files_properties(${arbor_sources} PROPERTIES LANGUAGE CXX) - set_source_files_properties(${arbor_mechanism_sources} PROPERTIES LANGUAGE CXX) + set_source_files_properties(${arbor-builtin-mechanism} PROPERTIES LANGUAGE CXX) endif() # Library target: - -add_library(arbor ${arbor_sources} ${arbor_mechanism_sources}) -add_dependencies(arbor build_all_mods) - +add_library(arbor ${arbor_sources} ${arbor-builtin-mechanisms}) target_link_libraries(arbor PRIVATE arbor-private-deps arbor-private-headers) target_link_libraries(arbor PUBLIC arbor-public-deps arbor-public-headers) diff --git a/arbor/include/arbor/mechcat.hpp b/arbor/include/arbor/mechcat.hpp index c8f98bd3..bfe5113a 100644 --- a/arbor/include/arbor/mechcat.hpp +++ b/arbor/include/arbor/mechcat.hpp @@ -109,7 +109,6 @@ private: void register_impl(arb_backend_kind, const std::string&, mechanism_ptr); }; -// References to global mechanism catalogues. ARB_ARBOR_API const mechanism_catalogue& global_default_catalogue(); ARB_ARBOR_API const mechanism_catalogue& global_allen_catalogue(); ARB_ARBOR_API const mechanism_catalogue& global_bbp_catalogue(); diff --git a/doc/dev/extending_catalogues.rst b/doc/dev/extending_catalogues.rst index d60182ec..aedd6cff 100644 --- a/doc/dev/extending_catalogues.rst +++ b/doc/dev/extending_catalogues.rst @@ -20,7 +20,7 @@ produce a catalogue of the same level of integration as the built-in catalogues (*default*, *bbp*, and *allen*). The required steps are as follows 1. Go to the Arbor source tree. -2. Create a new directory under *mechanisms*. +2. Create a new directory under *mechanisms* with the name of your catalogue 1. Add any ``.mod`` files you wish to integrate. 2. Add any raw C++ files to be included in the catalogue. @@ -31,27 +31,13 @@ produce a catalogue of the same level of integration as the built-in catalogues .. code-block :: cmake make_catalogue( - NAME default # Name of your catalogue - SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/default" # Directory name (added above) - OUTPUT "CAT_DEFAULT_SOURCES" # Variable name to store C++ files into (see below) - MOD exp2syn expsyn expsyn_stdp hh kamt kdrmt nax nernst pas # Space separated list of NMODL mechanism names - CXX # Space separated list of raw C++ mechanism names - PREFIX "${PROJECT_SOURCE_DIR}/mechanisms" # where does 'generate_catalogue' live, do not change - STANDALONE FALSE # build as shared object, must be OFF - VERBOSE OFF) # Print debug info at configuration time - -5. Add your ``output-name`` to the ``arbor_mechanism_sources`` list. - - .. code-block :: cmake - - set(arbor_mechanism_sources - ${CAT_BBP_SOURCES} - ${CAT_ALLEN_SOURCES} - ${CAT_DEFAULT_SOURCES} # from above - PARENT_SCOPE) - -6. Add a ``global_NAME_catalogue`` function in ``mechcat.hpp`` and ``mechcat.cpp`` -7. Bind this function in ``python/mechanisms.cpp``. + NAME default # Name of your catalogue, must match directory under 2. + MOD exp2syn expsyn expsyn_stdp hh kamt kdrmt nax nernst pas # Space separated list of mechanism names + CXX # Optional: list of raw C++ mechanism names + VERBOSE ${ARB_CAT_VERBOSE} # Print debug info at configuration time + ADD_DEPS ON) # Must be ON, make catalogue part of arbor +5. Add a ``global_NAME_catalogue`` function in ``mechcat.hpp``. +6. Bind this function in ``python/mechanisms.cpp`` to ``NAME-catalogue``. All steps can be directly adapted from the surrounding code. diff --git a/mechanisms/BuildModules.cmake b/mechanisms/BuildModules.cmake index 83b8467c..98126088 100644 --- a/mechanisms/BuildModules.cmake +++ b/mechanisms/BuildModules.cmake @@ -1,71 +1,59 @@ include(CMakeParseArguments) -# If a MODCC executable is explicitly provided, don't make the in-tree modcc a dependency. +function("make_catalogue") + cmake_parse_arguments(MK_CAT "" "NAME;VERBOSE;ADD_DEPS" "MOD;CXX" ${ARGN}) + set(MK_CAT_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated/${MK_CAT_NAME}") + file(MAKE_DIRECTORY "${MK_CAT_OUT_DIR}") + set(MK_CAT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${MK_CAT_NAME}") -function(build_modules) - cmake_parse_arguments(build_modules "" "MODCC;TARGET;SOURCE_DIR;DEST_DIR;MECH_SUFFIX" "MODCC_FLAGS;GENERATES" ${ARGN}) + if(MK_CAT_VERBOSE) + message("Catalogue name: ${MK_CAT_NAME}") + message("Catalogue mechanisms: ${MK_CAT_MOD}") + message("Extra cxx files: ${MK_CAT_CXX}") + message("Catalogue sources: ${MK_CAT_SOURCES}") + message("Catalogue output: ${MK_CAT_OUT_DIR}") + endif() - if("${build_modules_SOURCE_DIR}" STREQUAL "") - set(build_modules_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") - endif() + set(mk_cat_modcc_flags -t cpu ${ARB_MODCC_FLAGS} -N arb -c ${MK_CAT_NAME} -o ${MK_CAT_OUT_DIR}) + if(ARB_WITH_GPU) + set(mk_cat_modcc_flags, -t gpu ${mk_cat_modcc_flags}) + endif() + + list(APPEND catalogue_${MK_CAT_NAME}_source ${MK_CAT_OUT_DIR}/${MK_CAT_NAME}_catalogue.cpp) - if("${build_modules_DEST_DIR}" STREQUAL "") - set(build_modules_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}") + foreach(mech ${MK_CAT_MOD}) + list(APPEND catalogue_${MK_CAT_NAME}_mods ${MK_CAT_SOURCES}/${mech}.mod) + list(APPEND catalogue_${MK_CAT_NAME}_source ${MK_CAT_OUT_DIR}/${mech}_cpu.cpp) + if(ARB_WITH_GPU) + list(APPEND catalogue_${MK_CAT_NAME}_source ${MK_CAT_OUT_DIR}/${mech}_gpu.cpp ${MK_CAT_OUT_DIR}/${mech}_gpu.cu) endif() - file(MAKE_DIRECTORY "${build_modules_DEST_DIR}") - - set(all_generated) - foreach(mech ${build_modules_UNPARSED_ARGUMENTS}) - set(mod "${build_modules_SOURCE_DIR}/${mech}.mod") - set(out "${build_modules_DEST_DIR}/${mech}") - set(generated) - foreach (suffix ${build_modules_GENERATES}) - list(APPEND generated ${out}${suffix}) - endforeach() - - set(depends "${mod}") - if(build_modules_MODCC) - set(modcc_bin ${build_modules_MODCC}) - else() - list(APPEND depends modcc) - set(modcc_bin $<TARGET_FILE:modcc>) - endif() - - set(flags ${build_modules_MODCC_FLAGS} -o "${out}") - if(build_modules_MECH_SUFFIX) - list(APPEND flags -m "${mech}${build_modules_MECH_SUFFIX}") - endif() - - add_custom_command( - OUTPUT ${generated} - DEPENDS ${depends} - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - COMMAND ${modcc_bin} ${flags} ${mod} - COMMENT "modcc generating: ${generated}" - ) - set_source_files_properties(${generated} PROPERTIES GENERATED TRUE) - list(APPEND all_generated ${generated}) - endforeach() - - # Fake target to always trigger .mod -> .hpp/.cu dependencies because CMake - if (build_modules_TARGET) - set(depends ${all_generated}) - if(NOT build_modules_MODCC) - list(APPEND depends modcc) - endif() - add_custom_target(${build_modules_TARGET} DEPENDS ${depends}) + endforeach() + + foreach(mech ${MK_CAT_CXX}) + list(APPEND catalogue_${MK_CAT_NAME}_source ${MK_CAT_OUT_DIR}/${mech}_cpu.cpp) + if(ARB_WITH_GPU) + list(APPEND catalogue_${MK_CAT_NAME}_source ${MK_CAT_OUT_DIR}/${mech}_gpu.cpp ${MK_CAT_OUT_DIR}/${mech}_gpu.cu) endif() + endforeach() + + add_custom_command(OUTPUT ${catalogue_${MK_CAT_NAME}_source} + DEPENDS ${modcc} ${catalogue_${MK_CAT_NAME}_mods} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND ${modcc} ${mk_cat_modcc_flags} ${catalogue_${MK_CAT_NAME}_mods} + COMMENT "modcc generating: ${catalogue_${MK_CAT_NAME}_source}") + add_custom_target(catalogue-${MK_CAT_NAME}-target DEPENDS ${catalogue_${MK_CAT_NAME}_source}) + if (MK_CAT_ADD_DEPS) + add_dependencies(arbor-public-deps catalogue-${MK_CAT_NAME}-target) + set(arbor-builtin-mechanisms ${arbor-builtin-mechanisms} ${catalogue_${MK_CAT_NAME}_source} PARENT_SCOPE) + else() + set(catalogue-${MK_CAT_NAME}-mechanisms ${catalogue_${MK_CAT_NAME}_source} PARENT_SCOPE) + endif() endfunction() -function("make_catalogue") - cmake_parse_arguments(MK_CAT "" "NAME;SOURCES;OUTPUT;PREFIX;STANDALONE;VERBOSE" "CXX_FLAGS_TARGET;MOD;CXX" ${ARGN}) +function("make_catalogue_standalone") + cmake_parse_arguments(MK_CAT "" "NAME;SOURCES;VERBOSE" "CXX_FLAGS_TARGET;MOD;CXX" ${ARGN}) set(MK_CAT_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated/${MK_CAT_NAME}") - - # Need to set ARB_WITH_EXTERNAL_MODCC *and* modcc - set(external_modcc) - if(ARB_WITH_EXTERNAL_MODCC) - set(external_modcc MODCC ${modcc}) - endif() + file(MAKE_DIRECTORY "${MK_CAT_OUT_DIR}") if(MK_CAT_VERBOSE) message("Catalogue name: ${MK_CAT_NAME}") @@ -73,50 +61,32 @@ function("make_catalogue") message("Extra cxx files: ${MK_CAT_CXX}") message("Catalogue sources: ${MK_CAT_SOURCES}") message("Catalogue output: ${MK_CAT_OUT_DIR}") - message("Build as standalone: ${MK_CAT_STANDALONE}") message("Arbor cxx flags: ${MK_CAT_CXX_FLAGS_TARGET}") message("Arbor cxx compiler: ${ARB_CXX}") - message("Script prefix: ${MK_CAT_PREFIX}") message("Current cxx compiler: ${CMAKE_CXX_COMPILER}") endif() - file(MAKE_DIRECTORY "${MK_CAT_OUT_DIR}") - - if (NOT TARGET build_all_mods) - add_custom_target(build_all_mods) - endif() - - build_modules( - ${MK_CAT_MOD} - SOURCE_DIR "${MK_CAT_SOURCES}" - DEST_DIR "${MK_CAT_OUT_DIR}" - ${external_modcc} # NB: expands to 'MODCC <binary>' to add an optional argument - MODCC_FLAGS -t cpu -t gpu ${ARB_MODCC_FLAGS} -N arb::${MK_CAT_NAME}_catalogue - GENERATES .hpp _cpu.cpp _gpu.cpp _gpu.cu - TARGET build_catalogue_${MK_CAT_NAME}_mods) - - set(catalogue_${MK_CAT_NAME}_source ${CMAKE_CURRENT_BINARY_DIR}/${MK_CAT_NAME}_catalogue.cpp) - set(catalogue_${MK_CAT_NAME}_options -A arbor -I ${MK_CAT_OUT_DIR} -o ${catalogue_${MK_CAT_NAME}_source} -B multicore -C ${MK_CAT_NAME} -N arb::${MK_CAT_NAME}_catalogue) + set(mk_cat_modcc_flags -t cpu ${ARB_MODCC_FLAGS} -N arb -c ${MK_CAT_NAME} -o ${MK_CAT_OUT_DIR}) if(ARB_WITH_GPU) - list(APPEND catalogue_${MK_CAT_NAME}_options -B gpu) + set(mk_cat_modcc_flags, -t gpu ${mk_cat_modcc_flags}) endif() - add_custom_command( - OUTPUT ${catalogue_${MK_CAT_NAME}_source} - COMMAND ${MK_CAT_PREFIX}/generate_catalogue ${catalogue_${MK_CAT_NAME}_options} ${MK_CAT_MOD} ${MK_CAT_CXX} - COMMENT "Building catalogue ${MK_CAT_NAME}" - DEPENDS ${MK_CAT_PREFIX}/generate_catalogue) - - add_custom_target(${MK_CAT_NAME}_catalogue_cpp_target DEPENDS ${catalogue_${MK_CAT_NAME}_source}) - add_dependencies(build_catalogue_${MK_CAT_NAME}_mods ${MK_CAT_NAME}_catalogue_cpp_target) - add_dependencies(build_all_mods build_catalogue_${MK_CAT_NAME}_mods) + set(catalogue_${MK_CAT_NAME}_source ${MK_CAT_OUT_DIR}/${MK_CAT_NAME}_catalogue.cpp) foreach(mech ${MK_CAT_MOD}) + list(APPEND catalogue_${MK_CAT_NAME}_mods ${MK_CAT_SOURCES}/${mech}.mod) list(APPEND catalogue_${MK_CAT_NAME}_source ${MK_CAT_OUT_DIR}/${mech}_cpu.cpp) if(ARB_WITH_GPU) list(APPEND catalogue_${MK_CAT_NAME}_source ${MK_CAT_OUT_DIR}/${mech}_gpu.cpp ${MK_CAT_OUT_DIR}/${mech}_gpu.cu) endif() endforeach() + + add_custom_command(OUTPUT ${catalogue_${MK_CAT_NAME}_source} + DEPENDS ${catalogue_${MK_CAT_NAME}_mods} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND ${modcc} ${mk_cat_modcc_flags} ${catalogue_${MK_CAT_NAME}_mods} + COMMENT "modcc generating: ${catalogue_${MK_CAT_NAME}_source}") + foreach(mech ${MK_CAT_CXX}) list(APPEND catalogue_${MK_CAT_NAME}_source ${MK_CAT_OUT_DIR}/${mech}_cpu.cpp) if(ARB_WITH_GPU) @@ -124,28 +94,23 @@ function("make_catalogue") endif() endforeach() - set(${MK_CAT_OUTPUT} ${catalogue_${MK_CAT_NAME}_source} PARENT_SCOPE) - - if(${MK_CAT_STANDALONE}) - add_library(${MK_CAT_NAME}-catalogue SHARED ${catalogue_${MK_CAT_NAME}_source}) - target_compile_definitions(${MK_CAT_NAME}-catalogue PUBLIC STANDALONE=1) + add_library(${MK_CAT_NAME}-catalogue SHARED ${catalogue_${MK_CAT_NAME}_source}) + target_compile_definitions(${MK_CAT_NAME}-catalogue PUBLIC STANDALONE=1) - if(ARB_WITH_GPU) - target_compile_definitions(${MK_CAT_NAME}-catalogue PUBLIC ARB_GPU_ENABLED) - endif() + if(ARB_WITH_GPU) + target_compile_definitions(${MK_CAT_NAME}-catalogue PUBLIC ARB_GPU_ENABLED) + endif() - target_compile_options(${MK_CAT_NAME}-catalogue PUBLIC ${MK_CAT_CXX_FLAGS_TARGET}) - set_target_properties(${MK_CAT_NAME}-catalogue - PROPERTIES - SUFFIX ".so" - PREFIX "" - CXX_STANDARD 17) - target_include_directories(${MK_CAT_NAME}-catalogue PUBLIC "${MK_CAT_ARBOR}/arbor/") - - if(TARGET arbor) - target_link_libraries(${MK_CAT_NAME}-catalogue PRIVATE arbor) - else() - target_link_libraries(${MK_CAT_NAME}-catalogue PRIVATE arbor::arbor) - endif() + target_compile_options(${MK_CAT_NAME}-catalogue PUBLIC ${MK_CAT_CXX_FLAGS_TARGET}) + set_target_properties(${MK_CAT_NAME}-catalogue + PROPERTIES + SUFFIX ".so" + PREFIX "" + CXX_STANDARD 17) + + if(TARGET arbor) + target_link_libraries(${MK_CAT_NAME}-catalogue PRIVATE arbor) + else() + target_link_libraries(${MK_CAT_NAME}-catalogue PRIVATE arbor::arbor) endif() endfunction() diff --git a/mechanisms/CMakeLists.txt b/mechanisms/CMakeLists.txt index 97dbf7e3..9f1c14f5 100644 --- a/mechanisms/CMakeLists.txt +++ b/mechanisms/CMakeLists.txt @@ -1,46 +1,29 @@ include(BuildModules.cmake) +set(arbor-builtin-mechanisms) + # Define catalogues make_catalogue( NAME bbp - SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/bbp" - OUTPUT "CAT_BBP_SOURCES" MOD CaDynamics_E2 Ca_HVA Ca_LVAst Ih Im K_Pst K_Tst Nap_Et2 NaTa_t NaTs2_t SK_E2 SKv3_1 - CXX - PREFIX "${PROJECT_SOURCE_DIR}/mechanisms" - CXX_FLAGS_TARGET "${ARB_CXX_FLAGS_TARGET_FULL}" - STANDALONE FALSE - VERBOSE ${ARB_CAT_VERBOSE}) + VERBOSE ${ARB_CAT_VERBOSE} + ADD_DEPS ON) make_catalogue( NAME allen - SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/allen" - OUTPUT "CAT_ALLEN_SOURCES" MOD CaDynamics Ca_HVA Ca_LVA Ih Im Im_v2 K_P K_T Kd Kv2like Kv3_1 NaTa NaTs NaV Nap SK - CXX - PREFIX "${PROJECT_SOURCE_DIR}/mechanisms" - CXX_FLAGS_TARGET "${ARB_CXX_FLAGS_TARGET_FULL}" - STANDALONE FALSE - VERBOSE ${ARB_CAT_VERBOSE}) + VERBOSE ${ARB_CAT_VERBOSE} + ADD_DEPS ON) make_catalogue( NAME default - SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/default" - OUTPUT "CAT_DEFAULT_SOURCES" MOD exp2syn expsyn expsyn_curr expsyn_stdp hh kamt kdrmt nax nernst pas gj decay inject - CXX - PREFIX "${PROJECT_SOURCE_DIR}/mechanisms" - CXX_FLAGS_TARGET "${ARB_CXX_FLAGS_TARGET_FULL}" - STANDALONE FALSE - VERBOSE ${ARB_CAT_VERBOSE}) + VERBOSE ${ARB_CAT_VERBOSE} + ADD_DEPS ON) -# Join sources -set(arbor_mechanism_sources - ${CAT_BBP_SOURCES} - ${CAT_ALLEN_SOURCES} - ${CAT_DEFAULT_SOURCES} - PARENT_SCOPE) +# This re-exports +set(arbor-builtin-mechanisms ${arbor-builtin-mechanisms} PARENT_SCOPE) if(ARB_WITH_CUDA_CLANG OR ARB_WITH_HIP_CLANG) - set_source_files_properties(${arbor_mechanism_sources} PROPERTIES LANGUAGE CXX) + set_source_files_properties(${arbor-builtin-mechs} PROPERTIES LANGUAGE CXX) endif() diff --git a/mechanisms/default/pas.mod b/mechanisms/default/pas.mod index d7ffb028..7b085c5b 100644 --- a/mechanisms/default/pas.mod +++ b/mechanisms/default/pas.mod @@ -10,7 +10,6 @@ UNITS { (S) = (siemens) } - INITIAL {} PARAMETER { diff --git a/mechanisms/generate_catalogue b/mechanisms/generate_catalogue deleted file mode 100755 index 2a63f7d1..00000000 --- a/mechanisms/generate_catalogue +++ /dev/null @@ -1,170 +0,0 @@ -#!/usr/bin/env python3 - -# Note: compatible with Python2.7 and Python3. - -from __future__ import print_function -import sys -import string -import argparse - -def parse_arguments(): - def append_slash(s): - return s+'/' if s and not s.endswith('/') else s - - class ConciseHelpFormatter(argparse.HelpFormatter): - def __init__(self, **kwargs): - super(ConciseHelpFormatter, self).__init__(max_help_position=20, **kwargs) - - def _format_action_invocation(self, action): - if not action.option_strings: - return super(ConciseHelpFormatter, self)._format_action_invocation(action) - else: - optstr = ', '.join(action.option_strings) - if action.nargs==0: - return optstr - else: - return optstr+' '+self._format_args(action, action.dest.upper()) - - parser = argparse.ArgumentParser( - description = 'Generate global default catalogue source for Arbor build.', - usage = '%(prog)s [options] [module...]', - add_help = False, - formatter_class = ConciseHelpFormatter) - - parser.add_argument( - 'modules', - nargs = '*', - help = argparse.SUPPRESS) - - group = parser.add_argument_group('Options') - - group.add_argument( - '-I', '--module-prefix', - default = 'mechanisms', - metavar = 'PATH', - dest = 'modpfx', - type = append_slash, - help = 'directory prefix for module includes, default "%(default)s"') - - group.add_argument( - '-A', '--arbor-prefix', - default = '', - metavar = 'PATH', - dest = 'arbpfx', - type = append_slash, - help = 'directory prefix for arbor includes, default "%(default)s"') - - group.add_argument( - '-B', '--backend', - default = [], - action = 'append', - dest = 'backends', - metavar = 'BACKEND', - help = 'register implementations for back-end %(metavar)s') - - group.add_argument( - '-N', '--namespace', - default = [], - action = 'append', - dest = 'namespaces', - metavar = 'NAMESPACE', - help = 'add %(metavar)s to list of implicitly included namespaces') - - group.add_argument( - '-C', '--catalogue', - default = 'default', - dest = 'catalogue', - help = 'catalogue name, default "%(default)s"') - - group.add_argument( - '-o', '--output', - default = [], - dest = 'output', - metavar = 'FILE', - help = 'save output to %(metavar)s (default is to print to stdout)') - - group.add_argument( - '-h', '--help', - action = 'help', - help = 'display this help and exit') - - return vars(parser.parse_args()) - - -def generate(catalogue, modpfx='', arbpfx='', modules=[], backends=[], namespaces=[], **rest): - src = string.Template(\ -r'''// Automatically generated by: -// $cmdline - -#include <${arbpfx}mechanism_abi.h> - -$module_includes - -#ifdef STANDALONE -extern "C" { - [[gnu::visibility("default")]] const void* get_catalogue(int* n) { - static arb_mechanism cat[${n_modules}] = { - ${insert_modules} - }; - *n = ${n_modules}; - return (void*)cat; - } -} -#else - -#include <${arbpfx}mechcat.hpp> -#include <${arbpfx}mechanism.hpp> -#include <${arbpfx}assert.hpp> - -namespace arb { -mechanism_catalogue build_${catalogue}_catalogue() { - mechanism_catalogue cat; - -#define ADD(make) do { \ - auto mech = make(); \ - auto ty = mech.type(); \ - auto nm = ty.name; \ - auto ig = mech.i_gpu(); \ - auto ic = mech.i_cpu(); \ - arb_assert(ic || ig); \ - cat.add(nm, ty); \ - if (ic) cat.register_implementation(nm, std::make_unique<arb::mechanism>(ty, *ic)); \ - if (ig) cat.register_implementation(nm, std::make_unique<arb::mechanism>(ty, *ig)); \ -} while (false) - - $add_modules - -#undef ADD - - return cat; -} - -ARB_ARBOR_API const mechanism_catalogue& global_${catalogue}_catalogue() { - static mechanism_catalogue cat = build_${catalogue}_catalogue(); - return cat; -} -} // namespace arb -#endif -''') - - def indent(n, lines): - return '{{:<{0!s}}}'.format(n+1).format('\n').join(lines) - - return src.safe_substitute(dict( - cmdline=" ".join(sys.argv), - arbpfx=arbpfx, - catalogue=catalogue, - module_includes=indent(0, - ['#include "{}{}.hpp"'.format(modpfx, m) for m in modules]), - add_modules=indent(4, [f'ADD(make_arb_{catalogue}_catalogue_{mod});' for mod in modules]), - n_modules=len(modules), - insert_modules=indent(12, [f'make_arb_{catalogue}_catalogue_{mod}(),' for mod in modules]), - )) - - -args = parse_arguments() -code = generate(**args) -if args['output']: - print(code, file = open(args['output'],'w')) -else: - print(code) diff --git a/modcc/CMakeLists.txt b/modcc/CMakeLists.txt index 62fb49f5..102b397f 100644 --- a/modcc/CMakeLists.txt +++ b/modcc/CMakeLists.txt @@ -56,10 +56,25 @@ export_visibility(libmodcc) add_executable(modcc ${modcc_sources}) -target_link_libraries(modcc PRIVATE libmodcc ext-tinyopt) -set_target_properties(modcc libmodcc PROPERTIES EXCLUDE_FROM_ALL ${ARB_WITH_EXTERNAL_MODCC}) -if (NOT ARB_WITH_EXTERNAL_MODCC) - install(TARGETS modcc RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +if (ARB_USE_BUNDLED_FMT) + target_include_directories(modcc + PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> + $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include> + PRIVATE + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../ext/fmt/include>) + + target_compile_definitions(modcc PRIVATE FMT_HEADER_ONLY) +else() + target_include_directories(modcc + PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> + $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>) + find_package(fmt REQUIRED) + target_link_libraries(modcc PRIVATE fmt::fmt-header-only) endif() +target_link_libraries(modcc PRIVATE libmodcc ext-tinyopt) +set_target_properties(modcc libmodcc PROPERTIES EXCLUDE_FROM_ALL OFF) +install(TARGETS modcc RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/modcc/modcc.cpp b/modcc/modcc.cpp index 3eea843b..0934c21a 100644 --- a/modcc/modcc.cpp +++ b/modcc/modcc.cpp @@ -3,6 +3,7 @@ #include <stdexcept> #include <unordered_map> #include <unordered_set> +#include <regex> #include <tinyopt/tinyopt.h> @@ -19,6 +20,8 @@ #include "io/bulkio.hpp" #include "io/pprintf.hpp" +#include <fmt/format.h> + using std::cout; using std::cerr; @@ -66,8 +69,9 @@ auto key_by_value(const Map& map, const V& v) -> decltype(map.begin()->first) { struct Options { std::string outprefix; - std::string modfile; + std::vector<std::string> modfiles; std::string modulename; + std::string catalogue; bool verbose = false; bool analysis = false; std::unordered_set<targetKind> targets; @@ -97,12 +101,14 @@ std::ostream& operator<<(std::ostream& out, const Options& opt) { targets += " "+key_by_value(targetKindMap, t); } - return out << - table_prefix{"file"} << opt.modfile << line_end << - table_prefix{"output"} << (opt.outprefix.empty()? "-": opt.outprefix) << line_end << + for (const auto& f: opt.modfiles) { + out << table_prefix{"file"} << f << line_end; + } + out << table_prefix{"output"} << (opt.outprefix.empty()? "-": opt.outprefix) << line_end << table_prefix{"verbose"} << noyes[opt.verbose] << line_end << table_prefix{"targets"} << targets << line_end << table_prefix{"analysis"} << noyes[opt.analysis] << line_end; + return out; } std::ostream& operator<<(std::ostream& out, const printer_options& popt) { @@ -139,7 +145,7 @@ const char* usage_str = "-V|--verbose [Toggle verbose mode]\n" "-A|--analyse [Toggle analysis mode]\n" "-T|--trace-codegen [Leave trace marks in generated source]\n" - "<filename> [File to be compiled]\n"; + "<filenames> [Files to be compiled]\n"; int main(int argc, char **argv) { using namespace to; @@ -159,16 +165,14 @@ int main(int argc, char **argv) { } }; - auto add_target = [&opt](targetKind t) { - opt.targets.insert(t); - }; + auto add_target = [&opt](targetKind t) { opt.targets.insert(t); }; to::option options[] = { - { opt.modfile, to::mandatory}, - { opt.outprefix, "-o", "--output" }, + { to::push_back(opt.modfiles)}, + { opt.outprefix, "-o", "--output-dir" }, { to::set(opt.verbose), to::flag, "-V", "--verbose" }, { to::set(opt.analysis), to::flag, "-A", "--analyse" }, - { opt.modulename, "-m", "--module" }, + { opt.catalogue, "-c", "--catalogue"}, { popt.cpp_namespace, "-N", "--namespace" }, { to::action(enable_simd), to::flag, "-s", "--simd" }, { popt.simd, "-S", "--simd-abi" }, @@ -184,109 +188,192 @@ int main(int argc, char **argv) { return 1; } - try { - auto emit_header = [&opt](const char* h) { - if (opt.verbose) { - cout << green("[") << h << green("]") << "\n"; - } - }; + if (!opt.catalogue.empty()) popt.cpp_namespace += "::" + opt.catalogue + "_catalogue"; - if (opt.verbose) { - static const std::string tableline = cyan("."+std::string(60, '-')+".")+"\n"; - cout << tableline; - cout << opt; - cout << popt; - cout << tableline; - } + std::vector<std::string> modules; - // Load module file and initialize Module object. - - Module m(io::read_all(opt.modfile), opt.modfile); + for (const auto& modfile: opt.modfiles) { + try { + auto emit_header = [&opt](const char* h) { + if (opt.verbose) { + cout << green("[") << h << green("]") << "\n"; + } + }; - if (m.empty()) { - return report_error("empty file: "+opt.modfile); - } + if (opt.verbose) { + static const std::string tableline = cyan("."+std::string(60, '-')+".")+"\n"; + cout << tableline; + cout << opt; + cout << popt; + cout << tableline; + } - if (!opt.modulename.empty()) { - m.module_name(opt.modulename); - } + // Load module file and initialize Module object. + Module m(io::read_all(modfile), modfile); - // Perform parsing and semantic analysis passes. + if (m.empty()) { + return report_error("empty file: "+modfile); + } - emit_header("parsing"); - Parser p(m, false); - if (!p.parse()) { - // Parser::parse() writes its own errors to stderr. - return 1; - } + // Perform parsing and semantic analysis passes. - emit_header("semantic analysis"); - m.semantic(); - if (m.has_warning()) { - cerr << yellow("Warnings:\n"); - cerr << m.warning_string() << "\n"; - } - if (m.has_error()) { - return report_error(m.error_string()); - } + emit_header("parsing"); + Parser p(m, false); + if (!p.parse()) { + // Parser::parse() writes its own errors to stderr. + return 1; + } - // Generate backend-specific sources for each backend provided. + emit_header("semantic analysis"); + m.semantic(); + if (m.has_warning()) { + cerr << yellow("Warnings:\n"); + cerr << m.warning_string() << "\n"; + } + if (m.has_error()) { + return report_error(m.error_string()); + } - emit_header("code generation"); + // Generate backend-specific sources for each backend provided. - // If no output prefix given, use the module name. - std::string prefix = opt.outprefix.empty()? m.module_name(): opt.outprefix; + emit_header("code generation"); - bool have_cpu = opt.targets.find(targetKind::cpu) != opt.targets.end(); - bool have_gpu = opt.targets.find(targetKind::gpu) != opt.targets.end(); + std::string prefix = m.module_name(); + if (!opt.outprefix.empty()) { + if (opt.outprefix.back() != '/') opt.outprefix += "/"; + prefix = opt.outprefix + prefix; + } - io::write_all(build_info_header(m, popt, have_cpu, have_gpu), prefix+".hpp"); - for (targetKind target: opt.targets) { - std::string outfile = prefix; - switch (target) { - case targetKind::gpu: - io::write_all(emit_gpu_cpp_source(m, popt), outfile+"_gpu.cpp"); - io::write_all(emit_gpu_cu_source(m, popt), outfile+"_gpu.cu"); - break; - case targetKind::cpu: - io::write_all(emit_cpp_source(m, popt), outfile+"_cpu.cpp"); - break; + bool have_cpu = opt.targets.find(targetKind::cpu) != opt.targets.end(); + bool have_gpu = opt.targets.find(targetKind::gpu) != opt.targets.end(); + + io::write_all(build_info_header(m, popt, have_cpu, have_gpu), prefix+".hpp"); + for (targetKind target: opt.targets) { + std::string outfile = prefix; + switch (target) { + case targetKind::gpu: + io::write_all(emit_gpu_cpp_source(m, popt), outfile+"_gpu.cpp"); + io::write_all(emit_gpu_cu_source(m, popt), outfile+"_gpu.cu"); + break; + case targetKind::cpu: + io::write_all(emit_cpp_source(m, popt), outfile+"_cpu.cpp"); + break; + } } - } - // Optional analysis report. + // Optional analysis report. - if (opt.analysis) { - cout << green("performance analysis\n"); - for (auto &symbol: m.symbols()) { - if (auto method = symbol.second->is_api_method()) { - cout << white("-------------------------\n"); - cout << yellow("method " + method->name()) << "\n"; - cout << white("-------------------------\n"); + if (opt.analysis) { + cout << green("performance analysis\n"); + for (auto &symbol: m.symbols()) { + if (auto method = symbol.second->is_api_method()) { + cout << white("-------------------------\n"); + cout << yellow("method " + method->name()) << "\n"; + cout << white("-------------------------\n"); - FlopVisitor flops; - method->accept(&flops); - cout << white("FLOPS\n") << flops.print() << "\n"; + FlopVisitor flops; + method->accept(&flops); + cout << white("FLOPS\n") << flops.print() << "\n"; - MemOpVisitor memops; - method->accept(&memops); - cout << white("MEMOPS\n") << memops.print() << "\n"; + MemOpVisitor memops; + method->accept(&memops); + cout << white("MEMOPS\n") << memops.print() << "\n"; + } } } + + modules.push_back(m.module_name()); + } + catch (io::bulkio_error& e) { + return report_error(e.what()); + } + catch (compiler_exception& e) { + return report_ice(pprintf("% @ %", e.what(), e.location())); + } + catch (std::exception& e) { + return report_ice(e.what()); + } + catch (...) { + return report_ice(""); } } - catch (io::bulkio_error& e) { - return report_error(e.what()); - } - catch (compiler_exception& e) { - return report_ice(pprintf("% @ %", e.what(), e.location())); - } - catch (std::exception& e) { - return report_ice(e.what()); - } - catch (...) { - return report_ice(""); - } - return 0; + if (!opt.catalogue.empty()) { + const auto prefix = std::regex_replace(popt.cpp_namespace, std::regex{"::"}, "_"); + { + std::ofstream out(opt.outprefix + opt.catalogue + "_catalogue.cpp"); + out << "// Automatically generated by modcc\n" + "\n" + "#include <arbor/mechanism_abi.h>\n" + "\n"; + + for (const auto& mod: modules) { + out << fmt::format("#include \"{}.hpp\"\n", mod); + } + + out << "\n" + "#ifdef STANDALONE\n" + "extern \"C\" {\n" + " [[gnu::visibility(\"default\")]] const void* get_catalogue(int* n) {\n"; + out << fmt::format(" *n = {0};\n" + " static arb_mechanism cat[{0}] = {{\n", + opt.modfiles.size()); + for (const auto& mod: modules) { + out << fmt::format(" make_{}_{}(),\n", prefix, mod); + } + out << " };\n" + " return (void*)cat;\n" + " }\n" + "}\n" + "\n" + "#else\n" + "\n" + "#include <arbor/mechanism.hpp>\n" + "#include <arbor/assert.hpp>\n" + "\n"; + out << fmt::format("#include \"{0}_catalogue.hpp\"\n" + "\n" + "namespace arb {{\n" + "mechanism_catalogue build_{0}_catalogue() {{\n" + " mechanism_catalogue cat;\n", + opt.catalogue); + for (const auto& mod: modules) { + out << fmt::format(" {{\n" + " auto mech = make_{}_{}();\n" + " auto ty = mech.type();\n" + " auto nm = ty.name;\n" + " auto ig = mech.i_gpu();\n" + " auto ic = mech.i_cpu();\n" + " arb_assert(ic || ig);\n" + " cat.add(nm, ty);\n" + " if (ic) cat.register_implementation(nm, std::make_unique<arb::mechanism>(ty, *ic));\n" + " if (ig) cat.register_implementation(nm, std::make_unique<arb::mechanism>(ty, *ig));\n" + " }}\n", + prefix, mod); + } + + out << " return cat;\n" + "}\n" + "\n"; + out << fmt::format("ARB_ARBOR_API const mechanism_catalogue& global_{0}_catalogue() {{\n" + " static mechanism_catalogue cat = build_{0}_catalogue();\n" + " return cat;\n" + "}}\n", + opt.catalogue); + out << "} // namespace arb\n" + "#endif\n"; + } + { + std::ofstream out(opt.outprefix + opt.catalogue + "_catalogue.hpp"); + out << fmt::format("#pragma once\n" + "\n" + "#include <arbor/mechcat.hpp>\n" + "#include <arbor/export.hpp>\n" + "\n" + "namespace arb {{\n" + "ARB_ARBOR_API const mechanism_catalogue& global_{0}_catalogue();\n" + "}}\n", + opt.catalogue); + } + } } diff --git a/modcc/printer/cprinter.cpp b/modcc/printer/cprinter.cpp index 8eb2fc21..fd1ecc15 100644 --- a/modcc/printer/cprinter.cpp +++ b/modcc/printer/cprinter.cpp @@ -427,7 +427,7 @@ ARB_LIBMODCC_API std::string emit_cpp_source(const Module& module_, const printe " result.write_ions = {3}write_ions;\n" " result.post_event = {3}post_event;\n" " return &result;\n" - " }}" + " }}\n" "}}\n\n"), std::regex_replace(opt.cpp_namespace, std::regex{"::"}, "_"), name, diff --git a/scripts/build-catalogue.in b/scripts/build-catalogue.in index 0dc73ce7..6deea74e 100755 --- a/scripts/build-catalogue.in +++ b/scripts/build-catalogue.in @@ -131,7 +131,6 @@ exec_path = this_path.resolve() for path in [ exec_path / "modcc", - data_path / "generate_catalogue", data_path / "BuildModules.cmake", pack_path / "arbor-config.cmake", ]: @@ -155,15 +154,12 @@ include(BuildModules.cmake) set(ARB_WITH_EXTERNAL_MODCC true) find_program(modcc NAMES modcc PATHS {exec_path}) -make_catalogue( +make_catalogue_standalone( NAME {name} SOURCES "${{CMAKE_CURRENT_SOURCE_DIR}}/mod" - OUTPUT "CAT_{name.upper()}_SOURCES" MOD {' '.join(mods)} CXX {' '.join(raw)} - PREFIX {data_path} CXX_FLAGS_TARGET ${{ARB_CXX_FLAGS_TARGET}} - STANDALONE ON VERBOSE {"ON" if verbose else "OFF"}) """ @@ -215,7 +211,6 @@ with TemporaryDirectory() as tmp: with open(tmp / "CMakeLists.txt", "w") as fd: fd.write(cmake) shutil.copy2(f"{data_path}/BuildModules.cmake", tmp) - shutil.copy2(f"{data_path}/generate_catalogue", tmp) out = tmp / "build" / "generated" / name os.makedirs(out, exist_ok=True) diff --git a/test/unit-modcc/CMakeLists.txt b/test/unit-modcc/CMakeLists.txt index 5f000613..0f78f2c8 100644 --- a/test/unit-modcc/CMakeLists.txt +++ b/test/unit-modcc/CMakeLists.txt @@ -23,9 +23,7 @@ set(unit-modcc_sources ) add_executable(unit-modcc EXCLUDE_FROM_ALL ${unit-modcc_sources}) -if(NOT ARB_WITH_EXTERNAL_MODCC) - add_dependencies(tests unit-modcc) -endif() +add_dependencies(tests unit-modcc) target_link_libraries(unit-modcc PRIVATE libmodcc gtest) target_compile_definitions(unit-modcc PRIVATE "DATADIR=\"${CMAKE_CURRENT_SOURCE_DIR}\"") diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index db708766..d89a72c2 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -43,47 +43,11 @@ set(test_mechanisms include(${PROJECT_SOURCE_DIR}/mechanisms/BuildModules.cmake) -set(external_modcc) -if(ARB_WITH_EXTERNAL_MODCC) - set(external_modcc MODCC ${modcc}) -endif() -set(test_mech_dir ${CMAKE_CURRENT_BINARY_DIR}/mechanisms) - -build_modules( - ${test_mechanisms} - SOURCE_DIR mod - DEST_DIR "${test_mech_dir}" - ${external_modcc} - MODCC_FLAGS -t cpu -t gpu ${ARB_MODCC_FLAGS} -N testing - GENERATES .hpp _cpu.cpp _gpu.cpp _gpu.cu - TARGET build_test_mods -) - -set(test_mech_sources) -foreach(mech ${test_mechanisms}) - list(APPEND test_mech_sources ${test_mech_dir}/${mech}_cpu.cpp) - if(ARB_WITH_GPU) - list(APPEND test_mech_sources ${test_mech_dir}/${mech}_gpu.cpp) - list(APPEND test_mech_sources ${test_mech_dir}/${mech}_gpu.cu) - endif() -endforeach() - -# TODO: test_mechanism and mechanism prototype comparisons must -# be re-jigged. - -# set(proto_mechanisms pas hh expsyn exp2syn test_kin1 test_kinlva test_ca) -# set(mech_proto_dir "${CMAKE_CURRENT_BINARY_DIR}/mech_proto") -# file(MAKE_DIRECTORY "${mech_proto_dir}") -# -# build_modules( -# ${proto_mechanisms} -# SOURCE_DIR "${PROJECT_SOURCE_DIR}/mechanisms/mod" -# DEST_DIR "${mech_proto_dir}" -# MECH_SUFFIX _proto -# MODCC_FLAGS -t cpu -# GENERATES _cpu.hpp -# TARGET build_test_mods -# ) +make_catalogue( + NAME testing + MOD ${test_mechanisms} + VERBOSE ${ARB_CAT_VERBOSE} + ADD_DEPS OFF) # Unit test sources @@ -190,7 +154,6 @@ if(ARB_WITH_GPU) test_gpu_stack.cu test_multi_event_stream_gpu.cu test_reduce_by_key.cu - test_matrix_cpuvsgpu.cpp test_matrix_gpu.cpp test_mc_cell_group_gpu.cpp @@ -201,10 +164,7 @@ if(ARB_WITH_GPU) endif() if(ARB_WITH_NEUROML) - list(APPEND unit_sources - - test_nml_morphology.cpp - ) + list(APPEND unit_sources test_nml_morphology.cpp) endif() if(ARB_WITH_CUDA_CLANG OR ARB_WITH_HIP_CLANG) @@ -212,36 +172,33 @@ if(ARB_WITH_CUDA_CLANG OR ARB_WITH_HIP_CLANG) set_source_files_properties(${test_mech_sources} PROPERTIES LANGUAGE CXX) endif() -add_executable(unit EXCLUDE_FROM_ALL ${unit_sources} ${test_mech_sources}) -add_dependencies(unit build_test_mods) +add_executable(unit EXCLUDE_FROM_ALL ${unit_sources} ${catalogue-testing-mechanisms}) +add_dependencies(unit catalogue-testing-target) add_dependencies(tests unit) -if(${CMAKE_POSITION_INDEPENDENT_CODE}) - make_catalogue( + +make_catalogue_standalone( NAME dummy SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/dummy" - OUTPUT "CAT_DUMMY_SOURCES" MOD dummy CXX - PREFIX "${PROJECT_SOURCE_DIR}/mechanisms" CXX_FLAGS_TARGET ${ARB_CXX_FLAGS_TARGET_FULL} - STANDALONE ON VERBOSE ON) - target_compile_definitions(unit PRIVATE USE_DYNAMIC_CATALOGUES) - if(ARB_WITH_NVCC) + +if(ARB_WITH_NVCC) target_compile_options(dummy-catalogue PRIVATE -DARB_CUDA) - endif() - if(ARB_WITH_CUDA_CLANG) +endif() + +if(ARB_WITH_CUDA_CLANG) set(clang_options_ -DARB_CUDA -xcuda --cuda-gpu-arch=sm_60 --cuda-path=${CUDA_TOOLKIT_ROOT_DIR}) target_compile_options(unit PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${clang_options_}>) - endif() +endif() - if(ARB_WITH_HIP_CLANG) +if(ARB_WITH_HIP_CLANG) set(clang_options_ -DARB_HIP -xhip --amdgpu-target=gfx906 --amdgpu-target=gfx900) target_compile_options(unit PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${clang_options_}>) - endif() - add_dependencies(unit dummy-catalogue) endif() +add_dependencies(unit dummy-catalogue) if(ARB_WITH_GPU) target_compile_definitions(unit PRIVATE ARB_GPU_ENABLED) @@ -265,4 +222,5 @@ target_compile_options(unit PRIVATE ${ARB_CXX_FLAGS_TARGET_FULL}) target_compile_definitions(unit PRIVATE "-DDATADIR=\"${CMAKE_CURRENT_SOURCE_DIR}/../swc\"") target_compile_definitions(unit PRIVATE "-DLIBDIR=\"${PROJECT_BINARY_DIR}/lib\"") target_include_directories(unit PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") +target_include_directories(unit PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/generated/testing") target_link_libraries(unit PRIVATE gtest arbor arborenv arborio arborio-private-headers arbor-private-headers arbor-sup) diff --git a/test/unit/test_mechcat.cpp b/test/unit/test_mechcat.cpp index edd75498..a70306aa 100644 --- a/test/unit/test_mechcat.cpp +++ b/test/unit/test_mechcat.cpp @@ -278,7 +278,6 @@ TEST(mechcat, names) { } } -#ifdef USE_DYNAMIC_CATALOGUES TEST(mechcat, loading) { EXPECT_THROW(load_catalogue(LIBDIR "/does-not-exist-catalogue.so"), file_not_found_error); #if defined(ARB_ARBOR_SHARED_LIBRARY) @@ -293,7 +292,6 @@ TEST(mechcat, loading) { EXPECT_EQ(std::vector<std::string>{"dummy"}, cat.mechanism_names()); #endif } -#endif TEST(mechcat, derived_info) { auto cat = build_fake_catalogue(); diff --git a/test/unit/mod/ca_linear.mod b/test/unit/testing/ca_linear.mod similarity index 100% rename from test/unit/mod/ca_linear.mod rename to test/unit/testing/ca_linear.mod diff --git a/test/unit/mod/celsius_test.mod b/test/unit/testing/celsius_test.mod similarity index 100% rename from test/unit/mod/celsius_test.mod rename to test/unit/testing/celsius_test.mod diff --git a/test/unit/mod/diam_test.mod b/test/unit/testing/diam_test.mod similarity index 100% rename from test/unit/mod/diam_test.mod rename to test/unit/testing/diam_test.mod diff --git a/test/unit/mod/fixed_ica_current.mod b/test/unit/testing/fixed_ica_current.mod similarity index 100% rename from test/unit/mod/fixed_ica_current.mod rename to test/unit/testing/fixed_ica_current.mod diff --git a/test/unit/mod/gj0.mod b/test/unit/testing/gj0.mod similarity index 100% rename from test/unit/mod/gj0.mod rename to test/unit/testing/gj0.mod diff --git a/test/unit/mod/gj1.mod b/test/unit/testing/gj1.mod similarity index 100% rename from test/unit/mod/gj1.mod rename to test/unit/testing/gj1.mod diff --git a/test/unit/mod/linear_ca_conc.mod b/test/unit/testing/linear_ca_conc.mod similarity index 100% rename from test/unit/mod/linear_ca_conc.mod rename to test/unit/testing/linear_ca_conc.mod diff --git a/test/unit/mod/non_linear.mod b/test/unit/testing/non_linear.mod similarity index 100% rename from test/unit/mod/non_linear.mod rename to test/unit/testing/non_linear.mod diff --git a/test/unit/mod/param_as_state.mod b/test/unit/testing/param_as_state.mod similarity index 100% rename from test/unit/mod/param_as_state.mod rename to test/unit/testing/param_as_state.mod diff --git a/test/unit/mod/point_ica_current.mod b/test/unit/testing/point_ica_current.mod similarity index 100% rename from test/unit/mod/point_ica_current.mod rename to test/unit/testing/point_ica_current.mod diff --git a/test/unit/mod/post_events_syn.mod b/test/unit/testing/post_events_syn.mod similarity index 100% rename from test/unit/mod/post_events_syn.mod rename to test/unit/testing/post_events_syn.mod diff --git a/test/unit/mod/read_cai_init.mod b/test/unit/testing/read_cai_init.mod similarity index 100% rename from test/unit/mod/read_cai_init.mod rename to test/unit/testing/read_cai_init.mod diff --git a/test/unit/mod/read_eX.mod b/test/unit/testing/read_eX.mod similarity index 100% rename from test/unit/mod/read_eX.mod rename to test/unit/testing/read_eX.mod diff --git a/test/unit/mod/test0_kin_compartment.mod b/test/unit/testing/test0_kin_compartment.mod similarity index 100% rename from test/unit/mod/test0_kin_compartment.mod rename to test/unit/testing/test0_kin_compartment.mod diff --git a/test/unit/mod/test0_kin_conserve.mod b/test/unit/testing/test0_kin_conserve.mod similarity index 100% rename from test/unit/mod/test0_kin_conserve.mod rename to test/unit/testing/test0_kin_conserve.mod diff --git a/test/unit/mod/test0_kin_diff.mod b/test/unit/testing/test0_kin_diff.mod similarity index 100% rename from test/unit/mod/test0_kin_diff.mod rename to test/unit/testing/test0_kin_diff.mod diff --git a/test/unit/mod/test0_kin_steadystate.mod b/test/unit/testing/test0_kin_steadystate.mod similarity index 100% rename from test/unit/mod/test0_kin_steadystate.mod rename to test/unit/testing/test0_kin_steadystate.mod diff --git a/test/unit/mod/test1_kin_compartment.mod b/test/unit/testing/test1_kin_compartment.mod similarity index 100% rename from test/unit/mod/test1_kin_compartment.mod rename to test/unit/testing/test1_kin_compartment.mod diff --git a/test/unit/mod/test1_kin_conserve.mod b/test/unit/testing/test1_kin_conserve.mod similarity index 100% rename from test/unit/mod/test1_kin_conserve.mod rename to test/unit/testing/test1_kin_conserve.mod diff --git a/test/unit/mod/test1_kin_diff.mod b/test/unit/testing/test1_kin_diff.mod similarity index 100% rename from test/unit/mod/test1_kin_diff.mod rename to test/unit/testing/test1_kin_diff.mod diff --git a/test/unit/mod/test1_kin_steadystate.mod b/test/unit/testing/test1_kin_steadystate.mod similarity index 100% rename from test/unit/mod/test1_kin_steadystate.mod rename to test/unit/testing/test1_kin_steadystate.mod diff --git a/test/unit/mod/test2_kin_diff.mod b/test/unit/testing/test2_kin_diff.mod similarity index 100% rename from test/unit/mod/test2_kin_diff.mod rename to test/unit/testing/test2_kin_diff.mod diff --git a/test/unit/mod/test3_kin_diff.mod b/test/unit/testing/test3_kin_diff.mod similarity index 100% rename from test/unit/mod/test3_kin_diff.mod rename to test/unit/testing/test3_kin_diff.mod diff --git a/test/unit/mod/test4_kin_compartment.mod b/test/unit/testing/test4_kin_compartment.mod similarity index 100% rename from test/unit/mod/test4_kin_compartment.mod rename to test/unit/testing/test4_kin_compartment.mod diff --git a/test/unit/mod/test5_nonlinear_diff.mod b/test/unit/testing/test5_nonlinear_diff.mod similarity index 100% rename from test/unit/mod/test5_nonlinear_diff.mod rename to test/unit/testing/test5_nonlinear_diff.mod diff --git a/test/unit/mod/test6_nonlinear_diff.mod b/test/unit/testing/test6_nonlinear_diff.mod similarity index 100% rename from test/unit/mod/test6_nonlinear_diff.mod rename to test/unit/testing/test6_nonlinear_diff.mod diff --git a/test/unit/mod/test_ca.mod b/test/unit/testing/test_ca.mod similarity index 100% rename from test/unit/mod/test_ca.mod rename to test/unit/testing/test_ca.mod diff --git a/test/unit/mod/test_ca_read_valence.mod b/test/unit/testing/test_ca_read_valence.mod similarity index 100% rename from test/unit/mod/test_ca_read_valence.mod rename to test/unit/testing/test_ca_read_valence.mod diff --git a/test/unit/mod/test_cl_valence.mod b/test/unit/testing/test_cl_valence.mod similarity index 100% rename from test/unit/mod/test_cl_valence.mod rename to test/unit/testing/test_cl_valence.mod diff --git a/test/unit/mod/test_kin1.mod b/test/unit/testing/test_kin1.mod similarity index 100% rename from test/unit/mod/test_kin1.mod rename to test/unit/testing/test_kin1.mod diff --git a/test/unit/mod/test_kinlva.mod b/test/unit/testing/test_kinlva.mod similarity index 100% rename from test/unit/mod/test_kinlva.mod rename to test/unit/testing/test_kinlva.mod diff --git a/test/unit/mod/test_linear_init.mod b/test/unit/testing/test_linear_init.mod similarity index 100% rename from test/unit/mod/test_linear_init.mod rename to test/unit/testing/test_linear_init.mod diff --git a/test/unit/mod/test_linear_init_shuffle.mod b/test/unit/testing/test_linear_init_shuffle.mod similarity index 100% rename from test/unit/mod/test_linear_init_shuffle.mod rename to test/unit/testing/test_linear_init_shuffle.mod diff --git a/test/unit/mod/test_linear_state.mod b/test/unit/testing/test_linear_state.mod similarity index 100% rename from test/unit/mod/test_linear_state.mod rename to test/unit/testing/test_linear_state.mod diff --git a/test/unit/mod/write_Xi_Xo.mod b/test/unit/testing/write_Xi_Xo.mod similarity index 100% rename from test/unit/mod/write_Xi_Xo.mod rename to test/unit/testing/write_Xi_Xo.mod diff --git a/test/unit/mod/write_cai_breakpoint.mod b/test/unit/testing/write_cai_breakpoint.mod similarity index 100% rename from test/unit/mod/write_cai_breakpoint.mod rename to test/unit/testing/write_cai_breakpoint.mod diff --git a/test/unit/mod/write_eX.mod b/test/unit/testing/write_eX.mod similarity index 100% rename from test/unit/mod/write_eX.mod rename to test/unit/testing/write_eX.mod diff --git a/test/unit/mod/write_multiple_eX.mod b/test/unit/testing/write_multiple_eX.mod similarity index 100% rename from test/unit/mod/write_multiple_eX.mod rename to test/unit/testing/write_multiple_eX.mod diff --git a/test/unit/unit_test_catalogue.cpp b/test/unit/unit_test_catalogue.cpp index a87b0529..66b89f50 100644 --- a/test/unit/unit_test_catalogue.cpp +++ b/test/unit/unit_test_catalogue.cpp @@ -1,50 +1,14 @@ #include <arbor/mechcat.hpp> #include <arbor/version.hpp> +#include "testing_catalogue.hpp" + #ifdef ARB_GPU_ENABLED #include "backends/gpu/fvm.hpp" #endif #include "backends/multicore/fvm.hpp" #include "unit_test_catalogue.hpp" -#include "mechanisms/ca_linear.hpp" -#include "mechanisms/celsius_test.hpp" -#include "mechanisms/diam_test.hpp" -#include "mechanisms/gj0.hpp" -#include "mechanisms/gj1.hpp" -#include "mechanisms/non_linear.hpp" -#include "mechanisms/param_as_state.hpp" -#include "mechanisms/post_events_syn.hpp" -#include "mechanisms/test0_kin_diff.hpp" -#include "mechanisms/test_linear_state.hpp" -#include "mechanisms/test_linear_init.hpp" -#include "mechanisms/test_linear_init_shuffle.hpp" -#include "mechanisms/test0_kin_conserve.hpp" -#include "mechanisms/test0_kin_steadystate.hpp" -#include "mechanisms/test0_kin_compartment.hpp" -#include "mechanisms/test1_kin_compartment.hpp" -#include "mechanisms/test1_kin_diff.hpp" -#include "mechanisms/test1_kin_conserve.hpp" -#include "mechanisms/test2_kin_diff.hpp" -#include "mechanisms/test3_kin_diff.hpp" -#include "mechanisms/test4_kin_compartment.hpp" -#include "mechanisms/test5_nonlinear_diff.hpp" -#include "mechanisms/test6_nonlinear_diff.hpp" -#include "mechanisms/test1_kin_steadystate.hpp" -#include "mechanisms/fixed_ica_current.hpp" -#include "mechanisms/point_ica_current.hpp" -#include "mechanisms/linear_ca_conc.hpp" -#include "mechanisms/test_cl_valence.hpp" -#include "mechanisms/test_ca_read_valence.hpp" -#include "mechanisms/read_eX.hpp" -#include "mechanisms/write_Xi_Xo.hpp" -#include "mechanisms/write_multiple_eX.hpp" -#include "mechanisms/write_eX.hpp" -#include "mechanisms/read_cai_init.hpp" -#include "mechanisms/write_cai_breakpoint.hpp" -#include "mechanisms/test_ca.hpp" -#include "mechanisms/test_kin1.hpp" -#include "mechanisms/test_kinlva.hpp" #include "../gtest.h" @@ -57,50 +21,9 @@ } \ } while (false) -using namespace arb; - -mechanism_catalogue make_unit_test_catalogue(const mechanism_catalogue& from) { - mechanism_catalogue cat = from; - - ADD_MECH(cat, gj0); - ADD_MECH(cat, gj1); - ADD_MECH(cat, test_ca); - ADD_MECH(cat, test_kin1); - ADD_MECH(cat, test_kinlva); - ADD_MECH(cat, ca_linear); - ADD_MECH(cat, celsius_test); - ADD_MECH(cat, diam_test); - ADD_MECH(cat, param_as_state); - ADD_MECH(cat, post_events_syn); - ADD_MECH(cat, test_linear_state); - ADD_MECH(cat, test_linear_init); - ADD_MECH(cat, test_linear_init_shuffle); - ADD_MECH(cat, test0_kin_diff); - ADD_MECH(cat, test0_kin_conserve); - ADD_MECH(cat, test0_kin_steadystate); - ADD_MECH(cat, test0_kin_compartment); - ADD_MECH(cat, test1_kin_diff); - ADD_MECH(cat, test1_kin_conserve); - ADD_MECH(cat, test2_kin_diff); - ADD_MECH(cat, test3_kin_diff); - ADD_MECH(cat, test1_kin_steadystate); - ADD_MECH(cat, test1_kin_compartment); - ADD_MECH(cat, test4_kin_compartment); - ADD_MECH(cat, test5_nonlinear_diff); - ADD_MECH(cat, test6_nonlinear_diff); - ADD_MECH(cat, fixed_ica_current); - ADD_MECH(cat, non_linear); - ADD_MECH(cat, point_ica_current); - ADD_MECH(cat, linear_ca_conc); - ADD_MECH(cat, test_cl_valence); - ADD_MECH(cat, test_ca_read_valence); - ADD_MECH(cat, read_eX); - ADD_MECH(cat, write_Xi_Xo); - ADD_MECH(cat, write_multiple_eX); - ADD_MECH(cat, write_eX); - ADD_MECH(cat, read_cai_init); - ADD_MECH(cat, write_cai_breakpoint); - - return cat; +arb::mechanism_catalogue make_unit_test_catalogue(const arb::mechanism_catalogue& from) { + auto result = from; + result.import(arb::global_testing_catalogue(), ""); + return result; } diff --git a/test/unit/unit_test_catalogue.hpp b/test/unit/unit_test_catalogue.hpp index 68435023..a378132b 100644 --- a/test/unit/unit_test_catalogue.hpp +++ b/test/unit/unit_test_catalogue.hpp @@ -1,5 +1,6 @@ #pragma once +#include <arbor/export.hpp> #include <arbor/mechcat.hpp> arb::mechanism_catalogue make_unit_test_catalogue(const arb::mechanism_catalogue& from = {}); -- GitLab