QUDA  v0.7.0
A library for QCD on GPUs
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
comm_qmp.cpp
Go to the documentation of this file.
1 #include <qmp.h>
2 
3 #include <quda_internal.h>
4 #include <comm_quda.h>
5 
6 #define QMP_CHECK(qmp_call) do { \
7  QMP_status_t status = qmp_call; \
8  if (status != QMP_SUCCESS) \
9  errorQuda("(QMP) %s", QMP_error_string(status)); \
10 } while (0)
11 
12 struct MsgHandle_s {
13  QMP_msgmem_t mem;
14  QMP_msghandle_t handle;
15 };
16 
17 static int gpuid = -1;
18 
19 
20 void comm_init(int ndim, const int *dims, QudaCommsMap rank_from_coords, void *map_data)
21 {
22  if ( QMP_is_initialized() != QMP_TRUE ) {
23  errorQuda("QMP has not been initialized");
24  }
25 
26  int grid_size = 1;
27  for (int i = 0; i < ndim; i++) {
28  grid_size *= dims[i];
29  }
30  if (grid_size != QMP_get_number_of_nodes()) {
31  errorQuda("Communication grid size declared via initCommsGridQuda() does not match"
32  " total number of QMP nodes (%d != %d)", grid_size, QMP_get_number_of_nodes());
33  }
34 
35  Topology *topo = comm_create_topology(ndim, dims, rank_from_coords, map_data);
37 
38  // determine which GPU this process will use (FIXME: adopt the scheme in comm_mpi.cpp)
39 
40  int device_count;
41  cudaGetDeviceCount(&device_count);
42  if (device_count == 0) {
43  errorQuda("No CUDA devices found");
44  }
45 
46  gpuid = (comm_rank() % device_count);
47 }
48 
49 
50 int comm_rank(void)
51 {
52  return QMP_get_node_number();
53 }
54 
55 
56 int comm_size(void)
57 {
58  return QMP_get_number_of_nodes();
59 }
60 
61 
62 int comm_gpuid(void)
63 {
64  return gpuid;
65 }
66 
67 
71 MsgHandle *comm_declare_send_displaced(void *buffer, const int displacement[], size_t nbytes)
72 {
74 
75  int rank = comm_rank_displaced(topo, displacement);
76  MsgHandle *mh = (MsgHandle *)safe_malloc(sizeof(MsgHandle));
77 
78  mh->mem = QMP_declare_msgmem(buffer, nbytes);
79  if (mh->mem == NULL) errorQuda("Unable to allocate QMP message memory");
80 
81  mh->handle = QMP_declare_send_to(mh->mem, rank, 0);
82  if (mh->handle == NULL) errorQuda("Unable to allocate QMP message handle");
83 
84  return mh;
85 }
86 
90 MsgHandle *comm_declare_receive_displaced(void *buffer, const int displacement[], size_t nbytes)
91 {
93 
94  int rank = comm_rank_displaced(topo, displacement);
95  MsgHandle *mh = (MsgHandle *)safe_malloc(sizeof(MsgHandle));
96 
97  mh->mem = QMP_declare_msgmem(buffer, nbytes);
98  if (mh->mem == NULL) errorQuda("Unable to allocate QMP message memory");
99 
100  mh->handle = QMP_declare_receive_from(mh->mem, rank, 0);
101  if (mh->handle == NULL) errorQuda("Unable to allocate QMP message handle");
102 
103  return mh;
104 }
105 
106 
111 MsgHandle *comm_declare_strided_send_displaced(void *buffer, const int displacement[],
112  size_t blksize, int nblocks, size_t stride)
113 {
115 
116  int rank = comm_rank_displaced(topo, displacement);
117  MsgHandle *mh = (MsgHandle *)safe_malloc(sizeof(MsgHandle));
118 
119  mh->mem = QMP_declare_strided_msgmem(buffer, blksize, nblocks, stride);
120  if (mh->mem == NULL) errorQuda("Unable to allocate QMP message memory");
121 
122  mh->handle = QMP_declare_send_to(mh->mem, rank, 0);
123  if (mh->handle == NULL) errorQuda("Unable to allocate QMP message handle");
124 
125  return mh;
126 }
127 
132 MsgHandle *comm_declare_strided_receive_displaced(void *buffer, const int displacement[],
133  size_t blksize, int nblocks, size_t stride)
134 {
136 
137  int rank = comm_rank_displaced(topo, displacement);
138  MsgHandle *mh = (MsgHandle *)safe_malloc(sizeof(MsgHandle));
139 
140  mh->mem = QMP_declare_strided_msgmem(buffer, blksize, nblocks, stride);
141  if (mh->mem == NULL) errorQuda("Unable to allocate QMP message memory");
142 
143  mh->handle = QMP_declare_receive_from(mh->mem, rank, 0);
144  if (mh->handle == NULL) errorQuda("Unable to allocate QMP message handle");
145 
146  return mh;
147 }
148 
149 
151 {
152  QMP_free_msghandle(mh->handle);
153  QMP_free_msgmem(mh->mem);
154  host_free(mh);
155 }
156 
157 
159 {
160  QMP_CHECK( QMP_start(mh->handle) );
161 }
162 
163 
165 {
166  QMP_CHECK( QMP_wait(mh->handle) );
167 }
168 
169 
171 {
172  return (QMP_is_complete(mh->handle) == QMP_TRUE);
173 }
174 
175 
176 void comm_allreduce(double* data)
177 {
178  QMP_CHECK( QMP_sum_double(data) );
179 }
180 
181 
182 void comm_allreduce_max(double* data)
183 {
184  QMP_CHECK( QMP_max_double(data) );
185 }
186 
187 
188 void comm_allreduce_array(double* data, size_t size)
189 {
190  QMP_CHECK( QMP_sum_double_array(data, size) );
191 }
192 
193 
194 void comm_allreduce_int(int* data)
195 {
196  QMP_CHECK( QMP_sum_int(data) );
197 }
198 
199 
200 void comm_broadcast(void *data, size_t nbytes)
201 {
202  QMP_CHECK( QMP_broadcast(data, nbytes) );
203 }
204 
205 
206 void comm_barrier(void)
207 {
208  QMP_CHECK( QMP_barrier() );
209 }
210 
211 
212 void comm_abort(int status)
213 {
214  QMP_abort(status);
215 }
QMP_msghandle_t handle
Definition: comm_qmp.cpp:14
int comm_query(MsgHandle *mh)
Definition: comm_qmp.cpp:170
Topology * comm_create_topology(int ndim, const int *dims, QudaCommsMap rank_from_coords, void *map_data)
Definition: comm_common.cpp:93
int comm_gpuid(void)
Definition: comm_qmp.cpp:62
#define errorQuda(...)
Definition: util_quda.h:73
#define host_free(ptr)
Definition: malloc_quda.h:29
QMP_msgmem_t mem
Definition: comm_qmp.cpp:13
Topology * comm_default_topology(void)
void comm_wait(MsgHandle *mh)
Definition: comm_qmp.cpp:164
void comm_free(MsgHandle *mh)
Definition: comm_qmp.cpp:150
void comm_start(MsgHandle *mh)
Definition: comm_qmp.cpp:158
MsgHandle * comm_declare_strided_send_displaced(void *buffer, const int displacement[], size_t blksize, int nblocks, size_t stride)
Definition: comm_qmp.cpp:111
MsgHandle * comm_declare_strided_receive_displaced(void *buffer, const int displacement[], size_t blksize, int nblocks, size_t stride)
Definition: comm_qmp.cpp:132
void comm_allreduce(double *data)
Definition: comm_qmp.cpp:176
void comm_abort(int status)
Definition: comm_qmp.cpp:212
#define QMP_CHECK(qmp_call)
Definition: comm_qmp.cpp:6
int comm_rank_displaced(const Topology *topo, const int displacement[])
void comm_init(int ndim, const int *dims, QudaCommsMap rank_from_coords, void *map_data)
Definition: comm_qmp.cpp:20
#define safe_malloc(size)
Definition: malloc_quda.h:25
void comm_allreduce_max(double *data)
Definition: comm_qmp.cpp:182
int comm_size(void)
Definition: comm_qmp.cpp:56
void comm_set_default_topology(Topology *topo)
void comm_allreduce_int(int *data)
Definition: comm_qmp.cpp:194
MsgHandle * comm_declare_receive_displaced(void *buffer, const int displacement[], size_t nbytes)
Definition: comm_qmp.cpp:90
void comm_allreduce_array(double *data, size_t size)
Definition: comm_qmp.cpp:188
void comm_broadcast(void *data, size_t nbytes)
Definition: comm_qmp.cpp:200
int(* QudaCommsMap)(const int *coords, void *fdata)
Definition: comm_quda.h:12
MsgHandle * comm_declare_send_displaced(void *buffer, const int displacement[], size_t nbytes)
Definition: comm_qmp.cpp:71
int comm_rank(void)
Definition: comm_qmp.cpp:50
void comm_barrier(void)
Definition: comm_qmp.cpp:206