-
Notifications
You must be signed in to change notification settings - Fork 109
Feature/openqxd #1414
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/openqxd #1414
Changes from 200 commits
ed966db
71c1897
efc24b8
61b8a02
a40b032
0a69472
c29aa66
d3d4022
9e1b7ad
aec93e3
1f0e573
6271fac
ef1e5af
8550ed0
c9d0f6c
301378b
240d614
6202ac4
cf3a04a
16b7df0
12f22f4
d535512
f538e53
568d1cd
dc8c99f
ecc2177
8b1830d
f738510
ad8f689
189896e
37e6023
b0076de
2525a5b
9dce279
4ff5cce
b2d7446
fdf641c
ca66195
bc95079
e1bed36
5e60bc5
402cab6
ed234bd
bfe766f
b837622
23b1e0b
b577392
26918e6
d3fdc43
fe01653
34d388d
b6157c5
fdd1b62
be90f9d
736d2cd
3f131b0
92a8b50
088678e
271f828
00136bf
076cf0e
d9c4fff
a37c286
7c89362
5c21522
30ae3bd
7985910
5f57224
fd9975e
78465cf
9f52f30
61e4985
ef78041
18518f5
29da468
8ababe5
53d9a8c
4a9ba76
1cac7c0
96bb7ab
ed254d5
febf4fb
83ce801
0c9bcf0
2a91f8b
3a0012c
d929534
14baf0f
1f7fb9a
ac3d0d0
e7eaaa9
abdcbcc
732d760
25ed056
b69b67a
748693a
f663ec2
129c578
512e3e9
4d9b28a
236f869
cdd360e
025b0e3
dd0e4a5
86134fb
3ad9b06
36251b5
a0d8622
ec3e911
86ff1d5
b8bc138
1ce6b19
9e81a4c
9778011
8f4c7dc
608dec2
1c85393
3af70d1
0842ed0
ef57751
0020993
e622ce8
7085cc5
ad6787a
df1bd16
93c3f6a
8301dbf
200295d
59578cc
bab885c
dd29926
43a1b4f
23fefb1
848e6d9
02b8481
ae170fe
d56921e
886c90f
e6ce728
ba9ace1
1b1a55c
c2c8ef6
dd92262
20e59ba
d40d6e5
6c7bb9d
005aed9
ad1ab82
c1fec52
d356fa0
a80dd55
466d702
c79cb4a
6edc863
568dd37
3150761
0752a23
ca54f7e
9d9ace7
f63a507
bddb46e
7d06520
f77a907
fe998e4
db2fc52
0c2ea4e
21fd2bc
63feebe
49f3fd3
4f91376
1f538ec
e7a96b5
91819f1
66c60dc
e177aec
d712f5b
2f26208
1fca8a3
4ea946f
444b9f8
8eb4461
8949c22
ce3a31d
06adc2d
632e92e
b09867a
c00b4c2
10a7c7d
010cce8
452f6e6
6009fef
615d025
451dac1
15ef4fa
49211c4
499144e
d7fe0a2
e540039
bce4598
6e64c69
be3ba61
c7e3f74
abbedf7
ddc9730
415e156
e23eaf2
6caa627
7e2fcc1
9b7525d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ | |
| #include <convert.h> | ||
| #include <clover_field.h> | ||
| #include <complex_quda.h> | ||
| #include <index_helper.cuh> | ||
maddyscientist marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| #include <quda_matrix.h> | ||
| #include <color_spinor.h> | ||
| #include <load_store.h> | ||
|
|
@@ -637,7 +638,11 @@ namespace quda { | |
| errorQuda("Accessor reconstruct = %d does not match field reconstruct %d", enable_reconstruct, | ||
| clover.Reconstruct()); | ||
| if (clover.max_element(is_inverse) == 0.0 && isFixed<Float>::value) | ||
| #ifdef BUILD_OPENQCD_INTERFACE | ||
| warningQuda("%p max_element(%d) appears unset", &clover, is_inverse); /* ignore if the SW-field is zero */ | ||
| #else | ||
| errorQuda("%p max_element(%d) appears unset", &clover, is_inverse); | ||
| #endif | ||
| if (clover.Diagonal() == 0.0 && clover.Reconstruct()) errorQuda("%p diagonal appears unset", &clover); | ||
| this->clover = clover_ ? clover_ : clover.data<Float *>(is_inverse); | ||
| } | ||
|
|
@@ -1015,6 +1020,97 @@ namespace quda { | |
| size_t Bytes() const { return length*sizeof(Float); } | ||
| }; | ||
|
|
||
| /** | ||
| * OpenQCD ordering for clover fields | ||
| */ | ||
| template <typename Float, int length = 72> struct OpenQCDOrder { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just curious, whether QUDA has sufficient capability to create the clover term for OpenQ*D's use case or whether you have specific requirements that we are lacking? E.g., exponential clover or anisotropy? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maddyscientist filling this in for future reference, this is relevant for QCD+QED simulations where the QCD and QED clovers need to be separately constructed from the SU(3) and U(1) fields, respectively, then combined. We (QUDA) would need to be able to explicitly handle standalone U(1) fields. The reason we can't do this directly from the unified U(3) = SU(3)xU(1) fields is because you can't (naively) disentangle the SU(3) and U(1) components. (...I guess you can divide the U(1) contribution out of the SU(3) field if you know the right relative scaling coefficient, but it would be pretty gross) |
||
| static constexpr bool enable_reconstruct = false; | ||
| typedef typename mapper<Float>::type RegType; | ||
| Float *clover; | ||
| const int volumeCB; | ||
| const QudaTwistFlavorType twist_flavor; | ||
| const Float mu2; | ||
| const Float epsilon2; | ||
| const double coeff; | ||
| const double csw; | ||
| const double kappa; | ||
| const int dim[4]; // xyzt convention | ||
| const int L[4]; // txyz convention | ||
|
|
||
| OpenQCDOrder(const CloverField &clover, bool inverse, Float *clover_ = nullptr, void * = nullptr) : | ||
| volumeCB(clover.Stride()), | ||
| twist_flavor(clover.TwistFlavor()), | ||
| mu2(clover.Mu2()), | ||
| epsilon2(clover.Epsilon2()), | ||
| coeff(clover.Coeff()), | ||
| csw(clover.Csw()), | ||
| kappa(clover.Coeff() / clover.Csw()), | ||
| dim {clover.X()[0], clover.X()[1], clover.X()[2], clover.X()[3]}, // *local* lattice dimensions, xyzt | ||
| L {clover.X()[3], clover.X()[0], clover.X()[1], clover.X()[2]} // *local* lattice dimensions, txyz | ||
| { | ||
| if (clover.Order() != QUDA_OPENQCD_CLOVER_ORDER) { | ||
| errorQuda("Invalid clover order %d for this accessor", clover.Order()); | ||
| } | ||
| this->clover = clover_ ? clover_ : clover.data<Float *>(inverse); | ||
| if (clover.Coeff() == 0.0 || clover.Csw() == 0.0) { errorQuda("Neither coeff nor csw may be zero!"); } | ||
| } | ||
|
|
||
| QudaTwistFlavorType TwistFlavor() const { return twist_flavor; } | ||
| Float Mu2() const { return mu2; } | ||
| Float Epsilon2() const { return epsilon2; } | ||
|
|
||
| /** | ||
| * @brief Gets the offset in Floats from the openQCD base pointer to | ||
| * the spinor field. | ||
| * | ||
| * @param[in] x_cb Checkerboard index coming from quda | ||
| * @param[in] parity The parity coming from quda | ||
| * | ||
| * @return The offset. | ||
| */ | ||
| __device__ __host__ inline int getCloverOffset(int x_cb, int parity) const | ||
| { | ||
| int x_quda[4], x[4]; | ||
| getCoords(x_quda, x_cb, dim, parity); // x_quda contains xyzt local Carthesian corrdinates | ||
| openqcd::rotate_coords(x_quda, x); // xyzt -> txyz, x = openQCD local Carthesian lattice coordinate | ||
| return openqcd::ipt(x, L) * length; | ||
| } | ||
|
|
||
| /** | ||
| * @brief Load a clover field at lattice point x_cb | ||
| * | ||
| * @param v The output clover matrix in QUDA order | ||
| * @param x_cb The checkerboarded lattice site | ||
| * @param parity The parity of the lattice site | ||
| */ | ||
| __device__ __host__ inline void load(RegType v[length], int x_cb, int parity) const | ||
| { | ||
| int sign[36] = {-1, -1, -1, -1, -1, -1, // diagonals (idx 0-5) | ||
| -1, +1, -1, +1, -1, -1, -1, -1, -1, -1, // column 0 (idx 6-15) | ||
| -1, +1, -1, -1, -1, -1, -1, -1, // column 1 (idx 16-23) | ||
| -1, -1, -1, -1, -1, -1, // column 2 (idx 24-29) | ||
| -1, +1, -1, +1, // column 3 (idx 30-33) | ||
| -1, +1}; // column 4 (idx 34-35) | ||
| int map[36] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, 19, 24, 25, 16, 17, | ||
| 12, 13, 20, 21, 26, 27, 14, 15, 22, 23, 28, 29, 30, 31, 32, 33, 34, 35}; | ||
| const int M = length / 2; | ||
| int offset = getCloverOffset(x_cb, parity); | ||
| auto Ap = &clover[offset]; // A_+ | ||
| auto Am = &clover[offset + M]; // A_- | ||
|
|
||
| #pragma unroll | ||
| for (int i = 0; i < M; i++) { | ||
| v[i] = sign[i] * (kappa * Am[map[i]] - (i < 6)); | ||
| v[M + i] = sign[i] * (kappa * Ap[map[i]] - (i < 6)); | ||
| } | ||
| } | ||
|
|
||
| // FIXME implement the save routine for OpenQCD ordered fields | ||
| __device__ __host__ inline void save(RegType[length], int, int) const { } | ||
|
|
||
| size_t Bytes() const { return length * sizeof(Float); } | ||
| }; | ||
|
|
||
| } // namespace clover | ||
|
|
||
| // Use traits to reduce the template explosion | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,6 +41,7 @@ namespace quda | |
| int (*coords)[QUDA_MAX_DIM]; | ||
| int my_rank; | ||
| int my_coords[QUDA_MAX_DIM]; | ||
| int cstar; // number of C* direction as per openQxD convention | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We extended the Topology struct with a cstar member to indicate how many spatial directions have C* boundaries. Maybe you want to have that as a option in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Forgive my ignorance, but are the C* boundaries only relevant for fermions? |
||
| // It might be worth adding communicators to allow for efficient reductions: | ||
| // #if defined(MPI_COMMS) | ||
| // MPI_Comm comm; | ||
|
|
@@ -126,9 +127,26 @@ namespace quda | |
| inline int comm_rank_displaced(const Topology *topo, const int displacement[]) | ||
| { | ||
| int coords[QUDA_MAX_DIM]; | ||
|
|
||
| for (int i = 0; i < QUDA_MAX_DIM; i++) { | ||
| coords[i] = (i < topo->ndim) ? mod(comm_coords(topo)[i] + displacement[i], comm_dims(topo)[i]) : 0; | ||
| int shift_integer; | ||
|
|
||
| int Nx_displacement = 0; | ||
| for (int i = QUDA_MAX_DIM - 1; i >= 0; i--) { | ||
| // cstar shift[x] shift[y] shift[z] shift[t] | ||
| // 0 0 0 0 0 | ||
| // 1 0 0 0 0 | ||
| // 2 0 1 0 0 | ||
| // 3 0 1 1 0 | ||
| if (i < topo->ndim && ((i == 1 && topo->cstar >= 2) || (i == 2 && topo->cstar >= 3))) { | ||
| // if we go over the boundary and have a shifted boundary condition, | ||
| // we shift Nx/2 ranks in x-direction: | ||
| // shift_integer in { 0, 1, 2} | ||
| // (shift_integer - 1) in {-1, 0, 1} | ||
| shift_integer = (comm_coords(topo)[i] + displacement[i] + comm_dims(topo)[i]) / comm_dims(topo)[i]; | ||
| Nx_displacement += (shift_integer - 1) * (comm_dims(topo)[0] / 2); | ||
| } | ||
| coords[i] = (i < topo->ndim) ? | ||
| mod(comm_coords(topo)[i] + displacement[i] + (i == 0 ? Nx_displacement : 0), comm_dims(topo)[i]) : | ||
| 0; | ||
| } | ||
|
|
||
| return comm_rank_from_coords(topo, coords); | ||
|
|
@@ -390,6 +408,12 @@ namespace quda | |
| return comm_dims(topo)[dim]; | ||
| } | ||
|
|
||
| bool comm_dim_cstar(int dim) | ||
| { | ||
| Topology *topo = comm_default_topology(); | ||
| return (topo->cstar >= 2 && dim == 1) || (topo->cstar >= 3 && dim == 2); | ||
| } | ||
|
|
||
| int comm_coord(int dim) | ||
| { | ||
| Topology *topo = comm_default_topology(); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.