24 static int *squaresize =
nullptr;
25 static int *nsquares =
nullptr;
27 static size_t *size1[2] = {
nullptr,
nullptr}, *size2 =
nullptr;
28 static size_t sites_on_node;
29 static int *mcoord =
nullptr;
30 static bool single_parity =
false;
35 single_parity = single_parity_;
37 if (squaresize) free(squaresize);
38 squaresize = (
int *)malloc(ndim *
sizeof(
int));
40 if (nsquares) free(nsquares);
41 nsquares = (
int *)malloc(ndim *
sizeof(
int));
43 if (mcoord) free(mcoord);
44 mcoord = (
int *)malloc(ndim *
sizeof(
int));
47 if (!QMP_logical_topology_is_declared()) {
48 if (QMP_declare_logical_topology(nsquares, ndim) != 0)
return 1;
52 for (
int i = 0; i < ndim; i++) {
53 nsquares[i] = QMP_get_logical_dimensions()[i];
54 squaresize[i] = len[i] / nsquares[i];
58 for (
int i = 0; i < ndim; ++i) { sites_on_node *= squaresize[i]; }
60 if (size1[0]) free(size1[0]);
61 size1[0] = (
size_t *)malloc(2 * (ndim + 1) *
sizeof(size_t));
62 size1[1] = size1[0] + ndim + 1;
64 if (size2) free(size2);
65 size2 = (
size_t *)malloc((ndim + 1) *
sizeof(size_t));
70 for (
int i = 1; i <= ndim; i++) {
71 size1[0][i] = size2[i - 1] * (squaresize[i - 1] / 2) + size1[0][i - 1] * (squaresize[i - 1] % 2);
72 size1[1][i] = size2[i - 1] * (squaresize[i - 1] / 2) + size1[1][i - 1] * (squaresize[i - 1] % 2);
73 size2[i] = size1[0][i] + size1[1][i];
81 for (
int i = 0; i < ndim; i++) { mcoord[i] = x[i] / squaresize[i]; }
82 return QMP_get_node_number_from(mcoord);
85 #ifdef QIO_HAS_EXTENDED_LAYOUT
86 int quda_node_number_ext(
const int x[],
void *
arg)
97 for (
int i = ndim - 1; i >= 0; --i) {
98 r = r * squaresize[i] + (x[i] % squaresize[i]);
102 if (!single_parity) {
106 r = (r + sites_on_node) / 2;
113 #ifdef QIO_HAS_EXTENDED_LAYOUT
114 QIO_Index quda_node_index_ext(
const int x[],
void *
arg)
124 if (node_idx >
static_cast<size_t>(std::numeric_limits<int>::max()) || node_idx < 0)
125 errorQuda(
"Invalid node_idx %lu", node_idx);
127 return static_cast<int>(node_idx);
134 int *m = QMP_get_logical_coordinates_from(node);
137 for (
int i = 0; i < ndim; ++i) {
138 x[i] = m[i] * squaresize[i];
142 if (!single_parity) {
145 if (index >= size1[s][ndim]) {
146 index -= size1[s][ndim];
150 for (
int i = ndim - 1; i > 0; i--) {
151 x[i] += 2 * (index / size2[i]);
153 if (index >= size1[s][i]) {
154 index -= size1[s][i];
159 x[0] += 2 * index + s;
162 for (
int i = ndim - 1; i > 0; i--) {
163 x[i] += index / size2[i];
172 #ifdef QIO_HAS_EXTENDED_LAYOUT
173 size_t node_index = quda_node_index_ext(x, NULL);
177 if (node_index != si) {
179 fprintf(stderr,
"get_coords: error in layout!\n");
180 for (
int i = 0; i < ndim; i++) {
181 fprintf(stderr,
"%lu\t%lu\t%lu\n", (
size_t)size1[0][i], (
size_t)size1[1][i], (
size_t)size2[i]);
183 fprintf(stderr,
"%i\tindex=%lu\tx=(", node, (
size_t)si);
184 for (
int i = 0; i < ndim; i++) fprintf(stderr, i < ndim - 1 ?
"%i, " :
"%i)\n", x[i]);
191 #ifdef QIO_HAS_EXTENDED_LAYOUT
192 void quda_get_coords_ext(
int x[],
int node, QIO_Index index,
void *
arg)
196 if (index >
static_cast<QIO_Index
>(std::numeric_limits<int>::max()) || index < 0)
205 #ifdef QIO_HAS_EXTENDED_LAYOUT
206 QIO_Index quda_num_sites_ext(
int node,
void *
arg)
209 return sites_on_node;
214 if (sites_on_node >
static_cast<size_t>(std::numeric_limits<int>::max()) || sites_on_node < 0)
215 errorQuda(
"Invalid sites_on_node %lu", sites_on_node);
217 return static_cast<int>(sites_on_node);
void quda_get_coords(int x[], int node, int index)
int quda_node_index(const int x[])
int quda_num_sites(int node)
void quda_get_coords_helper(int x[], int node, size_t index)
size_t quda_node_index_helper(const int x[])
int quda_setup_layout(int len[], int nd, int numnodes, int single_parity_)
int quda_node_number(const int x[])
__host__ __device__ ValueType arg(const complex< ValueType > &z)
Returns the phase angle of z.