User Guide
global_var_visitor.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2023 Blue Brain Project, EPFL.
3  * See the top-level LICENSE file for details.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #pragma once
9 
10 /**
11  * \file
12  * \brief \copybrief nmodl::visitor::GlobalToRangeVisitor
13  */
14 
15 #include <sstream>
16 #include <string>
17 #include <utility>
18 #include <vector>
19 
20 #include "visitors/ast_visitor.hpp"
21 
22 namespace nmodl {
23 namespace visitor {
24 
25 /**
26  * \addtogroup visitor_classes
27  * \{
28  */
29 
30 /**
31  * \class GlobalToRangeVisitor
32  * \brief Visitor to convert GLOBAL variables to RANGE variables
33  *
34  * Some of the existing mod files have GLOBAL variables that are updated in BREAKPOINT
35  * or DERIVATIVE blocks. These variables have a single copy and works well when they
36  * are read only. If such variables are written as well, they result into race condition.
37  * For example,
38  *
39  * \code{.mod}
40  * NEURON {
41  * SUFFIX test
42  * GLOBAL x
43  * }
44  *
45  * ASSIGNED {
46  * x
47  * }
48  *
49  * BREAKPOINT {
50  * x = 1
51  * }
52  * \endcode
53  *
54  * In above example, \a x will be simultaneously updated in case of vectorization. In NEURON,
55  * such race condition is avoided by promoting these variables to thread variable (i.e. separate
56  * copy per thread). In case of CoreNEURON, this is not sufficient because of vectorisation or
57  * GPU execution. To address this issue, this visitor converts GLOBAL variables to RANGE variables
58  * when they are assigned / updated in compute functions.
59  */
60 
62  private:
63  /// ast::Ast* node
64  const ast::Program& ast;
65 
66  public:
67  /// \name Ctor & dtor
68  /// \{
69 
70  /// Default constructor
71  GlobalToRangeVisitor() = delete;
72 
73  /// Constructor that takes as parameter the AST
74  explicit GlobalToRangeVisitor(const ast::Program& node)
75  : ast(node) {}
76 
77  /// \}
78 
79  /// Visit ast::NeuronBlock nodes to check if there is any GLOBAL
80  /// variables defined in them that are written in any part of the code.
81  /// This is checked by reading the write_count member of the variable in
82  /// the symtab::SymbolTable. If it's written it removes the variable from
83  /// the ast::Global node and adds it to the ast::Range node of the
84  /// ast::NeuronBlock
85  void visit_neuron_block(ast::NeuronBlock& node) override;
86 };
87 
88 /** \} */ // end of visitor_classes
89 
90 } // namespace visitor
91 } // namespace nmodl
nmodl
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
nmodl::visitor::GlobalToRangeVisitor::visit_neuron_block
void visit_neuron_block(ast::NeuronBlock &node) override
Visit ast::NeuronBlock nodes to check if there is any GLOBAL variables defined in them that are writt...
Definition: global_var_visitor.cpp:23
nmodl::visitor::GlobalToRangeVisitor::GlobalToRangeVisitor
GlobalToRangeVisitor(const ast::Program &node)
Constructor that takes as parameter the AST.
Definition: global_var_visitor.hpp:74
nmodl::visitor::GlobalToRangeVisitor
Visitor to convert GLOBAL variables to RANGE variables.
Definition: global_var_visitor.hpp:61
nmodl::visitor::AstVisitor
Concrete visitor for all AST classes.
Definition: ast_visitor.hpp:37
nmodl::visitor::GlobalToRangeVisitor::GlobalToRangeVisitor
GlobalToRangeVisitor()=delete
Default constructor.
nmodl::visitor::GlobalToRangeVisitor::ast
const ast::Program & ast
ast::Ast* node
Definition: global_var_visitor.hpp:64
nmodl::ast::Program
Represents top level AST node for whole NMODL input.
Definition: program.hpp:39
nmodl::ast::NeuronBlock
Represent NEURON block in the mod file.
Definition: neuron_block.hpp:53
ast_visitor.hpp
Concrete visitor for all AST classes.