NAMD
CudaGlobalMasterClient.C
Go to the documentation of this file.
4 #include "CudaUtils.h"
5 #include "InfoStream.h"
6 #include "Lattice.h"
7 #include "Molecule.h"
8 #include "ReductionMgr.h"
9 #include "Node.h"
10 #include "NamdState.h"
11 #include "DataExchanger.h"
12 #include "SimParameters.h"
13 #include "ScriptTcl.h"
14 
15 namespace CudaGlobalMaster {
16 
17 #if (defined(NAMD_CUDA) || defined(NAMD_HIP)) && defined(NODEGROUP_FORCE_REGISTER)
18 
19 void CudaGlobalMasterClient::initialize(
20  const std::vector<std::string>& arguments, int deviceID, cudaStream_t stream) {
21  m_name = arguments[1];
22  m_device_id = deviceID;
23  const std::string msg = "Creating CudaGlobalMasterClient " + m_name +
24  " on PE " + std::to_string(CkMyPe()) + "\n";
25  iout << iINFO << msg << endi;
26  int savedDevice;
27  cudaCheck(cudaGetDevice(&savedDevice));
28  cudaCheck(cudaSetDevice(m_device_id));
29  allocate_device(&m_d_ExtVirial, 1);
30  allocate_device(&m_d_ExtForce, 1);
31  allocate_host(&m_h_virial, 1);
32  allocate_host(&m_h_ExtForce, 1);
33  cudaCheck(cudaSetDevice(savedDevice));
34 }
35 
36 CudaGlobalMasterClient::~CudaGlobalMasterClient() {
37  if (m_d_ExtVirial)
38  deallocate_device(&m_d_ExtVirial);
39  if (m_d_ExtForce)
40  deallocate_device(&m_d_ExtForce);
41  if (m_h_virial)
42  deallocate_host(&m_h_virial);
43  if (m_h_ExtForce)
44  deallocate_host(&m_h_ExtForce);
45 }
46 
47 void CudaGlobalMasterClient::unsubscribe() {
48  auto master = m_master.lock();
49  if (master) {
50  master->removeClient(shared_from_this());
51  master.reset();
52  } else {
53  iout << iWARN << "Trying to remove client \"" << name()
54  << "\" which is not in the master";
55  }
56 }
57 
58 void CudaGlobalMasterClient::subscribe(
59  std::shared_ptr<CudaGlobalMasterServer> master) {
60  auto tmp = m_master.lock();
61  if (tmp) {
62  return;
63  } else {
64  m_master = master;
65  master->addClient(shared_from_this());
66  }
67 }
68 
69 int CudaGlobalMasterClient::updateFromTCLCommand(const std::vector<std::string>& arguments) {
70  iout << iINFO << "Updating client " << name() << " with arguments:\n" << endi;
71  for (size_t i = 0; i < arguments.size(); ++i) {
72  iout << iINFO << " arguments[" << i << "]: " << arguments[i] << '\n' << endi;
73  }
74 #ifdef NAMD_TCL
75  return TCL_OK;
76 #else
77  return 0;
78 #endif // NAMD_TCL
79 }
80 
81 std::string CudaGlobalMasterClient::getTCLUpdateResult() {
82  return "undefined";
83 }
84 
85 bool CudaGlobalMasterClient::tclAvailable() const {
86 #ifdef NAMD_TCL
87  return true;
88 #else
89  return false;
90 #endif // NAMD_TCL
91 }
92 
93 void CudaGlobalMasterClient::finishReductions(bool doEnergy, bool doVirial,
94  SubmitReduction *reduction) {
95  if (doEnergy && hasEnergy()) {
96  reduction->item(REDUCTION_MISC_ENERGY) += getEnergy();
97  }
98  if (useDefaultExtForceAndVirial()) {
99  if (getRequestedAtoms().size() == getRequestedForcedAtoms().size()) {
100  if (doVirial) {
101  int savedDevice;
102  cudaCheck(cudaGetDevice(&savedDevice));
103  cudaCheck(cudaSetDevice(m_device_id));
104  cudaCheck(cudaMemsetAsync(m_d_ExtVirial, 0, sizeof(cudaTensor), getStream()));
105  cudaCheck(cudaMemsetAsync(m_d_ExtForce, 0, sizeof(Vector), getStream()));
106  clientVirialAndExtForce(this->getPositions(), this->getAppliedForces(),
107  this->getRequestedAtoms().size(), m_d_ExtVirial,
108  m_d_ExtForce, getStream());
109  copy_DtoH(m_d_ExtVirial, m_h_virial, 1, getStream());
110  copy_DtoH(m_d_ExtForce, m_h_ExtForce, 1, getStream());
111  cudaCheck(cudaStreamSynchronize(getStream()));
112  ADD_TENSOR_OBJECT(reduction, REDUCTION_VIRIAL_NORMAL, (*m_h_virial));
113  ADD_VECTOR_OBJECT(reduction, REDUCTION_EXT_FORCE_NORMAL, (*m_h_ExtForce));
114  cudaCheck(cudaSetDevice(savedDevice));
115  }
116  } else {
117  if (doVirial) {
118  iout << iWARN << "Virial is not available for CudaGlobalMasterClient \""
119  << name() << "\" since the number of atoms requested ("
120  << std::to_string(getRequestedAtoms().size())
121  << ") does not match the number of applied forces ("
122  << std::to_string(getRequestedForcedAtoms().size()) << ")\n";
123  }
124  }
125  } else {
126  if (hasVirial()) {
127  ADD_TENSOR_OBJECT(reduction, REDUCTION_VIRIAL_NORMAL, getVirial());
128  }
129  if (hasExtForce()) {
130  ADD_VECTOR_OBJECT(reduction, REDUCTION_EXT_FORCE_NORMAL, getExtForce());
131  }
132  }
133 }
134 
135 SimParameters* CudaGlobalMasterClient::getSimParameters() const {
136  return Node::Object()->simParameters;
137 }
138 
139 Molecule* CudaGlobalMasterClient::getMolecule() const {
140 
141  return Node::Object()->molecule;
142 }
143 
144 const Controller* CudaGlobalMasterClient::getController() const {
145  return &(Node::Object()->state->getController());
146 }
147 
148 ScriptTcl* CudaGlobalMasterClient::getScript() {
149 #ifdef NAMD_TCL
150  return Node::Object()->getScript();
151 #else
152  return nullptr;
153 #endif // NAMD_TCL
154 }
155 
156 bool CudaGlobalMasterClient::replica_enabled() const {
157 #if CMK_HAS_PARTITION
158  return true;
159 #else
160  return false;
161 #endif
162 }
163 
164 int CudaGlobalMasterClient::replica_index() const {
165  return CmiMyPartition();
166 }
167 
168 int CudaGlobalMasterClient::num_replicas() const {
169  return CmiNumPartitions();
170 }
171 
172 void replica_comm_barrier() {
173  replica_barrier();
174 }
175 
176 int replica_comm_recv(char* msg_data, int buf_len, int src_rep) {
177  DataMessage *recvMsg = NULL;
178  replica_recv(&recvMsg, src_rep, CkMyPe());
179  CmiAssert(recvMsg != NULL);
180  int retval = recvMsg->size;
181  if (buf_len >= retval) {
182  memcpy(msg_data,recvMsg->data,retval);
183  } else {
184  retval = 0;
185  }
186  CmiFree(recvMsg);
187  return retval;
188 }
189 
190 int replica_comm_send(char* msg_data, int msg_len, int dest_rep) {
191  replica_send(msg_data, msg_len, dest_rep, CkMyPe());
192  return msg_len;
193 }
194 
195 #else
196 
197 CudaGlobalMasterClient::CudaGlobalMasterClient() {
198  NAMD_die("CudaGlobalMasterClient requires NAMD to be built with CUDA");
199 }
200 
201 #endif // (defined(NAMD_CUDA) || defined(NAMD_HIP)) && defined(NODEGROUP_FORCE_REGISTER)
202 }
static Node * Object()
Definition: Node.h:86
const Controller & getController() const
Definition: NamdState.h:51
std::ostream & iINFO(std::ostream &s)
Definition: InfoStream.C:81
void deallocate_host(T **pp)
Definition: CudaUtils.h:387
Definition: Vector.h:72
#define ADD_TENSOR_OBJECT(R, RL, D)
Definition: ReductionMgr.h:44
SimParameters * simParameters
Definition: Node.h:181
void deallocate_device(T **pp)
Definition: CudaUtils.h:333
void allocate_device(T **pp, const size_t len)
Definition: CudaUtils.h:311
BigReal & item(int i)
Definition: ReductionMgr.h:336
void replica_send(const char *sndbuf, int sendcount, int destPart, int destPE)
std::ostream & endi(std::ostream &s)
Definition: InfoStream.C:54
std::ostream & iWARN(std::ostream &s)
Definition: InfoStream.C:82
#define iout
Definition: InfoStream.h:51
Molecule stores the structural information for the system.
Definition: Molecule.h:174
void replica_recv(DataMessage **precvMsg, int srcPart, int srcPE)
NamdState * state
Definition: Node.h:184
void allocate_host(T **pp, const size_t len)
Definition: CudaUtils.h:296
void replica_barrier()
void NAMD_die(const char *err_msg)
Definition: common.C:147
void copy_DtoH(const T *d_array, T *h_array, const size_t array_len, cudaStream_t stream=0)
Definition: CudaUtils.h:427
char data[1]
Definition: DataExchanger.h:23
ScriptTcl * getScript()
Definition: Node.C:1656
#define ADD_VECTOR_OBJECT(R, RL, D)
Definition: ReductionMgr.h:28
#define cudaCheck(stmt)
Definition: CudaUtils.h:233
Molecule * molecule
Definition: Node.h:179