-
Notifications
You must be signed in to change notification settings - Fork 23
NIMBLE function compilation flow
This outlines the processing path of simple compilation of one nimbleFunction starting from a call to compileNimble:
- create nimbleProjectClass object
- call nimbleProjectClass$compileNimbleFunctionMulti
-
compileNimbleFunctionMulti is set up for a list of nimbleFunctions. It sorts them into lists of instances from the same generator (returned from a call to the nimbleFunction function).
-
Call nimbleProjectClass$compileNimbleFunction for a list of instances from the same nimbleFunction
-
compileNimbleFunction starts with some project book-keeping
-
calls nimbleProjectClass$buildNimbleFunctionCompilationInfo
-
buildNimbleFunctionCompilationInfo creates an nfProcessing object, which manages all steps:
- initialization creates a list of RCfunProcessing objects, each of which manages processing of a method (member function)
-
calls nfProcessing$process, which does the heart of the compilation steps:
-
setupTypesForUsingFunction: inspect the setupOutputs (objects in the environment in which setup code was evaluated that will be preserved and member data of the resulting C++ class) to populate the symbol table (setupSymTab) with their names and types
-
add any types from a base class to the symbol table
-
make the RCfunProcessing objects do argument matching and ordering (in each method)
-
make the RCfunProcessing objects do keyword processing
- keyword processing uses a template and partial evaluation system
-
evaluate any new setup code resulting from keyword processing
-
-
-
add resulting objects needed in run code to the symbol table
-
make the RCfunProcessing objects set up their local symbol tables
-
make the RCfunProcessing objects do their compilation steps, which is the heart of run code (method) processing
* convert the body (code) to exprClass objects, which are a bidirectional syntax tree with fields for annontation * process specific calls that need simple changes such as converting one name to another * build intermediate variables for the few cases where this is always necessary * initialize type information (dimensionality and scalar types) * setSizes, the most intensive step: annotates every nodes of the syntax tree with dimensionality, type, and eigenizability (yes, no, or maybe for conversion to C++ Eigen package code). This also generates run-time size checks, inserts intermediate variables, and populations the local symbol table with locally created objects. * insert size checks and other new lines generated by size processing * label sections of the syntax tree for eigenization * convert labeled sections into a syntax tree for C++ Eigen library, including generation of map variables and their initialization and insertion into the symbol table. * insert code needed for maps that were identified. Maps are indexed subsets of larger objects, such as X[2:4, ] * Collect a list of any type definitions used in methods (run code) that will be needed for any C++ compilation of this nimbleFunction to be successful.- creates a cppNimbleFunctionClass object
- calls cppNimbleFunctionClass::buildAll, which takes all the information in the nfProcessing object and creates information to generate C++ code
-
creates a cppProjectClass object: This will manage all .cpp and .h code files for the current compilation
-
-
adds the cppNimbleFunctionClass object creates above to the cppProjectClass object
-
calls cppProjectClass methods:
-
writeFiles: writes the .cpp and .h files
- compileFile: C++ compiles the .cpp and .h files
- loadSO: loads the result (shared object) of the C++ compilation
-
calls cppNimbleFunctionClass$buildCallable, which builds the R interface object for calling the compiled nimbleFunction(s)
-
-