Contents
Description
- This will describe the steps taken in the Continuity code that are required to go from a sympy user generated model to a compiled binary.
-
Each model type (e.g., Electrophysiology, Biomechanics, etc), extend the client/forms/ModelsForm class on the client side, which handles the model editor, and the server/utils/BuildSytem class on the server side, which handles compiling the model
-
The View Code, which displays the generated C/C++ code, option on the Compile tab is handled by ModelsForm.doGenerate, which calls the server command to generate the C/C++ code: (self.serverCmd(self.cmdPrefix + “generateCode”, [codeType])
Electrophysiology
Code Generation
-
The EP model editor is in client/forms/IonicModelsForm.
-
When hitting the ‘Compile’ button, ModelsForm.saveOrCompileOnServer is called.
-
The sympy code is generated next by IonicModelsForm.generateCode which calls client/forms/EPSympyGenerator. generateCode returns the sympy generated code as a string.
-
ModelsForm.saveOrCompileOnServer then calls the server at: server/utils/IonicBuildSympy.saveAndCompile (which is in BuildSystem.py)
-
IonicBuildSympy.saveAndCompile will save the sympy code to the server in a file named justmodel.py.
-
IonicBuildSympy.rawCompile will handle the sympy to C conversion and will call Instant to compile the model as follows:
-
rawCompile will call buildAndShow.py, which in-turn, calls gen_sympy_model.py which will generate the C code version of the sympy model, and will create files named: ode_model_model.cu and ode_model_model_pert_delta.c.
- ode_model_model.cu contains function ‘f’ and ode_model_model_pert_delta.c contains functions ‘advance_bes’ and ‘advance_be1’, which is called by advance_bes.
-
buildAndShow will then call tweak_delta.py which will read in the ode_model_model_pert_delta.c file and create the final version of the model, named either: ode_model_model_pert_delta_tweak_cpu.c or ode_model_model_pert_delta_tweak.c if we are using the CPU or GPU, respectively.
-
-
Finally, Instant will read in the source from src/ode_cuda/ode_solver_cpu.c and compile that file. The previously generated files (ode_model_model.cu and ode_model_model_pert_delta_tweak_cpu.c) are included in ode_solver_cpu.c via the #include select_cell_model.h directive.
- buildAndShow.py and gen_sympy_model.py are located in src/ode_cuda, but during compilation are copied to the directory where the binary get created.
Solving a Problem
- Solving starts in server/problem/Electrophysiology.py
Biomechanics Dynamic + Constitutive Model
Code Generation
-
Currently, if you compile a dynamic model from the Dynamic Model Editor (starting from ActiveTensionModelsForm.py), it follows a different route than if you compile it in conjunction with a constitutive model.
- The steps below outline the scenario when compiling a constitutive model that has a dynamic model associated with it.
-
The compile button is linked to EquationsEditorNew.doCompile(), which calls ModelsForm.saveAndCompile, which calls ModelsForm.saveOrCompileOnServer, which calls generateCode
-
GenerateCode is subclassed in MatModelsForm.
-
MatModelsForm.generateCode will then call src/csrc/strain_energy/sympy_to_c.parse_table_file, which will parse all the equations and extract all the different variable types used in the equations.
-
If sympy_to_c.parse_table_file finds a variable type of ‘dynamic_var’, that will let the code generator know that it will also have to deal with a dynamic model, and will then call biomechanicsCommands.GenDynamics.
-
GenDynamics will generate the sympy code from the currently submitted dynamic model (stored_data.activeTensionEquations), by calling client/forms/EPSympyGenerator, which actually does the code generation.
-
GenDynamics will then call IonicBuildSympy.rawCompileDynamics
-
IonicBuildSympy.rawCompileDynamics will:
- Write the generated sympy code to justmodel.py
- Generate dynamicData.pickle
- Generate ode_model_model_pert_delta_tweak_cpu_mech.c
- Generate odecusingle.so.
-
dynamicData.pickle contains the state variables and the dynamic equation, which the constitutive model needs to know about. For example, for the Hilltype model, the dynamicData.pickle file contains:
[['Lsi', 'Con'], {'T_active': ' T_active = rpar_global[16]*y_global[0]*max(-0.01, (rpar_global[2] - y_global[1])/rpar_global[12])*max(y_global[1] - rpar_global[5], 0.0001);'}]
-
ode_model_model_pert_delta_tweak_cpu_mech.c contains the dynamic code that needs to be included with the constitutive model when it is compiled.
-
Now that the dynamic model has been compile, the code continues on in MatModelsForm.generateCode and will call sympy_to_c.generate_c
-
sympy_to_c.generate_c will generate the C code that gets compiled in src/csrc/strain_energy/strain_energy.cpp. During the code generation process, the code will look for the presence of the ode_model_model_pert_delta_tweak_cpu_mech.c file, and will include that into strain_energy.cpp if it is found.
-
Additionally, during the code gen process, if an equation is of the form “dynamicVar()“, it will then look for the dynamicData.pickle file and put that equation into strain_energy.cpp
-
Once all the code generation is completed, ModelsForm.saveOrCompileOnServer will call ConstitutiveBuildSympy.saveAndCompile, and eventually the final compilation will occur at ConstitutiveBuildSympy.rawCompile.
-
The dynamic binary is created in src/ode_cuda, but will be copied to pcty/server/problem/Biomechanics/ActiveTensionModels/<modelName>
- The constitutive binary is created in src/csrc/strain_energy and will be copied to pcty/server/problem/Biomechanics/ and will be renamed to constitutive model name.