QUDA  v0.7.0
A library for QCD on GPUs
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
cpu_gauge_field.cpp
Go to the documentation of this file.
1 #include <quda_internal.h>
2 #include <gauge_field.h>
3 #include <face_quda.h>
4 #include <assert.h>
5 #include <string.h>
6 
7 namespace quda {
8 
10  GaugeField(param), pinned(param.pinned)
11  {
13  errorQuda("CPU fields do not support half precision");
14  }
15  if (pad != 0) {
16  errorQuda("CPU fields do not support non-zero padding");
17  }
19  errorQuda("Reconstruction type %d not supported", reconstruct);
20  }
22  errorQuda("10-reconstruction only supported with MILC gauge order");
23  }
24 
25  int siteDim=0;
26  if (geometry == QUDA_SCALAR_GEOMETRY) siteDim = 1;
27  else if (geometry == QUDA_VECTOR_GEOMETRY) siteDim = nDim;
28  else if (geometry == QUDA_TENSOR_GEOMETRY) siteDim = nDim * (nDim-1) / 2;
29 
30  if (order == QUDA_QDP_GAUGE_ORDER) {
31 
32  gauge = (void**) safe_malloc(siteDim * sizeof(void*));
33 
34  for (int d=0; d<siteDim; d++) {
35  size_t nbytes = volume * reconstruct * precision;
37  gauge[d] = (pinned ? pinned_malloc(nbytes) : safe_malloc(nbytes));
39  memset(gauge[d], 0, nbytes);
40  }
41  } else if (create == QUDA_REFERENCE_FIELD_CREATE) {
42  gauge[d] = ((void**)param.gauge)[d];
43  } else {
44  errorQuda("Unsupported creation type %d", create);
45  }
46  }
47 
50 
52  size_t nbytes = siteDim * volume * reconstruct * precision;
53  gauge = (void **) (pinned ? pinned_malloc(nbytes) : safe_malloc(nbytes));
55  memset(gauge, 0, nbytes);
56  }
57  } else if (create == QUDA_REFERENCE_FIELD_CREATE) {
58  gauge = (void**) param.gauge;
59  } else {
60  errorQuda("Unsupported creation type %d", create);
61  }
62 
63  } else {
64  errorQuda("Unsupported gauge order type %d", order);
65  }
66 
67  // no need to exchange data if this is a momentum field
69  // Ghost zone is always 2-dimensional
70  for (int i=0; i<nDim; i++) {
71  size_t nbytes = nFace * surface[i] * reconstruct * precision;
72  ghost[i] = safe_malloc(nbytes); // no need to use pinned memory for this
73  }
74 
76  // exchange the boundaries if a non-trivial field
79  exchangeGhost();
80  }
81  }
82 
83  // compute the fat link max now in case it is needed later (i.e., for half precision)
84  if (param.compute_fat_link_max) fat_link_max = maxGauge(*this);
85  }
86 
87 
89  {
90  int siteDim = 0;
91  if (geometry == QUDA_SCALAR_GEOMETRY) siteDim = 1;
92  else if (geometry == QUDA_VECTOR_GEOMETRY) siteDim = nDim;
93  else if (geometry == QUDA_TENSOR_GEOMETRY) siteDim = nDim * (nDim-1) / 2;
94 
96  if (order == QUDA_QDP_GAUGE_ORDER) {
97  for (int d=0; d<siteDim; d++) {
98  if (gauge[d]) host_free(gauge[d]);
99  }
100  if (gauge) host_free(gauge);
101  } else {
102  if (gauge) host_free(gauge);
103  }
104  } else { // QUDA_REFERENCE_FIELD_CREATE
105  if (order == QUDA_QDP_GAUGE_ORDER){
106  if (gauge) host_free(gauge);
107  }
108  }
109 
111  for (int i=0; i<nDim; i++) {
112  if (ghost[i]) host_free(ghost[i]);
113  }
114  }
115  }
116 
117  // This does the exchange of the gauge field ghost zone and places it
118  // into the ghost array.
120  void *send[QUDA_MAX_DIM];
121  for (int d=0; d<nDim; d++) send[d] = safe_malloc(nFace*surface[d]*reconstruct*precision);
122 
123  // get the links into contiguous buffers
124  extractGaugeGhost(*this, send);
125 
126  // communicate between nodes
127  FaceBuffer faceBuf(x, nDim, reconstruct, nFace, precision);
129 
130  for (int d=0; d<nDim; d++) host_free(send[d]);
131  }
132 
133  void cpuGaugeField::exchangeExtendedGhost(const int *R, bool no_comms_fill) {
134 
135  void *send[QUDA_MAX_DIM];
136  void *recv[QUDA_MAX_DIM];
137  size_t bytes[QUDA_MAX_DIM];
138  // store both parities and directions in each
139  for (int d=0; d<nDim; d++) {
140  if (!commDimPartitioned(d) && !no_comms_fill) continue;
141  bytes[d] = surface[d] * R[d] * geometry * reconstruct * precision;
142  send[d] = safe_malloc(2 * bytes[d]);
143  recv[d] = safe_malloc(2 * bytes[d]);
144  }
145 
146  for (int d=0; d<nDim; d++) {
147  if (!commDimPartitioned(d) && !no_comms_fill) continue;
148  //extract into a contiguous buffer
149  extractExtendedGaugeGhost(*this, d, R, send, true);
150 
151  if (commDimPartitioned(d)) {
152  // do the exchange
157 
158  mh_recv_back = comm_declare_receive_relative(recv[d], d, -1, bytes[d]);
159  mh_recv_fwd = comm_declare_receive_relative(((char*)recv[d])+bytes[d], d, +1, bytes[d]);
160  mh_send_back = comm_declare_send_relative(send[d], d, -1, bytes[d]);
161  mh_send_fwd = comm_declare_send_relative(((char*)send[d])+bytes[d], d, +1, bytes[d]);
162 
163  comm_start(mh_recv_back);
164  comm_start(mh_recv_fwd);
165  comm_start(mh_send_fwd);
166  comm_start(mh_send_back);
167 
168  comm_wait(mh_send_fwd);
169  comm_wait(mh_send_back);
170  comm_wait(mh_recv_back);
171  comm_wait(mh_recv_fwd);
172 
173  comm_free(mh_send_fwd);
174  comm_free(mh_send_back);
175  comm_free(mh_recv_back);
176  comm_free(mh_recv_fwd);
177  } else {
178  memcpy(static_cast<char*>(recv[d])+bytes[d], send[d], bytes[d]);
179  memcpy(recv[d], static_cast<char*>(send[d])+bytes[d], bytes[d]);
180  }
181 
182  // inject back into the gauge field
183  extractExtendedGaugeGhost(*this, d, R, recv, false);
184  }
185 
186  for (int d=0; d<nDim; d++) {
187  if (!commDimPartitioned(d) && !no_comms_fill) continue;
188  host_free(send[d]);
189  host_free(recv[d]);
190  }
191 
192  }
193 
194  void cpuGaugeField::setGauge(void **gauge_)
195  {
197  errorQuda("Setting gauge pointer is only allowed when create="
198  "QUDA_REFERENCE_FIELD_CREATE type\n");
199  }
200  gauge = gauge_;
201  }
202 
203 /*template <typename Float>
204 void print_matrix(const Float &m, unsigned int x) {
205 
206  for (int s=0; s<o.Nspin(); s++) {
207  std::cout << "x = " << x << ", s = " << s << ", { ";
208  for (int c=0; c<o.Ncolor(); c++) {
209  std::cout << " ( " << o(x, s, c, 0) << " , " ;
210  if (c<o.Ncolor()-1) std::cout << o(x, s, c, 1) << " ) ," ;
211  else std::cout << o(x, s, c, 1) << " ) " ;
212  }
213  std::cout << " } " << std::endl;
214  }
215 
216 }
217 
218 // print out the vector at volume point x
219 void cpuColorSpinorField::PrintMatrix(unsigned int x) {
220 
221  switch(precision) {
222  case QUDA_DOUBLE_PRECISION:
223  print_matrix(*order_double, x);
224  break;
225  case QUDA_SINGLE_PRECISION:
226  print_matrix(*order_single, x);
227  break;
228  default:
229  errorQuda("Precision %d not implemented", precision);
230  }
231 
232 }
233 */
234 
235 } // namespace quda
void setGauge(void **_gauge)
double maxGauge(const GaugeField &u)
Definition: max_gauge.cu:29
#define pinned_malloc(size)
Definition: malloc_quda.h:26
int commDimPartitioned(int dir)
void exchangeExtendedGhost(const int *R, bool no_comms_fill=false)
MsgHandle *** mh_send_back[2]
#define errorQuda(...)
Definition: util_quda.h:73
void * ghost[QUDA_MAX_DIM]
Definition: gauge_field.h:148
#define host_free(ptr)
Definition: malloc_quda.h:29
void extractGaugeGhost(const GaugeField &u, void **ghost)
QudaReconstructType reconstruct
Definition: gauge_field.h:130
MsgHandle * comm_declare_send_relative(void *buffer, int dim, int dir, size_t nbytes)
int x[QUDA_MAX_DIM]
Definition: lattice_field.h:78
QudaFieldGeometry geometry
Definition: gauge_field.h:128
QudaGaugeParam param
Definition: pack_test.cpp:17
void comm_free(MsgHandle *mh)
Definition: comm_mpi.cpp:174
void exchangeLink(void **ghost_link, void **link_sendbuf, QudaFieldLocation location)
void extractExtendedGaugeGhost(const GaugeField &u, int dim, const int *R, void **ghost, bool extract)
void comm_start(MsgHandle *mh)
Definition: comm_mpi.cpp:180
MsgHandle *** mh_recv_back[2]
#define safe_malloc(size)
Definition: malloc_quda.h:25
MsgHandle * comm_declare_receive_relative(void *buffer, int dim, int dir, size_t nbytes)
int surface[QUDA_MAX_DIM]
Definition: lattice_field.h:80
QudaGhostExchange ghostExchange
Definition: gauge_field.h:147
void * memset(void *s, int c, size_t n)
QudaLinkType link_type
Definition: gauge_field.h:133
QudaFieldCreate create
Definition: gauge_field.h:142
#define QUDA_MAX_DIM
Maximum number of dimensions supported by QUDA. In practice, no routines make use of more than 5...
void comm_wait(MsgHandle *mh)
Definition: comm_mpi.cpp:186
QudaGaugeFieldOrder order
Definition: gauge_field.h:131
MsgHandle *** mh_send_fwd[2]
cpuGaugeField(const GaugeFieldParam &)
QudaPrecision precision
Definition: lattice_field.h:84
MsgHandle *** mh_recv_fwd[2]