1 /*
2 * vp_manager.h
3 *
4 * This file is part of NEST.
5 *
6 * Copyright (C) 2004 The NEST Initiative
7 *
8 * NEST is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * NEST is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with NEST. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23 #ifndef VP_MANAGER_H
24 #define VP_MANAGER_H
25
26 // Includes from libnestutil:
27 #include "manager_interface.h"
28
29 // Includes from nestkernel:
30 #include "nest_types.h"
31
32 // Includes from sli:
33 #include "dictdatum.h"
34
35 #ifdef _OPENMP
36 // C includes:
37 #include <omp.h>
38 #endif
39
40 namespace nest
41 {
42
43 struct AssignedRanks
44 {
45 thread begin;
46 thread end;
47 thread size;
48 thread max_size;
49 };
50
51 class VPManager : public ManagerInterface
52 {
53 public:
54 VPManager();
~VPManager()55 ~VPManager()
56 {
57 }
58
59 virtual void initialize();
60 virtual void finalize();
61
62 virtual void set_status( const DictionaryDatum& );
63 virtual void get_status( DictionaryDatum& );
64
65 /**
66 * Gets ID of local thread.
67 * Returns thread ID if OPENMP is installed
68 * and zero otherwise.
69 */
70 thread get_thread_id() const;
71
72 /**
73 * Set the number of threads by setting the internal variable
74 * n_threads_, the corresponding value in the Communicator, and
75 * the OpenMP number of threads.
76 */
77 void set_num_threads( const thread n_threads );
78
79 /**
80 * Get number of threads.
81 * This function returns the total number of threads per process.
82 */
83 thread get_num_threads() const;
84
85 /**
86 * Returns true if the given global node exists on this vp.
87 */
88 bool is_node_id_vp_local( const index node_id ) const;
89
90 /**
91 * Returns thread local index of a given global node.
92 */
93 index node_id_to_lid( const index node_id ) const;
94
95 /**
96 * Returns the node ID of a given local index.
97 */
98 index lid_to_node_id( const index lid ) const;
99
100 /**
101 * Returns virtual process index.
102 */
103 thread get_vp() const;
104
105 /**
106 * Return a thread number for a given global node id.
107 * Each node has a default thread on which it will run.
108 * The thread is defined by the relation:
109 * t = (node_id div P) mod T, where P is the number of simulation processes and
110 * T the number of threads. This may be used by Network::add_node()
111 * if the user has not specified anything.
112 */
113 thread node_id_to_vp( const index node_id ) const;
114
115 /**
116 * Convert a given VP ID to the corresponding thread ID
117 */
118 thread vp_to_thread( const thread vp ) const;
119
120 /**
121 * Convert a given thread ID to the corresponding VP ID
122 */
123 thread thread_to_vp( const thread tid ) const;
124
125 /**
126 * Return true, if the given VP is on the local machine
127 */
128 bool is_local_vp( const thread tid ) const;
129
130 /**
131 * Returns the number of virtual processes.
132 */
133 int get_num_virtual_processes() const;
134
135 /**
136 * Fails if NEST is in thread-parallel section.
137 */
138 static void assert_single_threaded();
139
140 /**
141 * Returns the number of processes that are taken care of by a single thread
142 * while processing MPI buffers in a multithreaded environment.
143 */
144 thread get_num_assigned_ranks_per_thread() const;
145
146 thread get_start_rank_per_thread( const thread tid ) const;
147 thread get_end_rank_per_thread( const thread rank_start, const thread num_assigned_ranks_per_thread ) const;
148
149 /**
150 * Returns assigned ranks per thread to fill MPI buffers. Thread tid
151 * is responsible for all ranks in [assigned_ranks.begin,
152 * assigned_ranks.end), which are in total assigned_ranks.size and
153 * at most assigned_ranks.max_size
154 */
155 AssignedRanks get_assigned_ranks( const thread tid );
156
157 private:
158 const bool force_singlethreading_;
159 index n_threads_; //!< Number of threads per process.
160 };
161 }
162
163 inline nest::thread
get_thread_id()164 nest::VPManager::get_thread_id() const
165 {
166 #ifdef _OPENMP
167 return omp_get_thread_num();
168 #else
169 return 0;
170 #endif
171 }
172
173 inline nest::thread
get_num_threads()174 nest::VPManager::get_num_threads() const
175 {
176 return n_threads_;
177 }
178
179 #endif /* VP_MANAGER_H */
180