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