-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Static vs jit #666
Draft
castigli
wants to merge
83
commits into
llvm
Choose a base branch
from
static-vs-JIT
base: llvm
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Static vs jit #666
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- while working on NMODL + LLVM, we don't worry that much about Python bindings by default - so lets disable them by default
* added NMODL_ENABLE_LLVM option to enable/disable llvm support in nmodl * LLVMHelper.cmake added to help with linking LLVM libraries - clang might need to use libstdc++ or libc++ linking - on BB5, using GCC with LLVM libraries is fine. But using clang results into lots of link error. Adding -stdlib=libstd++ solves the issue - use check_cxx_source_compiles to find out which cxx flag is needed
- added llvm dir under codegen where LLVM code generation work will live - llvm codegen visitor created that can be used as template for initial work - cmake adapted to enable llvm codegen based on CMake option - simple procedure.mod added that can be initial target for testing - new CLI option --llvm that runs LLVM codegen visitor - Enable CXX 14 because new LLVM versions require it
- install llvm via brew - set LLV_DIR variable so that CMake can find llvm-config
- print table with different build options, flags and paths used that can be helpful for debugging - fix git revision date for older git version - update INSTALL.md with correct brew paths for flex and bison
- test/unit/codegen/llvm.cpp added for unit testing LLVM code generation visitor - ./bin/testcodegen binary can be used to launch LLVM codegen specific tests - multiple llvm_map_components_to_libnames removed - update procedure.mod with simple examples for IR generation
* Added LLVM code generation for `ProcedureBlock`. * Added code generation routines for double, integer and boolean variable types. * Added binary and unary operator code generation: - Supported binary operators: +, -, *, /. - Supported unary operators: -. - Assignment (=) is also supported. * Added regex matching unit tests for LLVM code generation. * Fixed Travis CI/builds. fixes #451, fixes #452, fixes #456 Co-authored-by: Pramod Kumbhar <[email protected]>
* LLVM code generation for `FunctionBlock` is now supported. * Terminators in function or procedure blocks are enforced: - Every procedure must have `ret void` instruction. - Every function returns a double, specified by `ret_<function_name>`. * For local symbol table, code generation now uses LLVM's builtin `llvm::ValueSymbolTable`. fixes #454, fixes #469
* Add option to run LLVM optimisation passes - update CLI argument from --llvm to llvm --ir --opt - --ir runs CodegenLLVMVicitor and emits LLVM IR - if --opt is passed, we run basic LLVM optimisation passes - update simple test to check optimisation passes * Add function example in procedure.mod * Add test for LLVM optimisation passes and dead code removal
This patch adds support for function call code generation, particularly: - User-defined procedures and functions can now lowered to LLVM IR. - A framework for external method calls (e.g. sin, exp, etc.) has been created, currently `exp` and `pow` are supported. - Corresponding tests added. fixes #472
LLVM code generation for `IndexedName`s. - Added code generation for initialising arrays in LOCAL blocks (with both integer constants and macros). - Added support for indexing arrays. fixes #467
NMODL AST needs various transformation to generate C++ code or LLVM IR. This PR is begining of AST transformations to simplify code generation backends. * New CodegenLLVMHelperVisitor to perform various AST transformations to simplify code generation for various backends and simulators. * CodegenLLVMHelperVisitor is currently limited to LLVM backend to simplify initial implementation and keep C++ based backends working. * CodegenLLVMHelperVisitor now handles FUNCTIONS and PROCEDURES blocks - Replace LocalListStatement with CodegenVarStatement - Added new AST types for code generation - CodegenVar to represent variable used for code generation - CodegenVarType to represent codegen variable - CodegenVarListStatement to represent list of CodegenVar - CodegenStruct will be used in future to represent struct like NrnThread or Mechanism class See #474
* Added new BinaryOp for += and -= * Added string_to_binaryop function * Added Void node type to represent void return type * Added CodegenAtomicStatement for ion write statements * llvm helper started handling visit_nrn_state_block - NrnStateBlock is being converted into CodegenFunction - for loop body with solution blocks created - voltage and node index initialization code added - read and write ion statements are handled * Some of the functions are now moved into CodegenInfo Co-authored-by: Ioannis Magkanaris <[email protected]>
This commit introduces a functionality to execute functions from MOD file via LLVM jit. For that, there is now: - `JITDriver` class that, given a LLVM IR module, set ups the JIT compiler and is able to look up a function and execute it. - `Runner` class that wraps around JIT driver. It helps to initialise JIT with LLVM IR module only once, and then run multiple functions from it. To execute functions, `nmodl_llvm_runner` executable is used. It takes a single mod file and a specified entry-point function, and runs it via LLVM code generation pipeline and JIT driver. Only functions with double result types are supported at the moment. For example, for MOD file `foo.mod`: ``` FUNCTION one() { one = 1 } FUNCTION bar() { bar = one() + exp(1) } ``` running `nmodl_llvm_runner -f foo.mod -e bar` gives ``` Result: 3.718282 ``` Tests for execution of generated IR have been added as well. fixes #482 Co-authored-by: Pramod Kumbhar <[email protected]>
* Added more bin ops and refactored code - Now, there are code generation functions for all comparison and logical operators. - Code generation functions are now split based on the expression "type" (assignment, arithmetic, comparison, logical). Moreover, the lhs and rhs expression results can be both double and integer. This is important for control flow code generation and for the new AST node CodegenVarType. * Added support for NOT op * Added default type flag to switch between float and double * Added tests for single precision * Renames LLVM test file to codegen_llvm_ir.cpp to follow convention. * NOTE : Tests for new operators will be added when the first control flow node (most likely FOR node) will land. fixes #453
* visit_statement_block of all FUNCTION and PROCEDURE blocks was called resulting in changing LOCAL statement to DOUBLE statement * As statement block doesn't need to be visited for this purpose, rename function to convert_local_statement * Call convert_local_statement only when required i.e. only when codegen function creation time. fixes #491
* Handle CodegenVarType type in JSON printer - As AstNodeType is enum type and node itself, we need to print that explicitly * Indent json visitor jinja template - initially template was not indented as code generated was not looking good - now all generated code is automatically clang-formatted so it's less of a concern. Readability is important. fixes #493
* LLVM Helper visitor now can return a vector of `CodegenFunction`s. * LLVM Helper visitor has been integrated into LLVM visitor: - The type of variables is still double by default, but can also be inferred from `CodegenVarType` node. - Procedure's return type changed to int (so that error codes can be returned in the future). - New visitor functions added: for `CodegenReturn`, `CodegenFunction`, `CodegenVarList` and `CodegenVarType`.
* Added a new code generation function for conditional statements (`if`, `else if`, `else` and their nested variations). * Added tests for the new code generation: - IR unit tests. - Execution tests. * Fixed FP and integer comparison ordering in macros. fixes #468
Added error handling when a non-scope value is looked up. Before, such a lookup would yield a nullptr, therefore leading to a segmentation fault. This PR adds a lookup function that wraps around value symbol lookup, and throws an error with a message if nullptr is returned.
Added support for WHILE statement code generation. Corresponding tests for IR generation and execution were also added. Additional visitor for StatementBlock was added to reduce code duplication. fixes #500
* Moved info related function to codegen_info - Moved get_float_variables, codegen_int_variables, codegen_global_variables, codegen_shadow_variables into CodegenHelper - Move small utility functions from CodegenCVisitor to codeged_utils * Add proper variables to the mech_Instance * Adding LLVMStructBlock * Added test and visitor * Fix llvm codegen tests with x[0-9].*
- Added support for string function arguments. These are converted into global `i8` array values. - Added support for `printf` function call with variable number of arguments. - Refactored function/procedure call argument processing into a separate function. fixes #510
* Move code gen specific InstanceStruct node to codegen.yaml - nmodl.yaml file is more for language constructs - InstanceStruct is specific for code generation and hence move it to codegen.yaml * Update CI scripts * fix cmake-format with v==0.6.13
- instance structure now contains all global variables - instance structure now contains index variables for ions - nrn_state kernel now has all variables converted to instance - InstanceVarHelper added to query variable and it's location * Support for codegen variable with type * Add nmodl_to_json helper added in main.cpp * Added --vector-width CLI option * Add instance struct argument to nrn_state_hh * Add comments as TODOs to support LLVM IR generation Note that this commit and next commit (Part II) are required to make LLVM IR code generation working. Vector IR generation is working except indirect indexes. See comment in #531.
- remove undefined visit_codegen_instance_var - Improved member creation for instance struct - Instance struct type generation for kernel arguments - Proper integration of instance struct - Added scalar code generation for the kernel - Removed instance test since it is not created explicitly anymore - Fixed ordering for precision and width in LLVM Visitor - Added vector induction variable - Vectorised code for compute with direct loads fully functional - Instance naming fixed - (LLVM IR) Fixed compute vector code generation types - refactoring : improve coversion of double to int for the loop expressions
This PR adds a unit test to check LLVM instructions generated for the scalar kernel, particularly: - FOR loop blocks. - Induction variable increments and comparisons. - Correct loads through GEPs from the struct. Test for vectorised code generation would be added in a separate PR or when full vectorisation support (indirect indexing) would land.
Improved index code generation within the LLVM pipeline. The following issues were addressed: Array indices are i64 per LLVM's addressing convention. This means that if the value is not a constant, an additional sext instruction must be created. Bounds check is removed since it requires a certain analysis on the index value. This can be addressed in a separate PR. `IndexedName` code generation is separated into 2 functions The first, `get_array_length()` is responsible for array initialisation, the second, `get_array_index()`, for indexing. In latter case, we support the following cases: ``` ... // Indexing with an integer constant k[0] = ... // Indexing with an integer expression k[10 - 10] // Indexing with a `Name` AST node that is an integer // (in our case a FOR loop induction variable or a variable // with `CodegenVarType` == `Integer` k[id] = ... k[ena_id] = ... ``` Note that the case: ``` // id := loop integer induction variable k[id + 1] = ... ``` is not supported for 2 reasons: On the AST level, as per #545 the expression would contain a Name and not VarName node that fails the code generation. The case only arises in the kernel functions like state_update, where indexing is "artificially" created with indexing by a Name only. fixes #541
* CodegenLLVMHelperVisitor improved without hardcoded parameters * Added get_instance_struct_ptr to get instance structure for variable information * test/unit/codegen/codegen_data_helper.cpp : first draft implementation of codegen data helper * Added test for typecasting to the proper struct type Co-authored-by: Pramod Kumbhar <[email protected]>
- fixes the case, where loaded value was taken from the stack, but was never actually put there
Added support for vector predication. Currently, we support a very basic predication pattern (that will be extended in the future): ```c++ IF (/*condition*/) { // code here, no nested conditionals } ELSE { // code here, no nested conditionals } ``` **What has been changed and added** 1. Removed vectorization check Before, in the `FOR` statement visitor we were checking whether the code can be vectorized. After refactoring `llvm::IRBuilder<>` into a separate class, there is no interface to reset the builder's vector width. Hence, this check leads to visitor having scalar vector width of 1, and builder having the same vector width. ```c++ if (!can_vectorize(node, sym_tab)) { vector_width = 1; ir_builder.generate_scalar_code(); } ``` In order to avoid any issues, this check is simply removed and will be added in the separate PR. 2. Predication support - `can_vectorize` has been changed to support a single `IF` or `IF/ELSE` pair. - A special vectorized `IF` AST node visitor has been added. - If generating code within `IF` AST node, instructions are masked. 3. Added execution and IR tests fixes #539
* Improved cmake versioning of LLVM * Added ^ support * Added more math functions intrinsics with tests * Added compute time variance and min/max times in benchmarking output
* With this PR alloca instructions are always inserted in the beginning of the function entry block. This is done to avoid them in the while or for loops, where allocations per iteration cause stack overflow (if the IR is not optimized). * Insertion point for allocas is the enetry block now See #653
Added support for fast math flags in LLVM backend. Currently, the user can specify them via command-line (this approach was chosen for easier benchmarking). The specified flags are named exactly the same as in LLVM. This feature is useful to enable previously unsafe FP-math optimizations. For example, fused-multiply-add instructions can now be generated when lowering LLVM IR to assembly or executing via JIT. Example: ```c++ // fma.mod FUNCTION fma(a, b, c) { fma = (a * b) + c } ``` ```bash $ ./nmodl fma.mod --verbose debug llvm --ir --fmf nnan contract afn --opt ``` ```llvm define double @fma(double %a, double %b, double %c) { %1 = fmul nnan contract afn double %a, %b %2 = fadd nnan contract afn double %1, %c ret double %2 } ```
Can one of the admins verify this patch? |
- NMODL parser uses VarName on the LHS of assignment expression - Inline visitor was using Name on the LHS of assignment expression Related to #667
* Added support for `libsystem_m` and `SLEEF` vector libraries. The first one is supported by LLVM internally, so it comes for free with LLVM 13. For `SLEEF`, basic support was added for AArch64 and x86 architectures. Currently, we support - `exp` - `pow` * Added corresponding IR checks for `libsystem_m` and `SLEEF` (both AArch64 and x86). * Updated LLVM binaries for MAC OS CI, as well as for latest LLVM 13 (trunk) to fix link errors for Darwin vector library. Co-authored-by: Pramod Kumbhar <[email protected]>
pramodk
force-pushed
the
llvm
branch
2 times, most recently
from
March 9, 2022 12:04
bc5a4c4
to
c80a44d
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
No description provided.