@@ -13,7 +13,7 @@ namespace quda
1313 using WilsonArg<Float, nColor, nDim, DDArg, reconstruct_>::nSpin;
1414 static constexpr int length = (nSpin / (nSpin / 2 )) * 2 * nColor * nColor * (nSpin / 2 ) * (nSpin / 2 ) / 2 ;
1515 static constexpr bool dynamic_clover = clover::dynamic_inverse();
16-
16+
1717 typedef typename mapper<Float>::type real;
1818 typedef typename clover_mapper<Float, length>::type C;
1919 const C A;
@@ -65,7 +65,7 @@ namespace quda
6565 out(x) = M*in = in + a*(C + i*b*gamma_5*tau_3 + c*tau_1)/(C^2 + b^2 - c^2)*D*x ( xpay == true )
6666 */
6767 template <KernelType mykernel_type = kernel_type, bool allthreads = false >
68- __device__ __host__ __forceinline__ void operator ()(int idx, int src_flavor, int parity, bool active = true )
68+ __device__ __host__ __forceinline__ void operator ()(int idx, int src_flavor, int parity, bool alive = true )
6969 {
7070 using namespace linalg ; // for Cholesky
7171 typedef typename mapper<typename Arg::Float>::type real;
@@ -75,28 +75,30 @@ namespace quda
7575
7676 int src_idx = src_flavor / 2 ;
7777 int flavor = src_flavor % 2 ;
78+ bool active = mykernel_type != EXTERIOR_KERNEL_ALL ; // is thread active (non-trival for fused kernel only)
7879 int thread_dim; // which dimension is thread working on (fused kernel only)
7980 auto coord = getCoords<QUDA_4D_PC , mykernel_type>(arg, idx, flavor, parity, thread_dim);
8081
8182 const int my_spinor_parity = arg.nParity == 2 ? parity : 0 ;
8283 int my_flavor_idx = coord.x_cb + flavor * arg.dc .volume_4d_cb ;
8384 Vector out;
84- active &= mykernel_type != EXTERIOR_KERNEL_ALL ; // is thread active (non-trival for fused kernel only)
85- if (arg.dd_out .isZero (coord)) {
86- if (active) arg.out [src_idx](my_flavor_idx, my_spinor_parity) = out;
87- if constexpr (!allthreads) return ;
88- else active = false ;
85+ if (!allthreads || alive) {
86+ if (arg.dd_out .isZero (coord)) {
87+ if (mykernel_type != EXTERIOR_KERNEL_ALL || active) arg.out [src_idx](my_flavor_idx, my_spinor_parity) = out;
88+ if constexpr (!allthreads) return ;
89+ else alive = false ;
90+ }
8991 }
9092
91- if (!allthreads || active ) {
93+ if (!allthreads || alive ) {
9294 // defined in dslash_wilson.cuh
9395 applyWilson<dagger, mykernel_type>(out, arg, coord, parity, idx, thread_dim, active, src_idx);
94- }
9596
96- if (mykernel_type != INTERIOR_KERNEL && active) {
97- // if we're not the interior kernel, then we must sum the partial
98- Vector x = arg.out [src_idx](my_flavor_idx, my_spinor_parity);
99- out += x;
97+ if (mykernel_type != INTERIOR_KERNEL && active) {
98+ // if we're not the interior kernel, then we must sum the partial
99+ Vector x = arg.out [src_idx](my_flavor_idx, my_spinor_parity);
100+ out += x;
101+ }
100102 }
101103
102104 constexpr int n_flavor = 2 ;
@@ -109,7 +111,6 @@ namespace quda
109111
110112 int chirality = flavor; // relabel flavor as chirality
111113 SharedMemoryCache<HalfVector> cache {*this };
112-
113114 auto swizzle = [&](HalfVector x[2 ], int chirality) {
114115 if (chirality == 0 )
115116 cache.save_y (x[1 ], target::thread_idx ().y );
@@ -124,53 +125,57 @@ namespace quda
124125
125126 swizzle (out_chi, chirality); // apply the flavor-chirality swizzle between threads
126127
127- if (isComplete<mykernel_type>(arg, coord) && active) {
128- // load in the clover matrix
129- HMat A = arg.A (coord.x_cb , parity, chirality);
128+ if (!allthreads || alive) {
129+ if (isComplete<mykernel_type>(arg, coord) && active) {
130+ // load in the clover matrix
131+ HMat A = arg.A (coord.x_cb , parity, chirality);
130132
131- HalfVector A_chi[n_flavor];
133+ HalfVector A_chi[n_flavor];
132134#pragma unroll
133- for (int flavor_ = 0 ; flavor_ < n_flavor; flavor_++) {
134- const complex <real> b (0.0 , (chirality^flavor_) == 0 ? arg.b : -arg.b );
135- A_chi[flavor_] = A * out_chi[flavor_];
136- A_chi[flavor_] += b * out_chi[flavor_];
137- A_chi[flavor_] += arg.c * out_chi[1 - flavor_];
138- }
139-
140- if constexpr (Arg::dynamic_clover) {
141- HMat A2 = A.square ();
142- A2 += arg.b2_minus_c2 ;
143- Cholesky<HMatrix, clover::cholesky_t <typename Arg::Float>, Arg::nColor * Arg::nSpin / 2 > cholesky (A2 );
135+ for (int flavor_ = 0 ; flavor_ < n_flavor; flavor_++) {
136+ const complex <real> b (0.0 , (chirality^flavor_) == 0 ? arg.b : -arg.b );
137+ A_chi[flavor_] = A * out_chi[flavor_];
138+ A_chi[flavor_] += b * out_chi[flavor_];
139+ A_chi[flavor_] += arg.c * out_chi[1 - flavor_];
140+ }
141+
142+ if constexpr (Arg::dynamic_clover) {
143+ HMat A2 = A.square ();
144+ A2 += arg.b2_minus_c2 ;
145+ Cholesky<HMatrix, clover::cholesky_t <typename Arg::Float>, Arg::nColor * Arg::nSpin / 2 > cholesky (A2 );
144146
145147#pragma unroll
146- for (int flavor_ = 0 ; flavor_ < n_flavor; flavor_++) {
147- out_chi[flavor_] = static_cast <real>(0.25 ) * cholesky.backward (cholesky.forward (A_chi[flavor_]));
148- }
149- } else {
150- HMat A2inv = arg.A2inv (coord.x_cb , parity, chirality);
148+ for (int flavor_ = 0 ; flavor_ < n_flavor; flavor_++) {
149+ out_chi[flavor_] = static_cast <real>(0.25 ) * cholesky.backward (cholesky.forward (A_chi[flavor_]));
150+ }
151+ } else {
152+ HMat A2inv = arg.A2inv (coord.x_cb , parity, chirality);
151153#pragma unroll
152- for (int flavor_ = 0 ; flavor_ < n_flavor; flavor_++) {
153- out_chi[flavor_] = static_cast <real>(2.0 ) * (A2inv * A_chi[flavor_]);
154- }
155- }
154+ for (int flavor_ = 0 ; flavor_ < n_flavor; flavor_++) {
155+ out_chi[flavor_] = static_cast <real>(2.0 ) * (A2inv * A_chi[flavor_]);
156+ }
157+ }
158+ }
156159 }
157160
158161 swizzle (out_chi, chirality); // undo the flavor-chirality swizzle
159162
160- if (isComplete<mykernel_type>(arg, coord) && active) {
161- Vector tmp = out_chi[0 ].chiral_reconstruct (0 ) + out_chi[1 ].chiral_reconstruct (1 );
162- tmp.toNonRel (); // switch back to non-chiral basis
163-
164- if (xpay && !arg.dd_x .isZero (coord)) {
165- Vector x = arg.x [src_idx](my_flavor_idx, my_spinor_parity);
166- out = x + arg.a * tmp;
167- } else {
168- // multiplication with a needed here?
169- out = arg.a * tmp;
170- }
163+ if (!allthreads || alive) {
164+ if (isComplete<mykernel_type>(arg, coord) && active) {
165+ Vector tmp = out_chi[0 ].chiral_reconstruct (0 ) + out_chi[1 ].chiral_reconstruct (1 );
166+ tmp.toNonRel (); // switch back to non-chiral basis
167+
168+ if (xpay && !arg.dd_x .isZero (coord)) {
169+ Vector x = arg.x [src_idx](my_flavor_idx, my_spinor_parity);
170+ out = x + arg.a * tmp;
171+ } else {
172+ // multiplication with a needed here?
173+ out = arg.a * tmp;
174+ }
175+ }
176+
177+ if (mykernel_type != EXTERIOR_KERNEL_ALL || active) arg.out [src_idx](my_flavor_idx, my_spinor_parity) = out;
171178 }
172-
173- if (active) arg.out [src_idx](my_flavor_idx, my_spinor_parity) = out;
174179 }
175180 };
176181} // namespace quda
0 commit comments