QUDA  v0.7.0
A library for QCD on GPUs
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
lattice_field.cpp
Go to the documentation of this file.
1 #include <typeinfo>
2 #include <quda_internal.h>
3 #include <lattice_field.h>
4 #include <color_spinor_field.h>
5 #include <gauge_field.h>
6 #include <clover_field.h>
7 #include <face_quda.h>
8 
9 namespace quda {
10 
11  void* LatticeField::bufferPinned[] = {NULL};
12  bool LatticeField::bufferPinnedInit[] = {false};
13  size_t LatticeField::bufferPinnedBytes[] = {0};
15 
16 
17  void* LatticeField::bufferDevice = NULL;
18  bool LatticeField::bufferDeviceInit = false;
20 
22  : volume(1), pad(param.pad), total_bytes(0), nDim(param.nDim), precision(param.precision),
23  siteSubset(param.siteSubset)
24  {
25  for (int i=0; i<nDim; i++) {
26  x[i] = param.x[i];
27  volume *= param.x[i];
28  surface[i] = 1;
29  for (int j=0; j<nDim; j++) {
30  if (i==j) continue;
31  surface[i] *= param.x[j];
32  }
33  }
34 
35  if (siteSubset == QUDA_INVALID_SITE_SUBSET) errorQuda("siteSubset is not set");
37  stride = volumeCB + pad;
38 
39  // for parity fields the factor of half is present for all surfaces dimensions except x, so add it manually
40  for (int i=0; i<nDim; i++)
41  surfaceCB[i] = (siteSubset == QUDA_FULL_SITE_SUBSET || i==0) ? surface[i] / 2 : surface[i];
42 
43  // for 5-dimensional fields, we only communicate in the space-time dimensions
44  nDimComms = nDim == 5 ? 4 : nDim;
45 
47  }
48 
50  }
51 
52 
54  char vol_tmp[TuneKey::volume_n];
55  int check;
56  check = snprintf(vol_string, TuneKey::volume_n, "%d", x[0]);
57  if (check < 0 || check >= TuneKey::volume_n) errorQuda("Error writing volume string");
58  for (int d=1; d<nDim; d++) {
59  strcpy(vol_tmp, vol_string);
60  check = snprintf(vol_string, TuneKey::volume_n, "%sx%d", vol_tmp, x[d]);
61  if (check < 0 || check >= TuneKey::volume_n) errorQuda("Error writing volume string");
62  }
63  }
64 
66  if (a.volume != volume) errorQuda("Volume does not match %d %d", volume, a.volume);
67  if (a.volumeCB != volumeCB) errorQuda("VolumeCB does not match %d %d", volumeCB, a.volumeCB);
68  if (a.nDim != nDim) errorQuda("nDim does not match %d %d", nDim, a.nDim);
69  for (int i=0; i<nDim; i++) {
70  if (a.x[i] != x[i]) errorQuda("x[%d] does not match %d %d", i, x[i], a.x[i]);
71  if (a.surface[i] != surface[i]) errorQuda("surface[%d] does not match %d %d", i, surface[i], a.surface[i]);
72  if (a.surfaceCB[i] != surfaceCB[i]) errorQuda("surfaceCB[%d] does not match %d %d", i, surfaceCB[i], a.surfaceCB[i]);
73  }
74  }
75 
78  if (typeid(*this)==typeid(cudaCloverField) ||
79  typeid(*this)==typeid(cudaGaugeField)) {
80  location = QUDA_CUDA_FIELD_LOCATION;
81  } else if (typeid(*this)==typeid(cpuCloverField) ||
82  typeid(*this)==typeid(cpuGaugeField)) {
83  location = QUDA_CPU_FIELD_LOCATION;
84  } else {
85  errorQuda("Unknown field %s, so cannot determine location", typeid(*this).name());
86  }
87  return location;
88  }
89 
90  int LatticeField::Nvec() const {
91  if (typeid(*this) == typeid(const cudaColorSpinorField)) {
92  const ColorSpinorField &csField = static_cast<const ColorSpinorField&>(*this);
93  if (csField.FieldOrder() == 2 || csField.FieldOrder() == 4)
94  return static_cast<int>(csField.FieldOrder());
95  } else if (typeid(*this) == typeid(const cudaGaugeField)) {
96  const GaugeField &gField = static_cast<const GaugeField&>(*this);
97  if (gField.Order() == 2 || gField.Order() == 4)
98  return static_cast<int>(gField.Order());
99  } else if (typeid(*this) == typeid(const cudaCloverField)) {
100  const CloverField &cField = static_cast<const CloverField&>(*this);
101  if (cField.Order() == 2 || cField.Order() == 4)
102  return static_cast<int>(cField.Order());
103  }
104 
105  errorQuda("Unsupported field type");
106  return -1;
107  }
108 
109  void LatticeField::resizeBufferPinned(size_t bytes, const int idx) const {
110  if ((bytes > bufferPinnedBytes[idx] || bufferPinnedInit[idx] == 0) && bytes > 0) {
111  if (bufferPinnedInit[idx]) host_free(bufferPinned[idx]);
112  bufferPinned[idx] = pinned_malloc(bytes);
113  bufferPinnedBytes[idx] = bytes;
114  bufferPinnedInit[idx] = true;
116  if (bufferPinnedResizeCount == 0) bufferPinnedResizeCount = 1; // keep 0 as initialization state
117  }
118  }
119 
120  void LatticeField::resizeBufferDevice(size_t bytes) const {
121  if ((bytes > bufferDeviceBytes || bufferDeviceInit == 0) && bytes > 0) {
123  bufferDevice = device_malloc(bytes);
124  bufferDeviceBytes = bytes;
125  bufferDeviceInit = true;
126  }
127  }
128 
130  if (bufferPinnedInit[index]) {
131  host_free(bufferPinned[index]);
132  bufferPinned[index] = NULL;
134  bufferPinnedInit[index] = false;
135  }
136  if (bufferDeviceInit) {
138  bufferDevice = NULL;
139  bufferDeviceBytes = 0;
140  bufferDeviceInit = false;
141  }
142  }
143 
144  // This doesn't really live here, but is fine for the moment
145  std::ostream& operator<<(std::ostream& output, const LatticeFieldParam& param)
146  {
147  output << "nDim = " << param.nDim << std::endl;
148  for (int i=0; i<param.nDim; i++) {
149  output << "x[" << i << "] = " << param.x[i] << std::endl;
150  }
151  output << "pad = " << param.pad << std::endl;
152  output << "precision = " << param.precision << std::endl;
153 
154  return output; // for multiple << operators.
155  }
156 
157 } // namespace quda
#define pinned_malloc(size)
Definition: malloc_quda.h:26
static bool bufferPinnedInit[2]
Definition: lattice_field.h:93
#define errorQuda(...)
Definition: util_quda.h:73
QudaFieldLocation Location() const
#define host_free(ptr)
Definition: malloc_quda.h:29
QudaSiteSubset siteSubset
Definition: lattice_field.h:87
QudaGaugeFieldOrder Order() const
Definition: gauge_field.h:169
int x[QUDA_MAX_DIM]
Definition: lattice_field.h:78
QudaPrecision precision
Definition: lattice_field.h:41
virtual void setTuningString()
std::ostream & operator<<(std::ostream &output, const CloverFieldParam &param)
QudaGaugeParam param
Definition: pack_test.cpp:17
int x[QUDA_MAX_DIM]
Definition: lattice_field.h:38
const QudaFieldLocation location
Definition: pack_test.cpp:46
static void * bufferDevice
__device__ __host__ int index(int i, int j)
Definition: quda_matrix.h:342
QudaCloverFieldOrder Order() const
Definition: clover_field.h:66
void checkField(const LatticeField &)
static void freeBuffer(int index=0)
char vol_string[TuneKey::volume_n]
QudaFieldOrder FieldOrder() const
int surface[QUDA_MAX_DIM]
Definition: lattice_field.h:80
enum QudaFieldLocation_s QudaFieldLocation
static size_t bufferPinnedResizeCount
void resizeBufferDevice(size_t bytes) const
#define device_malloc(size)
Definition: malloc_quda.h:24
int surfaceCB[QUDA_MAX_DIM]
Definition: lattice_field.h:81
static size_t bufferPinnedBytes[2]
Definition: lattice_field.h:96
static size_t bufferDeviceBytes
static const int volume_n
Definition: tune_key.h:10
LatticeField(const LatticeFieldParam &param)
void resizeBufferPinned(size_t bytes, const int index=0) const
static void * bufferPinned[2]
Definition: lattice_field.h:90
static bool bufferDeviceInit
#define device_free(ptr)
Definition: malloc_quda.h:28