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