From 20311c9278555f1c1d22a69edda74becf0fbd91c Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Wed, 2 Dec 2020 09:59:33 +0100 Subject: [PATCH 01/10] Add first version of nrnivmodl-core.py --- coreneuron/CMakeLists.txt | 7 +- extra/CMakeLists.txt | 5 +- extra/nrnivmodl-core.py | 217 +++++++++++++++++++++++++++++++ extra/nrnivmodl_core_makefile.in | 111 +++++----------- 4 files changed, 257 insertions(+), 83 deletions(-) create mode 100644 extra/nrnivmodl-core.py diff --git a/coreneuron/CMakeLists.txt b/coreneuron/CMakeLists.txt index 0a023431b..8fa3a777c 100644 --- a/coreneuron/CMakeLists.txt +++ b/coreneuron/CMakeLists.txt @@ -167,12 +167,13 @@ set_target_properties( # ============================================================================= add_custom_target( nrniv-core ALL - COMMAND ${CMAKE_BINARY_DIR}/bin/nrnivmodl-core -b STATIC - -m ${CORENRN_MOD2CPP_BINARY} + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/bin/nrnivmodl-core.py + --build-type=STATIC --binary ${CORENRN_MOD2CPP_BINARY} + --verbose ${CORENEURON_PROJECT_SOURCE_DIR}/tests/integration/ring_gap/mod WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin - BYPRODUCTS + BYPRODUCTS ${CMAKE_BINARY_DIR}/bin/${CMAKE_SYSTEM_PROCESSOR}/special-core COMMENT "Running nrnivmodl-core with halfgap.mod") add_dependencies(nrniv-core scopmath coreneuron ${NMODL_TARGET_TO_DEPEND}) diff --git a/extra/CMakeLists.txt b/extra/CMakeLists.txt index 678a9dd31..c939deb96 100644 --- a/extra/CMakeLists.txt +++ b/extra/CMakeLists.txt @@ -65,8 +65,9 @@ set(nmodl_binary_name ${nmodl_name}) configure_file(nrnivmodl_core_makefile.in ${CMAKE_BINARY_DIR}/share/coreneuron/nrnivmodl_core_makefile @ONLY) -configure_file(nrnivmodl-core.in ${CMAKE_BINARY_DIR}/bin/nrnivmodl-core @ONLY) +configure_file(nrnivmodl-core.py + ${CMAKE_BINARY_DIR}/bin/nrnivmodl-core.py COPYONLY) install(FILES ${CMAKE_BINARY_DIR}/share/coreneuron/nrnivmodl_core_makefile DESTINATION share/coreneuron) -install(PROGRAMS ${CMAKE_BINARY_DIR}/bin/nrnivmodl-core DESTINATION bin) +install(PROGRAMS ${CMAKE_BINARY_DIR}/bin/nrnivmodl-core.py DESTINATION bin) diff --git a/extra/nrnivmodl-core.py b/extra/nrnivmodl-core.py new file mode 100644 index 000000000..0a0ffcc08 --- /dev/null +++ b/extra/nrnivmodl-core.py @@ -0,0 +1,217 @@ +#!/bin/python + +import argparse +import glob +import os +import shutil +import subprocess +import tempfile + +def get_root(): + parent_dir = os.path.dirname(os.path.realpath(__file__)) + return os.path.abspath(os.path.join(parent_dir, '..')) + +class ModFiles(): + def __init__(self, d, work_dir): + self.dir = d + self.work_dir = work_dir + self.basic_dir = os.path.join(get_root(), 'share', 'modfile') + + def get_files(self): + files = glob.glob(os.path.join(self.basic_dir, '*.mod')) + files.extend(glob.glob(os.path.join(self.dir, '*.mod'))) + return files + + """Artifical cell file cannot be processed by ispc so let's them be processed by GCC.""" + def get_ispc_files(self): + cpp_files = list() + ispc_files = list() + + for f in self.get_files(): + with open(f, "r") as h: + if "ARTIFICIAL_CELL" in h.read(): + cpp_files.append(f) + else: + ispc_files.append(f) + return (cpp_files, ispc_files) + + def get_ispc_files_for_rules(self, ispc_files): + l = list() + for f in ispc_files: + filename = os.path.basename(os.path.splitext(f)[0]) + l.append({'mod_file': f, 'ispc_file': filename+".ispc", 'obj_file': filename+".obj", 'cpp_file': filename+".cpp", 'o_file': filename+".o"}) + return l + + def get_cpp_files_for_rules(self, cpp_files): + l = list() + for f in cpp_files: + filename = os.path.basename(os.path.splitext(f)[0]) + l.append({'mod_file': f, 'cpp_file': filename+".cpp", 'o_file': filename+".o"}) + return l + +rules = { + 'ispc': r''' +$(MOD_OBJS_DIR)/{ispc_file}: {mod_file} + $(info Generating for {mod_file}) + $(MOD2CPP_ENV_VAR) $(MOD2CPP_BINARY_PATH) $< -o $(MOD_TO_CPP_DIR) $(MOD2CPP_BINARY_FLAG) + +$(MOD_OBJS_DIR)/{obj_file}: $(MOD_OBJS_DIR)/{ispc_file} + $(ISPC_COMPILE_CMD) $< -o $@ + +$(MOD_TO_CPP_DIR)/{cpp_file}: $(MOD_OBJS_DIR)/{ispc_file} + +$(MOD_OBJS_DIR)/{o_file}: $(MOD_TO_CPP_DIR)/{cpp_file} + $(CXX_COMPILE_CMD) -c $< -o $@ + +''', + 'cpp': r''' +$(MOD_TO_CPP_DIR)/{cpp_file}: {mod_file} + $(info Generating for {mod_file}) + $(MOD2CPP_ENV_VAR) $(MOD2CPP_BINARY_PATH) $< -o $(MOD_TO_CPP_DIR) $(NMODL_FLAGS_C) + +$(MOD_OBJS_DIR)/{o_file}: $(MOD_TO_CPP_DIR)/{cpp_file} $(KINDERIV_H_PATH) + $(CXX_COMPILE_CMD) -c $< -o $@ + +''', + 'general': r''' +MOD_FILES = {mod_files} +PRODUCED_OBJS_FROM_ISPC = {obj_ispc_files} +PRODUCED_OBJS_FROM_CPP = {obj_cpp_files} + +''' +} + +def parse_args(): + parser = argparse.ArgumentParser(description='') + parser.add_argument('--binary') + parser.add_argument('--nmodl', action='store_true') + + host_group = parser.add_mutually_exclusive_group() + host_group.add_argument('--cpp', action='store_false') + host_group.add_argument('--ispc', action='store_true') + host_group.add_argument('--omp', action='store_true') + + parser.add_argument('--gpu', choices=['cuda', 'OpenAcc'], const='OpenAcc', nargs='?') + + parser.add_argument('--work-dir', default=tempfile.mkdtemp(prefix='nrnivmodl-core_')) + + parser.add_argument('--build-type', choices=['STATIC', 'SHARED']) + + parser.add_argument('--suffix') + + parser.add_argument('-j', '--jobs', type=int, default=4) + parser.add_argument('--output-dir') + parser.add_argument('-v', '--verbose', action='store_true') + + parser.add_argument('mod_dir') + + return parser.parse_args() + +"""Generate drop-in""" +class MakefileGenerator(): + def __init__(self, arguments, files): + self.arguments = arguments + self.files = files + + def generate(self): + s = str() + s += self.generateCompilers() + s += self.generateRules() + + return s + + def generateHost(self): + if self.arguments.nmodl: + if self.arguments.cpp: + return 'host --c' + elif self.arguments.ispc: + return 'host --ispc' + elif self.arguments.omp: + return 'host --omp' + return '' + + def generateGPU(self): + if self.arguments.gpu: + if self.arguments.nmodl: + if self.arguments.gpu == 'OpenAcc': + return 'acc --oacc' + elif self.arguments.gpu == 'cuda': + return 'acc --cuda' + else: + raise "Error" + return '' + + def generateCompilers(self): + s = str() + if self.arguments.binary: + s += 'MOD2CPP_BINARY_PATH = {}'.format(self.arguments.binary) + else: + s += 'MOD2CPP_BINARY_PATH = {}'.format('$(NMODL_COMPILER)' if self.arguments.nmodl else '$(MOD2C_COMPILER)') + s += '\n' + s += 'MOD2CPP_BINARY_FLAG = ' + self.generateHost() + " " + self.generateGPU() + s += '\n' + + if self.arguments.ispc: + s += 'ISPC_COMPILE_CMD=$(ISPC) --pic\n' + + return s + + def generateRules(self): + s = str() + mod_files = [os.path.basename(x) for x in self.files.get_files()] + if self.arguments.ispc: + cpp_files, ispc_files = self.files.get_ispc_files() + cpp_files = self.files.get_cpp_files_for_rules(cpp_files) + ispc_files = self.files.get_ispc_files_for_rules(ispc_files) + obj_ispc_files = ['$(MOD_OBJS_DIR)/' + x['obj_file'] for x in ispc_files] + obj_cpp_files = ['$(MOD_OBJS_DIR)/' + x['o_file'] for x in cpp_files] + obj_cpp_files.extend(['$(MOD_OBJS_DIR)/' + x['o_file'] for x in ispc_files]) + s += rules['general'].format(obj_ispc_files=' '.join(obj_ispc_files), obj_cpp_files=' '.join(obj_cpp_files), mod_files=' '.join(mod_files)) + for f in ispc_files: + s += rules['ispc'].format(**f, work_dir=arguments.work_dir) + else: + files = self.files.get_files() + cpp_files = self.files.get_cpp_files_for_rules(files) + obj_cpp_files = ['$(MOD_OBJS_DIR)/' + x['o_file'] for x in cpp_files] + s += rules['general'].format(obj_ispc_files='', obj_cpp_files=' '.join(obj_cpp_files), mod_files=' '.join(mod_files)) + + for f in cpp_files: + s += rules['cpp'].format(**f, work_dir=arguments.work_dir) + + return s + +if __name__ == '__main__': + arguments = parse_args() + files = ModFiles(arguments.mod_dir, arguments.work_dir) + print("Output dir = 'make -f {}'".format(arguments.work_dir)) + G = MakefileGenerator(arguments, files) + Makefile = G.generate() + with open(os.path.join(arguments.work_dir, "GeneratedMakefile.make"), "w") as h: + h.write(Makefile) + shutil.copy(os.path.join(get_root(), 'share', 'coreneuron', 'nrnivmodl_core_makefile'), arguments.work_dir) + + make_args = [ 'make' ] + make_args.append('-f{}'.format(os.path.join(arguments.work_dir, 'nrnivmodl_core_makefile'))) + make_args.append('-j{}'.format(arguments.jobs)) + make_args.append('ROOT={}'.format(get_root())) + + if arguments.verbose: + make_args.append('VERBOSE=1') + + if arguments.binary: + make_args.append('MOD2CPP_BINARY={}'.format(arguments.binary)) + + if arguments.build_type: + make_args.append('BUILD_TYPE={}'.format(arguments.build_type)) + + if arguments.suffix: + make_args.append('MECHLIB_SUFFIX={}'.format(arguments.suffix)) + + if arguments.output_dir: + make_args.append('DESTDIR={}'.format(arguments.output_dir)) + make_args.append('install') + else: + make_args.append('all') + + print('Launching "{}"'.format(' '.join(make_args))) + subprocess.call(make_args) diff --git a/extra/nrnivmodl_core_makefile.in b/extra/nrnivmodl_core_makefile.in index f4b8d5df9..fda0abb55 100644 --- a/extra/nrnivmodl_core_makefile.in +++ b/extra/nrnivmodl_core_makefile.in @@ -2,6 +2,18 @@ # CoreNEURON executable called "special-core" from the provided mod files. # Mod files are looked up in the MODS_PATH directory. +OUTPUT_DIR = @CMAKE_HOST_SYSTEM_PROCESSOR@ + +# Directory where cpp files are generated for each mod file +MOD_TO_CPP_DIR = $(OUTPUT_DIR)/corenrn/mod2c + +# Directory where cpp files are compiled +MOD_OBJS_DIR = $(OUTPUT_DIR)/corenrn/build + +# Find the directory of the current makefile +SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +include $(SELF_DIR)/GeneratedMakefile.make + # Current system OS OS_NAME := $(shell uname) @@ -11,9 +23,8 @@ COMMA_OP =, # Default variables for various targets MECHLIB_SUFFIX = MODS_PATH = . -OUTPUT_DIR = @CMAKE_HOST_SYSTEM_PROCESSOR@ DESTDIR = -TARGET_LIB_TYPE = $(BUILD_TYPE) +BUILD_TYPE = @COMPILE_LIBRARY_TYPE@ # CoreNEURON installation directories CORENRN_BIN_DIR := $(ROOT)/bin @@ -28,11 +39,8 @@ DERIVIMPLICIT_CPP_FILE = $(CORENRN_SHARE_CORENRN_DIR)/dimplic.cpp # name of the CoreNEURON binary SPECIAL_EXE = $(OUTPUT_DIR)/special-core -# Directory where cpp files are generated for each mod file -MOD_TO_CPP_DIR = $(OUTPUT_DIR)/corenrn/mod2c - -# Directory where cpp files are compiled -MOD_OBJS_DIR = $(OUTPUT_DIR)/corenrn/build +# By default, build $(SPECIAL_EXE) +all: $(SPECIAL_EXE) # Linked libraries gathered by CMake LDFLAGS = $(LINKFLAGS) @CORENRN_LINK_DEFS@ @@ -56,6 +64,18 @@ CXX_SHARED_LIB_CMD = $(CXX) $(CXXFLAGS) @CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS@ ISPC = @CMAKE_ISPC_COMPILER@ ISPC_COMPILE_CMD = $(ISPC) @CMAKE_ISPC_FLAGS@ -I$(CORENRN_INC_DIR) +# NMODL compiler +NMODL_COMPILER ?= $(ROOT)/bin/nmodl + +# MOD2C compiler +MOD2C_COMPILER ?= @CORENRN_MOD2C_COMPILER@ + +# Binary of MOD2C/NMODL depending on CMake option activated +ifeq (@nmodl_FOUND@, TRUE) + INCLUDES += -I@CORENRN_MOD2CPP_INCLUDE@ + ISPC_COMPILE_CMD += -I@CORENRN_MOD2CPP_INCLUDE@ +endif + # env variables required for mod2c or nmodl MOD2CPP_ENV_VAR = PYTHONPATH=@CORENRN_NMODL_PYTHONPATH@:${CORENRN_LIB_DIR}/python MODLUNIT=$(CORENRN_SHARE_MOD2CPP_DIR)/nrnunits.lib @@ -72,7 +92,7 @@ DIMPLIC_OBJ = $(MOD_OBJS_DIR)/_dimplic.o ENGINEMECH_OBJ = $(MOD_OBJS_DIR)/enginemech.o # Depending on static/shared build, determine library name and it's suffix -ifeq ($(TARGET_LIB_TYPE), STATIC) +ifeq ($(BUILD_TYPE), STATIC) LIB_SUFFIX = @CMAKE_STATIC_LIBRARY_SUFFIX@ corenrnmech_lib_target = coremech_lib_static else @@ -80,62 +100,13 @@ else corenrnmech_lib_target = coremech_lib_shared endif -# Binary of MOD2C/NMODL depending on CMake option activated -ifeq (@nmodl_FOUND@, TRUE) - MOD2CPP_BINARY_PATH = $(if $(MOD2CPP_BINARY),$(MOD2CPP_BINARY), @CORENRN_MOD2CPP_BINARY@) - INCLUDES += -I@CORENRN_MOD2CPP_INCLUDE@ - ISPC_COMPILE_CMD += -I@CORENRN_MOD2CPP_INCLUDE@ -else - MOD2CPP_BINARY_PATH = $(if $(MOD2CPP_BINARY),$(MOD2CPP_BINARY), $(CORENRN_BIN_DIR)/@nmodl_binary_name@) -endif - -# MOD files with full path, without path and names without .mod extension -mod_files_paths = $(sort $(wildcard $(MODS_PATH)/*.mod)) -mod_files_names = $(sort $(notdir $(wildcard $(MODS_PATH)/*.mod))) -mod_files_no_ext = $(mod_files_names:.mod=) - -# Find out artificial and non-artificial cells for ISPC backend -define check_file - # if ISPC is active then only separate mod files - ifeq (@CORENRN_ENABLE_ISPC@, ON) - ifeq ($(shell grep -q $(2) $(1); echo $$?), 0) - mod_art_files += $(MOD_TO_CPP_DIR)/$(notdir $(1)) - else - mod_non_art_files += $(MOD_TO_CPP_DIR)/$(notdir $(1)) - endif - else - mod_all_files += $(MOD_TO_CPP_DIR)/$(notdir $(1)) - endif -endef - -# Iterate over all available mod files and make group -$(foreach mod_file, $(mod_files_paths), $(eval $(call check_file, $(mod_file), ARTIFICIAL_CELL))) - -# With ispc, artificial cells get translated as regular CPP backend -# Otherwise, all mod files are compiled as CPP backend -ifeq (@CORENRN_ENABLE_ISPC@, ON) - mod_files_for_cpp_backend = $(mod_art_files) -else - mod_files_for_cpp_backend = $(mod_all_files) -endif - -# CPP files and their obkects -mod_cpp_files = $(patsubst %.mod,%.cpp,$(mod_files_for_cpp_backend)) -mod_cpp_objs = $(addprefix $(MOD_OBJS_DIR)/,$(addsuffix .o,$(basename $(mod_files_no_ext)))) - -# For ISPC backend, we use all non-artificial cells -mod_ispc_srcs_names = $(notdir $(mod_non_art_files)) -mod_ispc_files = $(patsubst %.mod,%.ispc,$(mod_non_art_files)) -mod_ispc_cpp_files = $(patsubst %.mod,%.cpp,$(mod_non_art_files)) -mod_ispc_objs = $(addprefix $(MOD_OBJS_DIR)/,$(addsuffix .obj,$(basename $(mod_ispc_srcs_names)))) - # We use $ORIGIN (@loader_path in OSX) ORIGIN_RPATH := $(if $(filter Darwin,$(OS_NAME)),@loader_path,$$ORIGIN) SONAME_OPTION := -Wl,$(if $(filter Darwin,$(OS_NAME)),-install_name${COMMA_OP}@rpath/,-soname${COMMA_OP})$(notdir ${COREMECH_LIB_PATH}) LIB_RPATH = $(if $(DESTDIR),$(DESTDIR)/lib,$(ORIGIN_RPATH)) # All objects used during build -ALL_OBJS = $(MOD_FUNC_OBJ) $(DIMPLIC_OBJ) $(mod_cpp_objs) $(mod_ispc_objs) +ALL_OBJS = $(MOD_FUNC_OBJ) $(DIMPLIC_OBJ) $(PRODUCED_OBJS_FROM_CPP) $(PRODUCED_OBJS_FROM_ISPC) # Colors for pretty printing C_RESET := \033[0m @@ -186,31 +157,15 @@ coremech_lib_static: $(ALL_OBJS) $(ENGINEMECH_OBJ) build_always rm -f ${COREMECH_LIB_PATH}; \ ar cq ${COREMECH_LIB_PATH} $(ENGINEMECH_OBJ) $(ALL_OBJS) $(MOD_OBJS_DIR)/scopmath/*.o; -# compile cpp files to .o -$(MOD_OBJS_DIR)/%.o: $(MOD_TO_CPP_DIR)/%.cpp $(KINDERIV_H_PATH) | $(MOD_OBJS_DIR) - $(CXX_COMPILE_CMD) -c $< -o $@ - -# compile ispc files to .obj -$(MOD_OBJS_DIR)/%.obj: $(MOD_TO_CPP_DIR)/%.ispc | $(MOD_OBJS_DIR) - $(ISPC_COMPILE_CMD) $< -o $@ - -# translate MOD files to ISPC using NMODL -$(mod_ispc_files): $(MOD_TO_CPP_DIR)/%.ispc: $(MODS_PATH)/%.mod | $(MOD_TO_CPP_DIR) - $(MOD2CPP_ENV_VAR) $(MOD2CPP_BINARY_PATH) $< -o $(MOD_TO_CPP_DIR)/ $(NMODL_FLAGS_ISPC) - -# translate MOD files to CPP using mod2c/NMODL -$(mod_cpp_files): $(MOD_TO_CPP_DIR)/%.cpp: $(MODS_PATH)/%.mod | $(MOD_TO_CPP_DIR) - $(MOD2CPP_ENV_VAR) $(MOD2CPP_BINARY_PATH) $< -o $(MOD_TO_CPP_DIR)/ $(MOD2CPP_FLAGS_C) - -# static pattern to set up the dependencies for the previous recipe -$(mod_ispc_cpp_files): $(MOD_TO_CPP_DIR)/%.cpp: $(MOD_TO_CPP_DIR)/%.ispc - # generate mod registration function. Dont overwrite if it's not changed $(MOD_FUNC_CPP): build_always | $(MOD_TO_CPP_DIR) - @PERL_EXECUTABLE@ $(CORENRN_SHARE_CORENRN_DIR)/mod_func.c.pl $(mod_files_names) > $(MOD_FUNC_CPP).tmp + @PERL_EXECUTABLE@ $(CORENRN_SHARE_CORENRN_DIR)/mod_func.c.pl $(MOD_FILES) > $(MOD_FUNC_CPP).tmp diff -q $(MOD_FUNC_CPP).tmp $(MOD_FUNC_CPP) || \ mv $(MOD_FUNC_CPP).tmp $(MOD_FUNC_CPP) +$(MOD_FUNC_OBJ) $(DIMPLIC_OBJ): $(MOD_OBJS_DIR)/%.o: $(MOD_TO_CPP_DIR)/%.cpp $(KINDERIV_H_PATH) | $(MOD_OBJS_DIR) + $(CXX_COMPILE_CMD) -c $< -o $@ + # header to avoid function callbacks using function pointers $(KINDERIV_H_PATH): $(mod_cpp_files) build_always | $(MOD_TO_CPP_DIR) cd $(MOD_TO_CPP_DIR); \ From a338ed1afc668d86d8b8bcedaa8cfa4ad9c3f941 Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Thu, 17 Dec 2020 14:28:16 +0100 Subject: [PATCH 02/10] Continue --- extra/nrnivmodl-core.py | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/extra/nrnivmodl-core.py b/extra/nrnivmodl-core.py index 0a0ffcc08..8108205fa 100644 --- a/extra/nrnivmodl-core.py +++ b/extra/nrnivmodl-core.py @@ -51,14 +51,14 @@ def get_cpp_files_for_rules(self, cpp_files): rules = { 'ispc': r''' -$(MOD_OBJS_DIR)/{ispc_file}: {mod_file} +$(MOD_TO_CPP_DIR)/{ispc_file}: {mod_file} $(info Generating for {mod_file}) $(MOD2CPP_ENV_VAR) $(MOD2CPP_BINARY_PATH) $< -o $(MOD_TO_CPP_DIR) $(MOD2CPP_BINARY_FLAG) -$(MOD_OBJS_DIR)/{obj_file}: $(MOD_OBJS_DIR)/{ispc_file} +$(MOD_OBJS_DIR)/{obj_file}: $(MOD_TO_CPP_DIR)/{ispc_file} $(ISPC_COMPILE_CMD) $< -o $@ -$(MOD_TO_CPP_DIR)/{cpp_file}: $(MOD_OBJS_DIR)/{ispc_file} +$(MOD_TO_CPP_DIR)/{cpp_file}: $(MOD_TO_CPP_DIR)/{ispc_file} $(MOD_OBJS_DIR)/{o_file}: $(MOD_TO_CPP_DIR)/{cpp_file} $(CXX_COMPILE_CMD) -c $< -o $@ @@ -87,9 +87,10 @@ def parse_args(): parser.add_argument('--nmodl', action='store_true') host_group = parser.add_mutually_exclusive_group() - host_group.add_argument('--cpp', action='store_false') - host_group.add_argument('--ispc', action='store_true') - host_group.add_argument('--omp', action='store_true') + host_group.add_argument('--cpp', action='store_const', dest='host_backend', const='cpp') + host_group.add_argument('--ispc', action='store_const', dest='host_backend', const='ispc') + host_group.add_argument('--omp', action='store_const', dest='host_backend', const='omp') + parser.set_defaults(host_backend='cpp') parser.add_argument('--gpu', choices=['cuda', 'OpenAcc'], const='OpenAcc', nargs='?') @@ -122,11 +123,11 @@ def generate(self): def generateHost(self): if self.arguments.nmodl: - if self.arguments.cpp: + if self.arguments.host_backend == 'cpp': return 'host --c' - elif self.arguments.ispc: + elif self.arguments.host_backend == 'ispc': return 'host --ispc' - elif self.arguments.omp: + elif self.arguments.host_backend == 'omp': return 'host --omp' return '' @@ -141,6 +142,11 @@ def generateGPU(self): raise "Error" return '' + def generatePasses(self): + if self.arguments.nmodl: + return 'passes --inline' + return '' + def generateCompilers(self): s = str() if self.arguments.binary: @@ -148,18 +154,15 @@ def generateCompilers(self): else: s += 'MOD2CPP_BINARY_PATH = {}'.format('$(NMODL_COMPILER)' if self.arguments.nmodl else '$(MOD2C_COMPILER)') s += '\n' - s += 'MOD2CPP_BINARY_FLAG = ' + self.generateHost() + " " + self.generateGPU() + s += 'MOD2CPP_BINARY_FLAG = ' + self.generateHost() + " " + self.generateGPU() + " " + self.generatePasses() s += '\n' - if self.arguments.ispc: - s += 'ISPC_COMPILE_CMD=$(ISPC) --pic\n' - return s def generateRules(self): s = str() mod_files = [os.path.basename(x) for x in self.files.get_files()] - if self.arguments.ispc: + if self.arguments.host_backend == 'ispc': cpp_files, ispc_files = self.files.get_ispc_files() cpp_files = self.files.get_cpp_files_for_rules(cpp_files) ispc_files = self.files.get_ispc_files_for_rules(ispc_files) From 4d1e1f7b751127bfd5fb92aed38489e24c3016af Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Fri, 18 Dec 2020 11:40:33 +0100 Subject: [PATCH 03/10] Remove old script --- extra/nrnivmodl-core.in | 148 ---------------------------------------- 1 file changed, 148 deletions(-) delete mode 100755 extra/nrnivmodl-core.in diff --git a/extra/nrnivmodl-core.in b/extra/nrnivmodl-core.in deleted file mode 100755 index 697573517..000000000 --- a/extra/nrnivmodl-core.in +++ /dev/null @@ -1,148 +0,0 @@ -#!/bin/bash - -# ----------------------------------------------------------------------------- -# Copyright 2020 Blue Brain Project -# nrnivmodl-core is used to compile mod files for coreneuron -# ----------------------------------------------------------------------------- - -set -e - -# TODO : mod2c_core can be linked with (HPE-)MPI library -# and running that under slurm allocation result into -# runtime error. For now, unset PMI_RANK variable -# which is sufficint to avoid issue with HPE-MPI+SLURM. -unset PMI_RANK - -# name of the script -APP_NAME=$(basename $0) - -# directory and parent directory of this script -PARENT_DIR="$(dirname $BASH_SOURCE)/.." -ROOT_DIR=$(@PERL_EXECUTABLE@ -e "use Cwd 'abs_path'; print abs_path('$PARENT_DIR')") - -# default arguments : number of parallel builds and default mod file path -PARALLEL_BUILDS=4 -params_MODS_PATH="." -params_BUILD_TYPE="@COMPILE_LIBRARY_TYPE@" - -# prefix for common options : make sure to rename these if options are changed. -MAKE_OPTIONS="MECHLIB_SUFFIX MOD2CPP_BINARY MOD2CPP_RUNTIME_FLAGS DESTDIR INCFLAGS LINKFLAGS MODS_PATH VERBOSE BUILD_TYPE" - -# parse CLI args -while getopts "n:m:a:d:i:l:Vp:b:h" OPT; do - case "$OPT" in - n) - # suffix for mechanism library - params_MECHLIB_SUFFIX="$OPTARG";; - m) - # nmodl or mod2c binary to use - params_MOD2CPP_BINARY="$OPTARG";; - a) - # additional nmodl flags to be used - params_MOD2CPP_RUNTIME_FLAGS="$OPTARG";; - d) - # destination install directory - params_DESTDIR="$OPTARG";; - i) - # extra include flags - params_INCFLAGS="$OPTARG";; - l) - # extra link flags - params_LINKFLAGS="$OPTARG";; - V) - # make with verbose - params_VERBOSE=1;; - p) - # option for parallel build (with -j) - PARALLEL_BUILDS="$OPTARG";; - b) - # make with verbose - params_BUILD_TYPE="$OPTARG";; - h) - echo "$APP_NAME [options, ...] [mods_path]" - echo "Options:" - echo " -n The model name, used as a suffix in the shared library" - echo " -m NMODL/mod2c code generation compiler path" - echo " -a Runtime flags for NMODL/mod2c" - echo " -i Definitions passed to the compiler, typically '-I dir..'" - echo " -l Definitions passed to the linker, typically '-Lx -lylib..'" - echo " -d Install to dest_dir. Default: Off." - echo " -V Verbose: show commands executed by make" - echo " -p Number of parallel builds (Default: $PARALLEL_BUILDS)" - echo " -b libcorenrnmech library type" - exit 0;; - ?) - exit 1;; - esac -done - -# consume an option -shift $(($OPTIND - 1)) - -# only one mod files directory is supported in neuron and coreneuron -if [ $# -gt 1 ]; then - echo "[ERROR] $APP_NAME expects at most one mod dir. See syntax: '$APP_NAME -h' " - exit 1 -fi - -# if defined mods dir be in $1 -if [ $# -eq 1 ]; then - # Note: due to bug #712 makefile wont handle mod dir with spaces, so we let it fail here - params_MODS_PATH=$1 -fi - -# warn if no mod files provided -if [ -d $params_MODS_PATH ]; then - ls $params_MODS_PATH/*.mod &>/dev/null || echo "WARNING: No mod files found, compiling default ones only!" -else - echo "FATAL: Invalid mods directory: '$params_MODS_PATH'" - exit 1 -fi - -# temporary directory where mod files will be copied -temp_mod_dir=@CMAKE_HOST_SYSTEM_PROCESSOR@/core/mods -mkdir -p $temp_mod_dir - -# copy mod files with include files. note that ${ROOT_DIR}/share -# has inbuilt mod files and user provided mod files are in $params_MODS_PATH. -set +e -for mod_dir in ${ROOT_DIR}/share/modfile $params_MODS_PATH; -do - # copy mod files and include files - files=`ls $mod_dir/*.mod $mod_dir/*.inc 2>/dev/null` - for f in $files; - do - # copy mod files only if it's changed (to avoid rebuild) - target_file_path=$temp_mod_dir/`basename $f` - if ! diff -q $f $target_file_path &>/dev/null; then - cp $f $target_file_path - fi - done -done -set -e - -# use new mod files directory for compilation -params_MODS_PATH=$temp_mod_dir - -# build params to make command -make_params=("ROOT=${ROOT_DIR}") -for param in $MAKE_OPTIONS; do - var="params_${param}" - if [ "${!var+x}" ]; then - make_params+=("$param=${!var}") - fi -done - -# if -d (deploy) provided, call "make install" -if [ "$params_DESTDIR" ]; then - make_params+=("install") -fi - -if [ "$params_VERBOSE" ]; then - make_params+=("VERBOSE=1") -fi - -# run makefile -echo "[INFO] Running: make -j$PARALLEL_BUILDS -f ${ROOT_DIR}/share/coreneuron/nrnivmodl_core_makefile ${make_params[@]}" -make -j$PARALLEL_BUILDS -f "${ROOT_DIR}/share/coreneuron/nrnivmodl_core_makefile" "${make_params[@]}" -echo "[INFO] MOD files built successfully for CoreNEURON" From 4d08820f3f5cdc34dbe76546f921504cf172cc8d Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Fri, 18 Dec 2020 17:30:12 +0100 Subject: [PATCH 04/10] Output everything in a subdirectory --- extra/nrnivmodl-core.py | 6 ++++-- extra/nrnivmodl_core_makefile.in | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/extra/nrnivmodl-core.py b/extra/nrnivmodl-core.py index 8108205fa..2bf11dee8 100644 --- a/extra/nrnivmodl-core.py +++ b/extra/nrnivmodl-core.py @@ -5,7 +5,6 @@ import os import shutil import subprocess -import tempfile def get_root(): parent_dir = os.path.dirname(os.path.realpath(__file__)) @@ -94,7 +93,7 @@ def parse_args(): parser.add_argument('--gpu', choices=['cuda', 'OpenAcc'], const='OpenAcc', nargs='?') - parser.add_argument('--work-dir', default=tempfile.mkdtemp(prefix='nrnivmodl-core_')) + parser.add_argument('--work-dir', default=os.path.abspath("./output")) parser.add_argument('--build-type', choices=['STATIC', 'SHARED']) @@ -185,6 +184,7 @@ def generateRules(self): if __name__ == '__main__': arguments = parse_args() + os.makedirs(arguments.work_dir) files = ModFiles(arguments.mod_dir, arguments.work_dir) print("Output dir = 'make -f {}'".format(arguments.work_dir)) G = MakefileGenerator(arguments, files) @@ -216,5 +216,7 @@ def generateRules(self): else: make_args.append('all') + make_args.append('WORK_DIR={}'.format(arguments.work_dir)) + print('Launching "{}"'.format(' '.join(make_args))) subprocess.call(make_args) diff --git a/extra/nrnivmodl_core_makefile.in b/extra/nrnivmodl_core_makefile.in index fda0abb55..1d48b0974 100644 --- a/extra/nrnivmodl_core_makefile.in +++ b/extra/nrnivmodl_core_makefile.in @@ -2,7 +2,7 @@ # CoreNEURON executable called "special-core" from the provided mod files. # Mod files are looked up in the MODS_PATH directory. -OUTPUT_DIR = @CMAKE_HOST_SYSTEM_PROCESSOR@ +OUTPUT_DIR = $(WORK_DIR)/@CMAKE_HOST_SYSTEM_PROCESSOR@ # Directory where cpp files are generated for each mod file MOD_TO_CPP_DIR = $(OUTPUT_DIR)/corenrn/mod2c From 2b49bed56b2741fe8a84ce353f3ee9828e637017 Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Mon, 4 Jan 2021 14:55:53 +0100 Subject: [PATCH 05/10] blah --- coreneuron/apps/main1.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/coreneuron/apps/main1.cpp b/coreneuron/apps/main1.cpp index 40a0140dc..5b43b3807 100644 --- a/coreneuron/apps/main1.cpp +++ b/coreneuron/apps/main1.cpp @@ -77,10 +77,8 @@ bool corenrn_units_use_legacy() { void (*nrn2core_part2_clean_)(); -#ifdef ISPC_INTEROP -// cf. utils/ispc_globals.c +// cf. utils/ispc/globals.cpp extern double ispc_celsius; -#endif /** * If "export OMP_NUM_THREADS=n" is not set then omp by default sets From 8abc96396701537a70f23e5c9c85acf0edcb2fec Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Mon, 4 Jan 2021 16:17:33 +0100 Subject: [PATCH 06/10] Revert "blah" This reverts commit 2b49bed56b2741fe8a84ce353f3ee9828e637017. --- coreneuron/apps/main1.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/coreneuron/apps/main1.cpp b/coreneuron/apps/main1.cpp index 3f26eb6e9..0c25b65e0 100644 --- a/coreneuron/apps/main1.cpp +++ b/coreneuron/apps/main1.cpp @@ -77,8 +77,10 @@ bool corenrn_units_use_legacy() { void (*nrn2core_part2_clean_)(); -// cf. utils/ispc/globals.cpp +#ifdef ISPC_INTEROP +// cf. utils/ispc_globals.c extern double ispc_celsius; +#endif /** * If "export OMP_NUM_THREADS=n" is not set then omp by default sets From 7a1c0e538477afd4e0b4b9d5631f93187c50b444 Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Mon, 4 Jan 2021 20:33:48 +0100 Subject: [PATCH 07/10] check before creating dirs --- extra/nrnivmodl-core.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extra/nrnivmodl-core.py b/extra/nrnivmodl-core.py index 2bf11dee8..530901f51 100644 --- a/extra/nrnivmodl-core.py +++ b/extra/nrnivmodl-core.py @@ -184,7 +184,8 @@ def generateRules(self): if __name__ == '__main__': arguments = parse_args() - os.makedirs(arguments.work_dir) + if not os.path.exists(arguments.work_dir): + os.makedirs(arguments.work_dir) files = ModFiles(arguments.mod_dir, arguments.work_dir) print("Output dir = 'make -f {}'".format(arguments.work_dir)) G = MakefileGenerator(arguments, files) From b49f7572d634095fef6d3cdc5e1fac370586de6d Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Tue, 5 Jan 2021 12:57:59 +0100 Subject: [PATCH 08/10] Current directory as default output --- extra/nrnivmodl-core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/nrnivmodl-core.py b/extra/nrnivmodl-core.py index 530901f51..ac5e2a871 100644 --- a/extra/nrnivmodl-core.py +++ b/extra/nrnivmodl-core.py @@ -93,7 +93,7 @@ def parse_args(): parser.add_argument('--gpu', choices=['cuda', 'OpenAcc'], const='OpenAcc', nargs='?') - parser.add_argument('--work-dir', default=os.path.abspath("./output")) + parser.add_argument('--work-dir', default=os.path.abspath(".")) parser.add_argument('--build-type', choices=['STATIC', 'SHARED']) From 17aebfd4e6804aa88558491c1bdee646463ab80f Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Tue, 5 Jan 2021 13:41:32 +0100 Subject: [PATCH 09/10] Fix for python2 --- extra/nrnivmodl-core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/nrnivmodl-core.py b/extra/nrnivmodl-core.py index ac5e2a871..b8feaf607 100644 --- a/extra/nrnivmodl-core.py +++ b/extra/nrnivmodl-core.py @@ -170,7 +170,7 @@ def generateRules(self): obj_cpp_files.extend(['$(MOD_OBJS_DIR)/' + x['o_file'] for x in ispc_files]) s += rules['general'].format(obj_ispc_files=' '.join(obj_ispc_files), obj_cpp_files=' '.join(obj_cpp_files), mod_files=' '.join(mod_files)) for f in ispc_files: - s += rules['ispc'].format(**f, work_dir=arguments.work_dir) + s += rules['ispc'].format(work_dir=arguments.work_dir, **f) else: files = self.files.get_files() cpp_files = self.files.get_cpp_files_for_rules(files) @@ -178,7 +178,7 @@ def generateRules(self): s += rules['general'].format(obj_ispc_files='', obj_cpp_files=' '.join(obj_cpp_files), mod_files=' '.join(mod_files)) for f in cpp_files: - s += rules['cpp'].format(**f, work_dir=arguments.work_dir) + s += rules['cpp'].format(work_dir=arguments.work_dir, **f) return s From 56c12eff92f6cfc7c955254c28004f3a3ebac2a9 Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Tue, 5 Jan 2021 15:58:45 +0100 Subject: [PATCH 10/10] Fix name of mod2c name --- extra/nrnivmodl_core_makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/nrnivmodl_core_makefile.in b/extra/nrnivmodl_core_makefile.in index d8ae56cad..51a71a199 100644 --- a/extra/nrnivmodl_core_makefile.in +++ b/extra/nrnivmodl_core_makefile.in @@ -70,7 +70,7 @@ ISPC_COMPILE_CMD = $(ISPC) @CMAKE_ISPC_FLAGS@ -I$(CORENRN_INC_DIR) NMODL_COMPILER ?= $(ROOT)/bin/nmodl # MOD2C compiler -MOD2C_COMPILER ?= @CORENRN_MOD2C_COMPILER@ +MOD2C_COMPILER ?= @CORENRN_MOD2CPP_BINARY@ # Binary of MOD2C/NMODL depending on CMake option activated ifeq (@nmodl_FOUND@, TRUE)