QUDA  v0.5.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 
7 #define QMP_CHECK(qmp_call) do { \
8  QMP_status_t status = qmp_call; \
9  if (status != QMP_SUCCESS) \
10  errorQuda("(QMP) %s", QMP_error_string(status)); \
11 } while (0)
12 
13 
14 struct MsgHandle_s {
15  QMP_msgmem_t mem;
16  QMP_msghandle_t handle;
17 };
18 
19 
20 static int gpuid = -1;
21 
22 
23 void comm_init(int ndim, const int *dims, QudaCommsMap rank_from_coords, void *map_data)
24 {
25  if ( QMP_is_initialized() != QMP_TRUE ) {
26  errorQuda("QMP has not been initialized");
27  }
28 
29  int grid_size = 1;
30  for (int i = 0; i < ndim; i++) {
31  grid_size *= dims[i];
32  }
33  if (grid_size != QMP_get_number_of_nodes()) {
34  errorQuda("Communication grid size declared via initCommsGridQuda() does not match"
35  " total number of QMP nodes (%d != %d)", grid_size, QMP_get_number_of_nodes());
36  }
37 
38  Topology *topo = comm_create_topology(ndim, dims, rank_from_coords, map_data);
40 
41  // determine which GPU this process will use (FIXME: adopt the scheme in comm_mpi.cpp)
42 
43  int device_count;
44  cudaGetDeviceCount(&device_count);
45  if (device_count == 0) {
46  errorQuda("No CUDA devices found");
47  }
48 
49  gpuid = (comm_rank() % device_count);
50 }
51 
52 
53 int comm_rank(void)
54 {
55  return QMP_get_node_number();
56 }
57 
58 
59 int comm_size(void)
60 {
61  return QMP_get_number_of_nodes();
62 }
63 
64 
65 int comm_gpuid(void)
66 {
67  return gpuid;
68 }
69 
70 
74 MsgHandle *comm_declare_send_displaced(void *buffer, const int displacement[], size_t nbytes)
75 {
77 
78  int rank = comm_rank_displaced(topo, displacement);
79  MsgHandle *mh = (MsgHandle *)safe_malloc(sizeof(MsgHandle));
80 
81  mh->mem = QMP_declare_msgmem(buffer, nbytes);
82  if (mh->mem == NULL) errorQuda("Unable to allocate QMP message memory");
83 
84  mh->handle = QMP_declare_send_to(mh->mem, rank, 0);
85  if (mh->handle == NULL) errorQuda("Unable to allocate QMP message handle");
86 
87  return mh;
88 }
89 
90 
94 MsgHandle *comm_declare_receive_displaced(void *buffer, const int displacement[], size_t nbytes)
95 {
97 
98  int rank = comm_rank_displaced(topo, displacement);
99  MsgHandle *mh = (MsgHandle *)safe_malloc(sizeof(MsgHandle));
100 
101  mh->mem = QMP_declare_msgmem(buffer, nbytes);
102  if (mh->mem == NULL) errorQuda("Unable to allocate QMP message memory");
103 
104  mh->handle = QMP_declare_receive_from(mh->mem, rank, 0);
105  if (mh->handle == NULL) errorQuda("Unable to allocate QMP message handle");
106 
107  return mh;
108 }
109 
110 
112 {
113  QMP_free_msghandle(mh->handle);
114  QMP_free_msgmem(mh->mem);
115  host_free(mh);
116 }
117 
118 
120 {
121  QMP_CHECK( QMP_start(mh->handle) );
122 }
123 
124 
126 {
127  QMP_CHECK( QMP_wait(mh->handle) );
128 }
129 
130 
132 {
133  return (QMP_is_complete(mh->handle) == QMP_TRUE);
134 }
135 
136 
137 void comm_allreduce(double* data)
138 {
139  QMP_CHECK( QMP_sum_double(data) );
140 }
141 
142 
143 void comm_allreduce_max(double* data)
144 {
145  QMP_CHECK( QMP_max_double(data) );
146 }
147 
148 
149 void comm_allreduce_array(double* data, size_t size)
150 {
151  QMP_CHECK( QMP_sum_double_array(data, size) );
152 }
153 
154 
155 void comm_allreduce_int(int* data)
156 {
157  QMP_CHECK( QMP_sum_int(data) );
158 }
159 
160 
161 void comm_broadcast(void *data, size_t nbytes)
162 {
163  QMP_CHECK( QMP_broadcast(data, nbytes) );
164 }
165 
166 
167 void comm_barrier(void)
168 {
169  QMP_CHECK( QMP_barrier() );
170 }
171 
172 
173 void comm_abort(int status)
174 {
175  QMP_abort(status);
176 }