Skip to content
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
wants to merge 83 commits into
base: llvm
Choose a base branch
from
Draft

Static vs jit #666

wants to merge 83 commits into from

Commits on May 8, 2021

  1. Disable python bindings for faster build

      - while working on NMODL + LLVM, we don't worry that much
        about Python bindings by default
      - so lets disable them by default
    pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    16d3cab View commit details
    Browse the repository at this point in the history
  2. Integrate LLVM into CMake build system

      * 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
    pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    b1cfda6 View commit details
    Browse the repository at this point in the history
  3. Code infrastructure for LLVM code generation backend

     - 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
    pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    46d4779 View commit details
    Browse the repository at this point in the history
  4. Azure CI fixes for LLVM build and README update

     - install llvm via brew
     - set LLV_DIR variable so that CMake can find llvm-config
    pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    51987dc View commit details
    Browse the repository at this point in the history
  5. Print build status after cmake configure stage

      - 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
    pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    ae07ce4 View commit details
    Browse the repository at this point in the history
  6. Adding test template for LLVM codegen

      - 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
    pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    c540fb1 View commit details
    Browse the repository at this point in the history
  7. Initial LLVM codegen vistor routines (#457)

    * 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]>
    georgemitenkov and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    724605c View commit details
    Browse the repository at this point in the history
  8. FunctionBlock code generation and terminator checks (#470)

    * 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
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    b621d4e View commit details
    Browse the repository at this point in the history
  9. Add option to run LLVM optimisation passes (#471)

    * 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
    pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    917a7da View commit details
    Browse the repository at this point in the history
  10. Add function call LLVM code generation (#477)

    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
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    b261ba9 View commit details
    Browse the repository at this point in the history
  11. Support for IndexedName codegen (#478)

    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
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    7884de8 View commit details
    Browse the repository at this point in the history
  12. Improvements for code generation specific transformations (#483)

    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
    pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    dbda271 View commit details
    Browse the repository at this point in the history
  13. nrn_state function generation in NMODL AST to help LLVM codegen (#484)

    * 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]>
    pramodk and iomaganaris committed May 8, 2021
    Configuration menu
    Copy the full SHA
    83abf60 View commit details
    Browse the repository at this point in the history
  14. Running functions from MOD files via LLVM JIT (#482)

    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]>
    georgemitenkov and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    bcc091b View commit details
    Browse the repository at this point in the history
  15. Extended support for binary ops and refactoring (#489)

    * 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
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    838ed6f View commit details
    Browse the repository at this point in the history
  16. Avoid converting LOCAL statement in all StatementBlocks (#492)

    * 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
    pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    eaeb7aa View commit details
    Browse the repository at this point in the history
  17. Handle CodegenVarType type in JSON printer (#494)

    * 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
    pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    6d60ca9 View commit details
    Browse the repository at this point in the history
  18. Integrating LLVM helper into LLVM visitor (#497)

    * 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`.
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    5b32b31 View commit details
    Browse the repository at this point in the history
  19. LLVM code generation for if/else statements (#499)

    * 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
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    bc305ba View commit details
    Browse the repository at this point in the history
  20. Added error handling for values not in scope (#502)

    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.
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    c8ea994 View commit details
    Browse the repository at this point in the history
  21. Added support for WHILE statement (#501)

    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
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    a32f76b View commit details
    Browse the repository at this point in the history
  22. Create mechanism instance struct in LLVM IR (#507)

    * 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].*
    iomaganaris authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    bfaff72 View commit details
    Browse the repository at this point in the history
  23. Printf support in LLVM IR codegen (#510)

    - 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
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    b690961 View commit details
    Browse the repository at this point in the history
  24. Configuration menu
    Copy the full SHA
    a561c97 View commit details
    Browse the repository at this point in the history
  25. Move code gen specific InstanceStruct node to codegen.yaml (#526)

    * 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
    pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    5c80684 View commit details
    Browse the repository at this point in the history
  26. * Improvements to codegen helper (Part I)

     - 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.
    pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    5b72bc3 View commit details
    Browse the repository at this point in the history
  27. Addressing TODOs for Instance struct (#533) Part II

      - 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
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    4b3e2fc View commit details
    Browse the repository at this point in the history
  28. Unit test for scalar state kernel generation in LLVM (#547)

    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.
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    c08eb22 View commit details
    Browse the repository at this point in the history
  29. Indexed name codegen improvements (#550)

    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
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    ec91271 View commit details
    Browse the repository at this point in the history
  30. Add InstanceStruct test data generation helper and unit test (#546)

    * 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]>
    iomaganaris and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    559d152 View commit details
    Browse the repository at this point in the history
  31. Add the remainder loop for vectorization of DERIVATIVE block (#534)

    * Implement remainder loop along with main vector loop
    * Add unit test for the same
    
    fixes #532
    alkino authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    b5d152f View commit details
    Browse the repository at this point in the history
  32. Always initialize return variable in function block (#554)

    * return value in PROCEDURE block was not initialised
    * do the initialisation as part of ASTR transformation
    * remove initialisation specific code from LLVM visitor
    
    fixes #530
    alkino authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    c7e5e28 View commit details
    Browse the repository at this point in the history
  33. Running a kernel with NMODL-LLVM JIT (#549)

    * Added support for arguments in the JIT llvm runner
    * Adjusted tests and added a simple kernel test
    * Removed printfs from the kernel
    * Fixed kernel number of arguments check
    * Initial integration of dataHelper for kernel tests
    * Implemented a test to check the scalar kernel execution
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    20dc785 View commit details
    Browse the repository at this point in the history
  34. Loop epilogue fix for LLVM visitor helper (#567)

    * Added renaming for loop local variables in CodegenForStatement
    * Fixed trip count in main loop and removed epilogue loop for scalar case
    * Refactored loop remainder tests and added a scalar case
    * Change `reminder` to `epilogue` in the test
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    f684466 View commit details
    Browse the repository at this point in the history
  35. Gather support and vectorisation fixes for LLVM code generation (#568)

    * Add gather support
    * Fixed vectorisation patterns and added simple JIT tests
    * Added IR regex test for gather
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    cc92fc2 View commit details
    Browse the repository at this point in the history
  36. Verification and file utilities for LLVM IR codegen (#582)

    Added several minor improvement to the current pipeline
    infrastructure. Particularly, the following was addressed:
    
    - The generated IR module is now verified after running the
    visitor
    - The kernel is checked if it can be vectorised or not
    - The generated IR can be dumped to `.ll` file with
    `-o <filename>`
    - Printing LLVM IR is moved to debug mode
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    3803ae1 View commit details
    Browse the repository at this point in the history
  37. Add gather execution test (#591)

    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    60e68c9 View commit details
    Browse the repository at this point in the history
  38. Fixed loop allocations (#590)

    * avoid local variables inside loop to not have allocas
    * this was causing stack overview for large instance count
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    8f1fbae View commit details
    Browse the repository at this point in the history
  39. Benchmarking LLVM code generation (#583)

    Introduced the benchmarking for LLVM code generation pipeline.
    For that, new options have been added:
    
    ```
    benchmark
      LLVM benchmark option
      Options:
        --run                                                               Run LLVM benchmark (false)
        --instance-size INT                                       Instance struct size (10000)
        --repeat INT                                                    Number of experiments for benchmarking (100)
        --backend TEXT:{avx2, default, sse2}         Target's backend (default)
    ```
    
    The JIT runner has also been modified to extract the target
    information correctly, and disable available CPU features for
    benchmarking a specific backend.
    
    Example:
    ```
    $ nmodl hh.mod llvm --ir --vector-width 1 benchmark --run --instance-size 100 --repeat 2 --backend default
    
    Created LLVM IR module from NMODL AST in 0.006765817
    
    Benchmarking kernel 'nrn_state_hh'
    Experiment 0: compute time = 0.013977749
    Experiment 1: compute time = 0.004847989
    Average compute time = 0.0058550929
    ```
    
    Co-authored-by: Pramod Kumbhar <[email protected]>
    georgemitenkov and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    53cd1cc View commit details
    Browse the repository at this point in the history
  40. Minor benchmarking improvement (#593)

    - allocate instance data only once
    - store memory size with instance data
    - print memory size while running benchmarking kernel
    pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    db80372 View commit details
    Browse the repository at this point in the history
  41. Bug fix in codegen helper: delete LOCAL statement (#595)

    - LOCAL statement was not deleted correctly
    - Instead of getting first element from statement vector,
       use local statement pointer to erase it from the node.
      
    Related to #594
    pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    2a699a8 View commit details
    Browse the repository at this point in the history
  42. LLVM 13 compatibility and fixing void* type (#603)

    * Made compatible with LLVM 13 and replaced void* with i8*
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    630033c View commit details
    Browse the repository at this point in the history
  43. Allow LOCAL variable inside StatementBlock for LLVM IR generation (#599)

      - if LOCAL variable was declared inside DERIVATIVE block then
        we were getting error:
          "Stored value type does not match pointer operand type!"
      - the error was happening because scalar variable from epilogue
        loop was conflicting with the vector type variable in main loop
      - to avoid conflict between main and epilogue loop, rename all
        local variables in epilogue.
      - bug fix for recursive handling of LocalList statement
    
    fixes #594
    pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    fe3d856 View commit details
    Browse the repository at this point in the history
  44. Update CI with LLVM v13 (trunk) (#605)

     * In order to use VecLibReplace pass, we need LLVM 13 / trunk
     * Change ubuntu image on azure from 16.04 to 18.04
     * Install llvm-13 nightly snapshot
     * Enable LLVM build on Ubuntu
     * For Mac OS use pre-built binary package from https://github.com/pramodk/llvm-nightly
     * We will see if we get OS X bottle from BlueBrain/homebrew-tap/pull/7
    pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    dddffed View commit details
    Browse the repository at this point in the history
  45. Integrating vector maths library into LLVM codegen (#604)

    Added support for replacing LLVM IR maths intrinsics with vector
    maths functions from Accelerate, libmvec, MASSV, and SVML. To
    trigger the replacement, a new `--veclib` option should be used.
    This is only supported on LLVM 13+.
    
    Example:
    ```
    $ bin/nmodl hh.mod llvm --ir --vector-width 4 --veclib SVML
    ```
    
    fixes #589
    
    Co-authored-by: Pramod Kumbhar <[email protected]>
    georgemitenkov and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    068ba5d View commit details
    Browse the repository at this point in the history
  46. Using shared libraries in LLVM JIT (#609)

    * Integrated veclibs in benchmark and added shared libs support for JIT
    * Tested on BBP Ubuntu Linux box
    * Make sure to set LD_LIBRARY_PATH for Intel library dir
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    98a88d5 View commit details
    Browse the repository at this point in the history
  47. Avoid local std::ofstream object causing segfault (#614)

    - std::ofstream().rdbuf() was used but as it was a local object,
       it becomes invalid at the end of function scope
     - make std::ofstream as member variable
    pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    16504c7 View commit details
    Browse the repository at this point in the history
  48. Refactoring of runners' infrastructure and dumping object files (#620)

    The following is added:
    
    1. Dumping object files in JIT.
    
    A functionality to dump (enabled by default) the generated from LLVM IR file binary to `.o` has been added to benchmarking. Now, in addition to logs, a `v<vector_width>_<mod_filename>.o` is generated. The reasons it is an object file and not an assembly (hence not included in logs) are the following:
    
    - LLVM does not have library functions that take the object and turn back into assembly, but rather `object -> file -> assembly` path. It also has a `llvm-objdump` tool, but it is intended as a command-line utility and does not have a well-defined API.
    
    - Writing custom functions to produce a readable assembly is not a priority. Also, mimicking `objdump` functionality would be difficult.
    
    - Both `objdump` and `llvm-objdump` can be used to isnpect the `.o` file manually.
    
    2. Refactoring of `Runner` class.
    
    In addition to the support of dumping the binary, `Runner`and `JITDriver` classes were refactored to have a nicer OOP-style.
    
    fixes #611
    
    Co-authored-by: Pramod S Kumbhar <[email protected]>
    georgemitenkov and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    dd2889d View commit details
    Browse the repository at this point in the history
  49. Optimisation levels for benchmarking (#623)

    This PR adds two flags to the benchmarking pipeline:
    
    * `--opt-level-ir`: This flag is used to run `-On` passes on the
       generated LLVM IR module.
    * `--opt-level-codegen`: This flag is used for setting optimisation level
        for machine code generation inside the JIT target machine.
    * As an example:
    
    ```bash
    $ ./nmodl file.mod \
         llvm --ir --vector-width 1 \
         benchmark --run --instance-size 10000000 --repeat 20 --opt-level-ir 2 --opt-level-codegen 2
    ```
    
    fixes #616
    georgemitenkov authored and pramodk committed May 8, 2021
    Configuration menu
    Copy the full SHA
    93732e0 View commit details
    Browse the repository at this point in the history

Commits on May 10, 2021

  1. Adding function debug information (#628)

    Added debug support to LLVM code generation pipeline. Currently,
    only basic support was added:
    
    1. Debug information about functions (name)
    2. Debug information about module
    
    **What has been changed and added**
    
    1. A new class `DebugBuilder` was created. It is used as a wrapper
    around LLVM's `DIBuilder` and holds important information such as
    `LLVMContext`, debug file and compile unit. It also wraps `DIBuilder`'s
    functionality into a more suitable API.
    
    2. A temporary `Location` struct has been added. It encapsulates the
    location of the source AST construct and reflects `ModToken` on LLVM
    code generation level. It is only used if the location of the source NMODL
    function is known.
    
    3. LLVM visitor know takes an extra `add_debug_information` flag and
    handles debug information creation. Fore readability, `IRBuilder` was
    renamed to `ir_builder`.
    
    4. JIT runner is now able to listen for GDB, perf (build LLVM with
    `-DLLVM_USE_PERF=ON`) and VTune (build LLVM with
    `-DLLVM_USE_INTEL_JITEVENTS=ON`) events.
    
    5. Necessary cmake changes were added to optionally support JIT event
    listeners (`-DNMODL_HAVE_JIT_EVENT_LISTENERS`).
    
    **How to generate debug information**
    
    Debug information is attached to every function, procedure or artificially
    created kernel (and corresponding wrappers). Debug information is enable
    by default, so to turn it off use ` --disable-debug-info` flag. For example,
    the given NMODL
    ```nmodl
    1   FUNCTION func(x) {
    2     func = x
    3   }
    4
    5   PROCEDURE proc() {}
    ```
    is transformed (running `./bin/nmodl <filename>.mod llvm --ir`) into
    ```llvm
    define double @func(double %x1) !dbg !4 {
      ; ...
    }
    
    define i32 @proc() !dbg !6 {
      ; ...
    }
    
    !llvm.dbg.cu = !{!0}
    !llvm.module.flags = !{!3}
    
    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "NMODL-LLVM", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
    !1 = !DIFile(filename: "foo", directory: ".")
    !2 = !{}
    !3 = !{i32 2, !"Debug Version", i32 3}
    !4 = distinct !DISubprogram(name: "func", linkageName: "func", scope: null, file: !1, line: 1, type: !5, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
    !5 = !DISubroutineType(types: !2)
    !6 = distinct !DISubprogram(name: "proc", linkageName: "proc", scope: null, file: !1, line: 5, type: !5, scopeLine: 5, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
    ```
    
    fixes #592 #612 
    
    Co-authored-by: Pramod Kumbhar <[email protected]>
    georgemitenkov and pramodk committed May 10, 2021
    Configuration menu
    Copy the full SHA
    150943c View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    1802b74 View commit details
    Browse the repository at this point in the history
  3. Fixes to run CI with NVHPC/PGI compiler

      * in the new deployment, pgi module is changed to nvhpc
      * fix gitlab CI script accordingly
    pramodk committed May 10, 2021
    Configuration menu
    Copy the full SHA
    3359ea3 View commit details
    Browse the repository at this point in the history

Commits on May 11, 2021

  1. Fixed addition of SOLVE block to kernel's FOR loop (#636)

    * Fix `append_statements_from_block` function in LLVM helper visitor.
    * Before, if nonspecific current was not specified, the whole `BREAKPOINT`
       block would be added to the kernel body.
    * This led to cases when `SOLVE` block was together with the actual
        solution to `DERIVATIVE`
    georgemitenkov authored May 11, 2021
    Configuration menu
    Copy the full SHA
    524b292 View commit details
    Browse the repository at this point in the history

Commits on May 13, 2021

  1. IR builder redesign for LLVM IR code generation pipeline (#634)

    Improves the code structure for the LLVM code generation pipeline
    
    The following changes were added:
    
    1. New IR builder class.
    
    Before, LLVM visitor just simply used `llvm::IRBuilder<>` class to
    generate instructions. Recently, this (as well as adding the functionality
    to the visitor on the go) had led to code duplication and it became hard
    to introduce new features nicely.
    
    Hence, a special `IRBuilder` class is now used. This class is a wrapper
    around `llvm::IRBuilder<>` that keeps track of certain IR generation
    specific fields (that are unrelated to the visitor), defines an API that the
    visitor can use to generate LLVM IR.
    
    Also, this IR builder has been designed to be nearly fully-independent from
    NMODL AST nodes. this allows it to be more generic and to be more
    extensible.
    
    2. Visitor clean-up
    
     LLVM visitor has been refactored to take the new IR builder class into
    account. Also, the functions were reordered, refactored and renamed to
    better reflect the intended use and provide encapsulation.
    
    3. Scatter preparation
    
    The functionality of the generating code for `CodegenInstanceVar` node
    has been extended with `read_from_or_write_to_instance(...)` function.
    Now, an optional `value_to_store` is passed to indicate whether the code
    needs to be generated for reading the instance variable or writing to it.
    
    
    fixes #538
    georgemitenkov authored May 13, 2021
    Configuration menu
    Copy the full SHA
    68639a7 View commit details
    Browse the repository at this point in the history
  2. Fixed initialisation of CodegenAtomicStatement (#642)

      * Fixed CodegenAtomicStatement initialisation
      * Removed unused variable and changed comment
    georgemitenkov authored May 13, 2021
    Configuration menu
    Copy the full SHA
    454a18f View commit details
    Browse the repository at this point in the history
  3. Fix instance struct data generation for testing/benchmarking (#641)

    * Instance data structure initialization had following bug
       - instance struct has int member variables which act as
         offsets to other vectors (e.g. node_index, na_ion_index)
       - these variables were initialized from 1 to N where N was
         incremented always without considering the upper bound on
         for offset.
    * With this fix
       - index / integer variables are always initialized from
         0 to N-1.
       - Variables are initialised 1e-5 prevision so that we have
         reaosanbly bigger values
       - Update tests to check offset from 0 to N-1
    pramodk authored May 13, 2021
    Configuration menu
    Copy the full SHA
    53727df View commit details
    Browse the repository at this point in the history
  4. Basic scatter support (#643)

    Added basic support to transform indirect writes into
    `llvm.masked.scatter` intrinsic. Currently, the scatter functionality is
    limited to non-atomic writes and assignment (e.g. `+=` operator is
    not yet supported). Hence, a warning is logged to the console
    indicating all limitations.
    
    Corresponding IR and execution tests were also added.
    
    fixes #539
    georgemitenkov authored May 13, 2021
    Configuration menu
    Copy the full SHA
    23100e9 View commit details
    Browse the repository at this point in the history

Commits on May 16, 2021

  1. Benchmarking code re-organisation and minor improvements (#647)

    * Move benchmark + JIT related code from src/codegen/llvm
      to test/benchmark
    * Common execution of CodegenLLVMVisitor for llvm --ir and
      benchmark option. With this, ast transformed for LLVM
      code generation is dumped to file.
    * Previous object file is removed (if exist) so that output
      file name is same / deterministic
    * Benchmark output is always printed to stdout via common
      logger object
    * Remove unnecessary LLVMBuildInfo struct
    pramodk authored May 16, 2021
    Configuration menu
    Copy the full SHA
    bd05479 View commit details
    Browse the repository at this point in the history

Commits on May 17, 2021

  1. Added attributes and metadata to LLVM IR compute kernels (#648)

    Previously, there was no metadata and attributes associated with the
    instance struct pointer, compute kernels or loops. This commit fixes
    this.
    
    - New instance struct attributes
    
    Since all pointers contained in the instance struct do not alias, we add
    a `noalias` (LLVM's `__restrict` alternative) attribute to it. In addition,
    we add `nocapture` (No capturing occurs in the function) and
    `readonly` (Struct pointer is not written to) attributes.
    
    This means that some load instructions can be moved out from the loop
    body. Example:
    ```llvm
    ; BEFORE
    for.body.lr.ph:                                   ; preds = %0
      %5 = getelementptr inbounds %avx__instance_var__type, %avx__instance_var__type* %mech1, i64 0, i32 1
      br label %for.body
    
    for.body:                                         ; preds = %for.body.lr.ph, %for.body
      %15 = load double*, double** %5, align 8
      ; ...
    
    
    ; AFTER
    for.body.lr.ph:                                   ; preds = %0
      %5 = getelementptr inbounds %avx__instance_var__type, %avx__instance_var__type* %mech1, i64 0, i32 1
      %6 = load double*, double** %5, align 8
      br label %for.body
    ```
    
    - New function attributes
    
    Now, compute kernels are marked with `nofree` and `nounwind`
    attributes.
    
    - Loop metadata
    
    Also, loop metadata is added to scalar kernels, specifying that no
    vectorization is needed. The reason for this is because we want to
    benchmark truly scalar kernels, and disable LLVM's vectorization if
    necessary.
    
    Note that for vector loop epilogue there is no metadata that disables
    vectorization.
    
    fixes #607
    georgemitenkov authored May 17, 2021
    Configuration menu
    Copy the full SHA
    5d126aa View commit details
    Browse the repository at this point in the history

Commits on May 18, 2021

  1. Added loaded value to the stack (#655)

    - fixes the case, where loaded value was taken from the stack, but was never actually put there
    georgemitenkov authored May 18, 2021
    Configuration menu
    Copy the full SHA
    ee8bbdb View commit details
    Browse the repository at this point in the history

Commits on May 20, 2021

  1. Basic predication support for LLVM backend (#652)

    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
    georgemitenkov authored May 20, 2021
    Configuration menu
    Copy the full SHA
    5ee761b View commit details
    Browse the repository at this point in the history
  2. Improvements for LLVM code generation and benchmarking (#661)

    * 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
    georgemitenkov authored May 20, 2021
    Configuration menu
    Copy the full SHA
    8bee7de View commit details
    Browse the repository at this point in the history
  3. Fixed allocas insertion point for LLVM backend (#663)

    * 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
    georgemitenkov authored May 20, 2021
    Configuration menu
    Copy the full SHA
    1461d8f View commit details
    Browse the repository at this point in the history

Commits on May 21, 2021

  1. Fast math flags for LLVM backend (#662)

    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
    }
    ```
    georgemitenkov authored May 21, 2021
    Configuration menu
    Copy the full SHA
    908779e View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    2ca85e5 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    7fdbb4f View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    4c585f3 View commit details
    Browse the repository at this point in the history

Commits on May 25, 2021

  1. Use VarName on the RHS of assignment expression (#669)

    - NMODL parser uses VarName on the LHS of assignment expression
    - Inline visitor was using Name on the LHS of assignment expression
    
    Related to #667
    pramodk authored May 25, 2021
    Configuration menu
    Copy the full SHA
    f0a3afc View commit details
    Browse the repository at this point in the history

Commits on May 30, 2021

  1. [LLVM] SLEEF and libsystem_m vector libraries support (#674)

    * 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]>
    georgemitenkov and pramodk authored May 30, 2021
    Configuration menu
    Copy the full SHA
    2609f87 View commit details
    Browse the repository at this point in the history

Commits on May 31, 2021

  1. hacky support for timing JIT vs statically compiled kernels

    Castiglioni Giacomo committed May 31, 2021
    Configuration menu
    Copy the full SHA
    da1ed52 View commit details
    Browse the repository at this point in the history
  2. renamed folder

    Castiglioni Giacomo committed May 31, 2021
    Configuration menu
    Copy the full SHA
    6ca88c2 View commit details
    Browse the repository at this point in the history
  3. slightly better stub for ext kernel, init data at every iteration

    Castiglioni Giacomo committed May 31, 2021
    Configuration menu
    Copy the full SHA
    bf8c9d5 View commit details
    Browse the repository at this point in the history
  4. added script and simple kernels

    Castiglioni Giacomo committed May 31, 2021
    Configuration menu
    Copy the full SHA
    57d785c View commit details
    Browse the repository at this point in the history
  5. updated benchmark stats for hacky ext kernel

    Castiglioni Giacomo committed May 31, 2021
    Configuration menu
    Copy the full SHA
    a714903 View commit details
    Browse the repository at this point in the history
  6. fixed typo, cleaned up stub

    Castiglioni Giacomo committed May 31, 2021
    Configuration menu
    Copy the full SHA
    2853d23 View commit details
    Browse the repository at this point in the history
  7. added hh kernel

    Castiglioni Giacomo committed May 31, 2021
    Configuration menu
    Copy the full SHA
    6b5e022 View commit details
    Browse the repository at this point in the history
  8. add fast math for JIT in script

    Castiglioni Giacomo committed May 31, 2021
    Configuration menu
    Copy the full SHA
    7b7b33b View commit details
    Browse the repository at this point in the history
  9. added precise division flag to icpc

    Castiglioni Giacomo committed May 31, 2021
    Configuration menu
    Copy the full SHA
    a5da1d1 View commit details
    Browse the repository at this point in the history
  10. added pragmas to cpp kernel, add ext kernel sse2 and avx2

    Castiglioni Giacomo committed May 31, 2021
    Configuration menu
    Copy the full SHA
    b1b851c View commit details
    Browse the repository at this point in the history
  11. pragm/flag to vec hh with clang, addded gcc

    Castiglioni Giacomo committed May 31, 2021
    Configuration menu
    Copy the full SHA
    7620651 View commit details
    Browse the repository at this point in the history
  12. flag typo

    Castiglioni Giacomo committed May 31, 2021
    Configuration menu
    Copy the full SHA
    80e85bf View commit details
    Browse the repository at this point in the history
  13. rebased and updated llvm path

    Castiglioni Giacomo committed May 31, 2021
    Configuration menu
    Copy the full SHA
    102210e View commit details
    Browse the repository at this point in the history
  14. fixed llvm path

    Castiglioni Giacomo committed May 31, 2021
    Configuration menu
    Copy the full SHA
    e3a25be View commit details
    Browse the repository at this point in the history