BioDynaMo  v1.05.119-a4ff3934
resource_manager.h
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------
2 //
3 // Copyright (C) 2021 CERN & University of Surrey for the benefit of the
4 // BioDynaMo collaboration. All Rights Reserved.
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 //
9 // See the LICENSE file distributed with this work for details.
10 // See the NOTICE file distributed with this work for additional information
11 // regarding copyright ownership.
12 //
13 // -----------------------------------------------------------------------------
14 
15 #ifndef CORE_RESOURCE_MANAGER_H_
16 #define CORE_RESOURCE_MANAGER_H_
17 
18 #include <omp.h>
19 #include <sched.h>
20 #include <algorithm>
21 #include <cmath>
22 #include <limits>
23 #include <memory>
24 #include <ostream>
25 #include <set>
26 #include <string>
27 #include <unordered_map>
28 #include <utility>
29 #include <vector>
30 
31 #include "core/agent/agent.h"
33 #include "core/agent/agent_uid.h"
38 #include "core/functor.h"
40 #include "core/simulation.h"
41 #include "core/type_index.h"
42 #include "core/util/numa.h"
43 #include "core/util/root.h"
44 #include "core/util/thread_info.h"
45 #include "core/util/type.h"
46 
47 namespace bdm {
48 
54  public:
55  explicit ResourceManager(TRootIOCtor* r) {}
56 
58 
59  virtual ~ResourceManager();
60 
62  if (agents_.size() != other.agents_.size()) {
63  Log::Fatal(
64  "Restored ResourceManager has different number of NUMA nodes.");
65  }
66  for (auto& el : continuum_models_) {
67  delete el.second;
68  }
69  for (auto& numa_agents : agents_) {
70  for (auto* agent : numa_agents) {
71  delete agent;
72  }
73  }
74  agents_ = std::move(other.agents_);
75  agents_lb_.resize(agents_.size());
76  continuum_models_ = std::move(other.continuum_models_);
77 
79  // restore type_index_
80  if (type_index_) {
81  for (auto& numa_agents : agents_) {
82  for (auto* agent : numa_agents) {
83  type_index_->Add(agent);
84  }
85  }
86  }
87  return *this;
88  }
89 
91  // rebuild uid_ah_map_
92  uid_ah_map_.clear();
93  auto* agent_uid_generator = Simulation::GetActive()->GetAgentUidGenerator();
94  uid_ah_map_.resize(agent_uid_generator->GetHighestIndex() + 1);
95  for (AgentHandle::NumaNode_t n = 0; n < agents_.size(); ++n) {
96  for (AgentHandle::ElementIdx_t i = 0; i < agents_[n].size(); ++i) {
97  auto* agent = agents_[n][i];
98  this->uid_ah_map_.Insert(agent->GetUid(), AgentHandle(n, i));
99  }
100  }
101  }
102 
103  Agent* GetAgent(const AgentUid& uid) {
104  if (!uid_ah_map_.Contains(uid)) {
105  return nullptr;
106  }
107  auto& ah = uid_ah_map_[uid];
108  return agents_[ah.GetNumaNode()][ah.GetElementIdx()];
109  }
110 
112  return agents_[ah.GetNumaNode()][ah.GetElementIdx()];
113  }
114 
115  AgentHandle GetAgentHandle(const AgentUid& uid) const {
116  return uid_ah_map_[uid];
117  }
118 
119  void SwapAgents(std::vector<std::vector<Agent*>>* agents);
120 
121  [[deprecated("Use AddContinuum() instead")]] void AddDiffusionGrid(
122  DiffusionGrid* dgrid) {
123  AddContinuum(dgrid);
124  }
125 
127  auto tmp = cm->GetContinuumId();
128  if (tmp < 0) {
129  Log::Fatal("ResourceManager::AddContinuum",
130  "You tried to add a continuum model that was not properly "
131  "initialized. "
132  "Continuum id is negative but should be positive. "
133  "Continuum id is " +
134  std::to_string(tmp));
135  }
136  auto continuum_id = static_cast<uint64_t>(tmp);
137  auto search = continuum_models_.find(continuum_id);
138  if (search != continuum_models_.end()) {
139  Log::Fatal("ResourceManager::AddContinuum",
140  "You tried to add a continuum model with an already existing "
141  "substance id. Please choose a different substance id.");
142  } else {
143  continuum_models_[continuum_id] = cm;
144  }
146  }
147 
148  [[deprecated("Use RemoveContinuum() instead")]] void RemoveDiffusionGrid(
149  size_t substance_id) {
150  RemoveContinuum(substance_id);
151  }
152 
153  void RemoveContinuum(size_t continuum_id) {
154  auto search = continuum_models_.find(continuum_id);
155  if (search != continuum_models_.end()) {
156  delete search->second;
157  continuum_models_.erase(search);
158  } else {
159  Log::Error("ResourceManager::RemoveContinuum",
160  "You tried to remove a continuum model that does not exist.");
161  }
162  }
163 
167  DiffusionGrid* GetDiffusionGrid(size_t substance_id) const {
168  auto* cm = GetContinuum(substance_id);
169  auto* dgrid = dynamic_cast<DiffusionGrid*>(cm);
170  if (!dgrid) {
171  Log::Error("ResourceManager::GetDiffusionGrid",
172  "You tried to get a diffusion grid but the substance id "
173  "does not correspond to a diffusion grid.");
174  }
175  return dgrid;
176  }
177 
179  Continuum* GetContinuum(size_t continuum_id) const {
180  auto search = continuum_models_.find(continuum_id);
181  if (search != continuum_models_.end()) {
182  return search->second;
183  } else {
184  Log::Error("ResourceManager::GetContinuum",
185  "You tried to request continuum model '", continuum_id,
186  "', but it does not exist! Make sure that it's the correct id "
187  "and that the continuum model is registered.");
188  return nullptr;
189  }
190  }
191 
197  DiffusionGrid* GetDiffusionGrid(const std::string& substance_name) const {
198  auto* cm = GetContinuum(substance_name);
199  auto* dgrid = dynamic_cast<DiffusionGrid*>(cm);
200  if (!dgrid) {
201  Log::Error("ResourceManager::GetDiffusionGrid",
202  "You tried to get a diffusion grid but the substance name "
203  "does not correspond to a diffusion grid.");
204  }
205  return dgrid;
206  }
207 
211  Continuum* GetContinuum(const std::string& continuum_name) const {
212  for (auto& el : continuum_models_) {
213  auto& cm = el.second;
214  if (cm->GetContinuumName() == continuum_name) {
215  return cm;
216  }
217  }
218  Log::Error("ResourceManager::GetContinuum",
219  "You tried to request a continuum model named '", continuum_name,
220  "', but it does not exist! Make sure that it's spelled "
221  "correctly and that the continuum model is registered.");
222  return nullptr;
223  }
224 
231  template <typename TFunctor>
232  void ForEachDiffusionGrid(TFunctor&& f) const {
233  for (auto& el : continuum_models_) {
234  auto* dgrid = dynamic_cast<DiffusionGrid*>(el.second);
235  if (dgrid) {
236  f(dgrid);
237  }
238  }
239  }
240 
247  template <typename TFunctor>
248  void ForEachContinuum(TFunctor&& f) const {
249  for (auto& el : continuum_models_) {
250  f(el.second);
251  }
252  }
253 
256  size_t GetNumAgents(int numa_node = -1) const {
257  if (numa_node == -1) {
258  size_t num_agents = 0;
259  for (auto& numa_agents : agents_) {
260  num_agents += numa_agents.size();
261  }
262  return num_agents;
263  } else {
264  return agents_[numa_node].size();
265  }
266  }
267 
268  size_t GetAgentVectorCapacity(int numa_node);
269 
280  virtual void ForEachAgent(const std::function<void(Agent*)>& function,
281  Functor<bool, Agent*>* filter = nullptr) {
282  for (auto& numa_agents : agents_) {
283  for (auto* agent : numa_agents) {
284  if (!filter || (filter && (*filter)(agent))) {
285  function(agent);
286  }
287  }
288  }
289  }
290 
291  virtual void ForEachAgent(
292  const std::function<void(Agent*, AgentHandle)>& function,
293  Functor<bool, Agent*>* filter = nullptr) {
294  for (AgentHandle::NumaNode_t n = 0; n < agents_.size(); ++n) {
295  auto& numa_agents = agents_[n];
296  for (AgentHandle::ElementIdx_t i = 0; i < numa_agents.size(); ++i) {
297  auto* a = numa_agents[i];
298  if (!filter || (filter && (*filter)(a))) {
299  function(a, AgentHandle(n, i));
300  }
301  }
302  }
303  }
304 
312  virtual void ForEachAgentParallel(Functor<void, Agent*>& function,
313  Functor<bool, Agent*>* filter = nullptr);
314 
319  virtual void ForEachAgentParallel(Operation& op,
320  Functor<bool, Agent*>* filter = nullptr);
321 
322  virtual void ForEachAgentParallel(
324  Functor<bool, Agent*>* filter = nullptr);
325 
333  virtual void ForEachAgentParallel(
334  uint64_t chunk, Functor<void, Agent*, AgentHandle>& function,
335  Functor<bool, Agent*>* filter = nullptr);
336 
339  void Reserve(size_t capacity) {
340  for (auto& numa_agents : agents_) {
341  numa_agents.reserve(capacity);
342  }
343  if (type_index_) {
344  type_index_->Reserve(capacity);
345  }
346  }
347 
351  uint64_t GrowAgentContainer(size_t additional, size_t numa_node) {
352  if (additional == 0) {
353  return agents_[numa_node].size();
354  }
355  auto current = agents_[numa_node].size();
356  if (current + additional < agents_[numa_node].size()) {
357  agents_[numa_node].reserve((current + additional) * 1.5);
358  }
359  agents_[numa_node].resize(current + additional);
360  return current;
361  }
362 
365  bool ContainsAgent(const AgentUid& uid) const {
366  return uid_ah_map_.Contains(uid);
367  }
368 
373  void ClearAgents() {
374  uid_ah_map_.clear();
375  for (auto& numa_agents : agents_) {
376  for (auto* agent : numa_agents) {
377  delete agent;
378  }
379  numa_agents.clear();
380  }
381  if (type_index_) {
382  type_index_->Clear();
383  }
384  }
385 
388  virtual void LoadBalance();
389 
390  void DebugNuma() const;
391 
398  void AddAgent(Agent* agent, // NOLINT
399  typename AgentHandle::NumaNode_t numa_node = 0) {
400  auto uid = agent->GetUid();
401  if (uid.GetIndex() >= uid_ah_map_.size()) {
402  uid_ah_map_.resize(uid.GetIndex() + 1);
403  }
404  agents_[numa_node].push_back(agent);
405  uid_ah_map_.Insert(
406  uid, AgentHandle(numa_node, static_cast<AgentHandle::ElementIdx_t>(
407  agents_[numa_node].size() - 1u)));
408  if (type_index_) {
409  type_index_->Add(agent);
410  }
412  }
413 
415  auto* agent_uid_generator = Simulation::GetActive()->GetAgentUidGenerator();
416  auto highest_idx = agent_uid_generator->GetHighestIndex();
417  auto new_size = highest_idx * 1.5 + 1;
418  if (highest_idx >= uid_ah_map_.size()) {
419  uid_ah_map_.resize(new_size);
420  }
421  if (type_index_) {
422  type_index_->Reserve(new_size);
423  }
424  }
425 
426  virtual void EndOfIteration() {}
427 
432  virtual void AddAgents(typename AgentHandle::NumaNode_t numa_node,
433  uint64_t offset,
434  const std::vector<Agent*>& new_agents) {
435  uint64_t i = 0;
436  for (auto* agent : new_agents) {
437  auto uid = agent->GetUid();
438  uid_ah_map_.Insert(
439  uid, AgentHandle(numa_node,
440  static_cast<AgentHandle::ElementIdx_t>(offset + i)));
441  agents_[numa_node][offset + i] = agent;
442  i++;
443  }
444  if (type_index_) {
445 #pragma omp critical
446  for (auto* agent : new_agents) {
447  type_index_->Add(agent);
448  }
449  }
450 #pragma omp single
451  if (new_agents.size() != 0) {
453  }
454  }
455 
460  void RemoveAgent(const AgentUid& uid) {
461  // remove from map
462  if (uid_ah_map_.Contains(uid)) {
463  auto ah = uid_ah_map_[uid];
464  uid_ah_map_.Remove(uid);
465  // remove from vector
466  auto& numa_agents = agents_[ah.GetNumaNode()];
467  Agent* agent = nullptr;
468  if (ah.GetElementIdx() == numa_agents.size() - 1) {
469  agent = numa_agents.back();
470  numa_agents.pop_back();
471  } else {
472  // swap
473  agent = numa_agents[ah.GetElementIdx()];
474  auto* reordered = numa_agents.back();
475  numa_agents[ah.GetElementIdx()] = reordered;
476  numa_agents.pop_back();
477  uid_ah_map_.Insert(reordered->GetUid(), ah);
478  }
479  if (type_index_) {
480  type_index_->Remove(agent);
481  }
482  delete agent;
484  }
486  }
487 
488  // \param uids: one vector for each thread containing one vector for each numa
489  // node
490  void RemoveAgents(const std::vector<std::vector<AgentUid>*>& uids);
491 
492  const TypeIndex* GetTypeIndex() const { return type_index_; }
493 
494  protected:
498  void MarkEnvironmentOutOfSync() const;
499 
502  std::vector<std::vector<Agent*>> agents_;
505  std::vector<std::vector<Agent*>> agents_lb_;
506 
508 
509  TypeIndex* type_index_ = nullptr;
510 
512  std::vector<std::vector<uint64_t>> to_right;
513  std::vector<std::vector<uint64_t>> not_to_left;
514  };
515 
518 
519  friend class SimulationBackup;
520  friend std::ostream& operator<<(std::ostream& os, const ResourceManager& rm);
521 
522  private:
524  std::unordered_map<uint64_t, Continuum*> continuum_models_;
525 
527 };
528 
529 inline std::ostream& operator<<(std::ostream& os, const ResourceManager& rm) {
530  os << "\033[1mAgents per numa node\033[0m" << std::endl;
531  uint64_t cnt = 0;
532  for (auto& numa_agents : rm.agents_) {
533  os << "numa node " << cnt++ << " -> size: " << numa_agents.size()
534  << std::endl;
535  }
536  return os;
537 }
538 
539 } // namespace bdm
540 
541 #endif // CORE_RESOURCE_MANAGER_H_
bdm::ResourceManager::ContainsAgent
bool ContainsAgent(const AgentUid &uid) const
Definition: resource_manager.h:365
bdm::AgentHandle::NumaNode_t
uint16_t NumaNode_t
Definition: agent_handle.h:31
bdm::ResourceManager::EndOfIteration
virtual void EndOfIteration()
Definition: resource_manager.h:426
bdm::ResourceManager::agents_lb_
std::vector< std::vector< Agent * > > agents_lb_
Container used during load balancing.
Definition: resource_manager.h:505
agent_uid_map.h
bdm::ResourceManager::GetNumAgents
size_t GetNumAgents(int numa_node=-1) const
Definition: resource_manager.h:256
bdm::TypeIndex::Add
void Add(Agent *agent)
Definition: type_index.cc:22
agent_uid.h
bdm::ThreadInfo::GetInstance
static ThreadInfo * GetInstance()
Definition: thread_info.cc:21
bdm::ResourceManager::ResizeAgentUidMap
void ResizeAgentUidMap()
Definition: resource_manager.h:414
bdm::ResourceManager::LoadBalance
virtual void LoadBalance()
Definition: resource_manager.cc:239
agent_handle.h
bdm::ResourceManager::GetAgent
Agent * GetAgent(const AgentUid &uid)
Definition: resource_manager.h:103
bdm::ResourceManager::type_index_
TypeIndex * type_index_
Definition: resource_manager.h:509
bdm
Definition: agent.cc:39
bdm::ResourceManager::GetTypeIndex
const TypeIndex * GetTypeIndex() const
Definition: resource_manager.h:492
operation.h
bdm::ResourceManager::RemoveAgents
void RemoveAgents(const std::vector< std::vector< AgentUid > * > &uids)
Definition: resource_manager.cc:339
thread_info.h
bdm::ResourceManager::GetAgentHandle
AgentHandle GetAgentHandle(const AgentUid &uid) const
Definition: resource_manager.h:115
bdm::ResourceManager::GetDiffusionGrid
DiffusionGrid * GetDiffusionGrid(size_t substance_id) const
Definition: resource_manager.h:167
bdm::ResourceManager::Reserve
void Reserve(size_t capacity)
Definition: resource_manager.h:339
bdm::ResourceManager::ResourceManager
ResourceManager(TRootIOCtor *r)
Definition: resource_manager.h:55
bdm::ResourceManager::ParallelRemovalAuxData::to_right
std::vector< std::vector< uint64_t > > to_right
Definition: resource_manager.h:512
bdm::ResourceManager::SwapAgents
void SwapAgents(std::vector< std::vector< Agent * >> *agents)
Definition: resource_manager.cc:584
bdm::Agent::GetUid
const AgentUid & GetUid() const
Definition: agent.cc:123
bdm::ResourceManager::AddDiffusionGrid
void AddDiffusionGrid(DiffusionGrid *dgrid)
Definition: resource_manager.h:121
bdm::ResourceManager::operator=
ResourceManager & operator=(ResourceManager &&other) noexcept
Definition: resource_manager.h:61
type.h
bdm::DiffusionGrid
Definition: diffusion_grid.h:90
bdm::AgentUidGenerator::ReuseAgentUid
void ReuseAgentUid(const AgentUid &uid)
Definition: agent_uid_generator.h:60
bdm::TypeIndex
Definition: type_index.h:27
bdm::AgentHandle::ElementIdx_t
uint32_t ElementIdx_t
Definition: agent_handle.h:32
bdm::Continuum
Continuum class to interface with BioDynaMo for hybrid simulations.
Definition: continuum_interface.h:52
bdm::ResourceManager::GetDiffusionGrid
DiffusionGrid * GetDiffusionGrid(const std::string &substance_name) const
Definition: resource_manager.h:197
bdm::ResourceManager::parallel_remove_
ParallelRemovalAuxData parallel_remove_
auxiliary data required for parallel agent removal
Definition: resource_manager.h:517
bdm::ResourceManager::ParallelRemovalAuxData
Definition: resource_manager.h:511
bdm::ResourceManager::ForEachAgent
virtual void ForEachAgent(const std::function< void(Agent *)> &function, Functor< bool, Agent * > *filter=nullptr)
Definition: resource_manager.h:280
bdm::Agent
Contains code required by all agents.
Definition: agent.h:79
bdm::ResourceManager::RebuildAgentUidMap
void RebuildAgentUidMap()
Definition: resource_manager.h:90
bdm::AgentUidGenerator::GetHighestIndex
AgentUid::Index_t GetHighestIndex() const
Thread-safe.
Definition: agent_uid_generator.h:56
bdm::ResourceManager::RemoveContinuum
void RemoveContinuum(size_t continuum_id)
Definition: resource_manager.h:153
bdm::Functor
Definition: functor.h:24
bdm::ResourceManager::AddAgents
virtual void AddAgents(typename AgentHandle::NumaNode_t numa_node, uint64_t offset, const std::vector< Agent * > &new_agents)
Definition: resource_manager.h:432
bdm::ResourceManager::uid_ah_map_
AgentUidMap< AgentHandle > uid_ah_map_
Maps an AgentUid to its storage location in agents_ .
Definition: resource_manager.h:501
bdm::ResourceManager::RemoveAgent
void RemoveAgent(const AgentUid &uid)
Definition: resource_manager.h:460
bdm::ResourceManager::AddAgent
void AddAgent(Agent *agent, typename AgentHandle::NumaNode_t numa_node=0)
Add an agent to the ResourceManager (not thread-safe). This function might invalidate agent reference...
Definition: resource_manager.h:398
bdm::ResourceManager::GetContinuum
Continuum * GetContinuum(size_t continuum_id) const
Return the continuum model which holds the substance of specified id.
Definition: resource_manager.h:179
continuum_interface.h
diffusion_grid.h
bdm::ResourceManager::ParallelRemovalAuxData::not_to_left
std::vector< std::vector< uint64_t > > not_to_left
Definition: resource_manager.h:513
bdm::ResourceManager::BDM_CLASS_DEF_NV
BDM_CLASS_DEF_NV(ResourceManager, 2)
bdm::ResourceManager::GetAgent
Agent * GetAgent(AgentHandle ah)
Definition: resource_manager.h:111
bdm::ResourceManager
Definition: resource_manager.h:53
bdm::Continuum::GetContinuumId
int GetContinuumId() const
Returns the ID of the continuum.
Definition: continuum_interface.h:87
numa.h
bdm::ResourceManager::~ResourceManager
virtual ~ResourceManager()
Definition: resource_manager.cc:45
root.h
bdm::ResourceManager::ClearAgents
void ClearAgents()
Definition: resource_manager.h:373
bdm::ResourceManager::agents_
std::vector< std::vector< Agent * > > agents_
Pointer container for all agents.
Definition: resource_manager.h:503
bdm::ResourceManager::GetContinuum
Continuum * GetContinuum(const std::string &continuum_name) const
Definition: resource_manager.h:211
agent_uid_generator.h
bdm::TypeIndex::Remove
void Remove(Agent *agent)
Definition: type_index.cc:40
bdm::TypeIndex::Clear
void Clear()
Definition: type_index.cc:55
agent.h
bdm::AgentUidMap
Definition: agent_uid_map.h:31
bdm::ResourceManager::RemoveDiffusionGrid
void RemoveDiffusionGrid(size_t substance_id)
Definition: resource_manager.h:148
bdm::Log::Fatal
static void Fatal(const std::string &location, const Args &... parts)
Prints fatal error message.
Definition: log.h:115
bdm::Log::Error
static void Error(const std::string &location, const Args &... parts)
Prints error message.
Definition: log.h:79
bdm::Simulation::GetAgentUidGenerator
AgentUidGenerator * GetAgentUidGenerator()
Definition: simulation.cc:256
bdm::ResourceManager::GrowAgentContainer
uint64_t GrowAgentContainer(size_t additional, size_t numa_node)
Definition: resource_manager.h:351
bdm::ResourceManager::continuum_models_
std::unordered_map< uint64_t, Continuum * > continuum_models_
Maps a continuum ID to the pointer to the continuum models.
Definition: resource_manager.h:524
bdm::ResourceManager::ForEachAgent
virtual void ForEachAgent(const std::function< void(Agent *, AgentHandle)> &function, Functor< bool, Agent * > *filter=nullptr)
Definition: resource_manager.h:291
type_index.h
bdm::ResourceManager::ForEachDiffusionGrid
void ForEachDiffusionGrid(TFunctor &&f) const
Definition: resource_manager.h:232
bdm::ResourceManager::MarkEnvironmentOutOfSync
void MarkEnvironmentOutOfSync() const
Definition: resource_manager.cc:588
bdm::AgentUid
Definition: agent_uid.h:25
bdm::ResourceManager::ResourceManager
ResourceManager()
Definition: resource_manager.cc:30
bdm::operator<<
std::ostream & operator<<(std::ostream &o, const MathArray< T, N > &arr)
Definition: math_array.h:412
bdm::SimulationBackup
Definition: simulation_backup.h:33
bdm::ResourceManager::ForEachContinuum
void ForEachContinuum(TFunctor &&f) const
Definition: resource_manager.h:248
bdm::ResourceManager::ForEachAgentParallel
virtual void ForEachAgentParallel(Functor< void, Agent * > &function, Functor< bool, Agent * > *filter=nullptr)
Definition: resource_manager.cc:92
bdm::ResourceManager::thread_info_
ThreadInfo * thread_info_
Definition: resource_manager.h:507
simulation.h
bdm::ResourceManager::DebugNuma
void DebugNuma() const
bdm::AgentHandle::GetNumaNode
NumaNode_t GetNumaNode() const
Definition: agent_handle.h:44
bdm::Simulation::GetActive
static Simulation * GetActive()
This function returns the currently active Simulation simulation.
Definition: simulation.cc:68
bdm::Operation
Definition: operation.h:99
bdm::ResourceManager::AddContinuum
void AddContinuum(Continuum *cm)
Definition: resource_manager.h:126
bdm::AgentHandle::GetElementIdx
ElementIdx_t GetElementIdx() const
Definition: agent_handle.h:45
functor.h
bdm::ResourceManager::operator<<
friend std::ostream & operator<<(std::ostream &os, const ResourceManager &rm)
Definition: resource_manager.h:529
bdm::ThreadInfo
This class stores information about each thread. (e.g. to which NUMA node it belongs to....
Definition: thread_info.h:31
bdm::TypeIndex::Reserve
void Reserve(uint64_t capacity)
Definition: type_index.cc:63
bdm::ResourceManager::GetAgentVectorCapacity
size_t GetAgentVectorCapacity(int numa_node)
Definition: resource_manager.cc:579
bdm::AgentHandle
Definition: agent_handle.h:29