NEURON
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
72 
73  /// Constructor that takes as parameter the AST
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
86 };
87 
88 /** \} */ // end of visitor_classes
89 
90 } // namespace visitor
91 } // namespace nmodl
Concrete visitor for all AST classes.
Represent NEURON block in the mod file.
Represents top level AST node for whole NMODL input.
Definition: program.hpp:39
Concrete visitor for all AST classes.
Definition: ast_visitor.hpp:37
Visitor to convert GLOBAL variables to RANGE variables.
const ast::Program & ast
ast::Ast* node
GlobalToRangeVisitor()=delete
Default constructor.
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...
GlobalToRangeVisitor(const ast::Program &node)
Constructor that takes as parameter the AST.
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
static Node * node(Object *)
Definition: netcvode.cpp:291