|
QUDA v0.3.2
A library for QCD on GPUs
|
00001 /* 00002 MAC: 00003 00004 On my mark, unleash template hell 00005 00006 Here we are templating on the following 00007 - input precision 00008 - output precision 00009 - number of colors 00010 - number of spins 00011 - short vector lengh (float, float2, float4 etc.) 00012 00013 This is still quite a mess. Options to reduce to the amount of code 00014 bloat here include: 00015 00016 1. Using functors to define arbitrary ordering 00017 2. Use class inheritance to the same effect 00018 3. Abuse the C preprocessor to define arbitrary mappings 00019 4. Something else 00020 00021 I probably prefer option 2., the problem with 1.) and and 2.) as far 00022 as I can see it is that the fields are defined using void*, and cast 00023 at runtime as appropriate. This doesn't mesh well with defining 00024 return types based on inheritance which is decided at compile time. 00025 I could hack it returing void* and casting as appropriate (see 00026 functor examples in color_spinor_field.h, but this is going to be 00027 S..L..O..W. 00028 00029 While I think about this, I shall leave in the verbose state it is 00030 in, and come back to this in the future. 00031 00032 */ 00033 00034 00035 /* 00036 00037 Packing routines 00038 00039 */ 00040 00041 #define PRESERVE_SPINOR_NORM 1 00042 00043 #ifdef PRESERVE_SPINOR_NORM // Preserve the norm regardless of basis 00044 double kP = (1.0/sqrt(2.0)); 00045 double kU = (1.0/sqrt(2.0)); 00046 #else // More numerically accurate not to preserve the norm between basis 00047 double kP = 0.5; 00048 double kU = 1.0; 00049 #endif 00050 00051 // SPACE_SPIN_COLOR -> FLOAT1, FLOAT2 or FLOAT4 (no "internal re-ordering") 00052 template <int Nc, int Ns, int N, typename Float, typename FloatN> 00053 inline void packSpinorField(FloatN* a, Float *b, int V) { 00054 for (int sc=0; sc<(Ns*Nc*2)/N; sc++) { 00055 for (int zc=0; zc<N; zc++) { 00056 (a+N*V*sc)[zc] = b[sc*N+zc]; 00057 } 00058 } 00059 } 00060 00061 // SPACE_COLOR_SPIN -> FLOATN (maintain Dirac basis) 00062 template <int Nc, int Ns, int N, typename Float, typename FloatN> 00063 inline void packQLASpinorField(FloatN* a, Float *b, int V) { 00064 for (int s=0; s<Ns; s++) { 00065 for (int c=0; c<Nc; c++) { 00066 for (int z=0; z<2; z++) { 00067 (a+(((s*Nc+c)*2+z)/N)*V*N) [((s*Nc+c)*2+z) % N] = b[(c*Ns+s)*2+z]; 00068 } 00069 } 00070 } 00071 00072 } 00073 00074 // SPACE_SPIN_COLOR -> FLOATN (Chiral -> non-relativistic) 00075 template <int Nc, int N, typename Float, typename FloatN> 00076 inline void packNonRelSpinorField(FloatN* a, Float *b, int V) { 00077 int s1[4] = {1, 2, 3, 0}; 00078 int s2[4] = {3, 0, 1, 2}; 00079 Float K1[4] = {kP, -kP, -kP, -kP}; 00080 Float K2[4] = {kP, -kP, kP, kP}; 00081 00082 for (int s=0; s<4; s++) { 00083 for (int c=0; c<Nc; c++) { 00084 for (int z=0; z<2; z++) { 00085 (a+(((s*Nc+c)*2+z)/N)*V*N )[((s*Nc+c)*2+z) % N] = 00086 K1[s]*b[(s1[s]*Nc+c)*2+z] + K2[s]*b[(s2[s]*Nc+c)*2+z]; 00087 } 00088 } 00089 } 00090 00091 } 00092 00093 // SPACE_COLOR_SPIN -> FLOATN (Chiral -> non-relativistic) 00094 template <int Nc, int N, typename Float, typename FloatN> 00095 inline void packNonRelQLASpinorField(FloatN* a, Float *b, int V) { 00096 int s1[4] = {1, 2, 3, 0}; 00097 int s2[4] = {3, 0, 1, 2}; 00098 Float K1[4] = {kP, -kP, -kP, -kP}; 00099 Float K2[4] = {kP, -kP, kP, kP}; 00100 00101 for (int s=0; s<4; s++) { 00102 for (int c=0; c<Nc; c++) { 00103 for (int z=0; z<2; z++) { 00104 (a+(((s*Nc+c)*2+z)/N)*V*N )[((s*Nc+c)*2+z) % N] = 00105 K1[s]*b[(c*4+s1[s])*2+z] + K2[s]*b[(c*4+s2[s])*2+z]; 00106 } 00107 } 00108 } 00109 00110 } 00111 00112 // Standard spinor packing, colour inside spin 00113 template <int Nc, int Ns, int N, typename Float, typename FloatN> 00114 void packParitySpinor(FloatN *dest, Float *src, int Vh, int pad, 00115 QudaGammaBasis destBasis, QudaGammaBasis srcBasis) { 00116 if (destBasis==srcBasis) { 00117 for (int i = 0; i < Vh; i++) { 00118 packSpinorField<Nc, Ns, N>(dest+N*i, src+2*Nc*Ns*i, Vh+pad); 00119 } 00120 } else if (destBasis == QUDA_UKQCD_GAMMA_BASIS && srcBasis == QUDA_DEGRAND_ROSSI_GAMMA_BASIS) { 00121 for (int i = 0; i < Vh; i++) { 00122 packNonRelSpinorField<Nc, N>(dest+N*i, src+2*Nc*Ns*i, Vh+pad); 00123 } 00124 } else { 00125 errorQuda("Basis change not supported"); 00126 } 00127 } 00128 00129 // QLA spinor packing, spin inside colour 00130 template <int Nc, int Ns, int N, typename Float, typename FloatN> 00131 void packQLAParitySpinor(FloatN *dest, Float *src, int Vh, int pad, 00132 QudaGammaBasis destBasis, QudaGammaBasis srcBasis) { 00133 if (destBasis==srcBasis) { 00134 for (int i = 0; i < Vh; i++) { 00135 packQLASpinorField<Nc, Ns, N>(dest+N*i, src+2*Nc*Ns*i, Vh+pad); 00136 } 00137 } else if (destBasis == QUDA_UKQCD_GAMMA_BASIS && srcBasis == QUDA_DEGRAND_ROSSI_GAMMA_BASIS) { 00138 for (int i = 0; i < Vh; i++) { 00139 packNonRelQLASpinorField<Nc, N>(dest+N*i, src+2*Nc*Ns*i, Vh+pad); 00140 } 00141 } else { 00142 errorQuda("Basis change not supported"); 00143 } 00144 } 00145 00146 template <int Nc, int Ns, int N, typename Float, typename FloatN> 00147 void packFullSpinor(FloatN *dest, Float *src, int V, int pad, const int x[], int destLength, 00148 QudaGammaBasis destBasis, QudaGammaBasis srcBasis) { 00149 00150 int Vh = V/2; 00151 if (destBasis==srcBasis) { 00152 for (int i=0; i<V/2; i++) { 00153 00154 int boundaryCrossings = i/(x[0]/2) + i/(x[1]*(x[0]/2)) + i/(x[2]*x[1]*(x[0]/2)); 00155 00156 { // even sites 00157 int k = 2*i + boundaryCrossings%2; 00158 packSpinorField<Nc,Ns,N>(dest+N*i, src+2*Nc*Ns*k, Vh+pad); 00159 } 00160 00161 { // odd sites 00162 int k = 2*i + (boundaryCrossings+1)%2; 00163 packSpinorField<Nc,Ns,N>(dest+destLength/2+N*i, src+ 2*Nc*Ns*k, Vh+pad); 00164 } 00165 } 00166 } else if (destBasis == QUDA_UKQCD_GAMMA_BASIS && srcBasis == QUDA_DEGRAND_ROSSI_GAMMA_BASIS) { 00167 for (int i=0; i<V/2; i++) { 00168 00169 int boundaryCrossings = i/(x[0]/2) + i/(x[1]*(x[0]/2)) + i/(x[2]*x[1]*(x[0]/2)); 00170 00171 { // even sites 00172 int k = 2*i + boundaryCrossings%2; 00173 packNonRelSpinorField<Nc,N>(dest+N*i, src+2*Nc*Ns*k, Vh+pad); 00174 } 00175 00176 { // odd sites 00177 int k = 2*i + (boundaryCrossings+1)%2; 00178 packNonRelSpinorField<Nc,N>(dest+destLength/2+N*i, src+2*Nc*Ns*k, Vh+pad); 00179 } 00180 } 00181 } else { 00182 errorQuda("Basis change not supported"); 00183 } 00184 } 00185 00186 template <int Nc, int Ns, int N, typename Float, typename FloatN> 00187 void packQLAFullSpinor(FloatN *dest, Float *src, int V, int pad, const int x[], 00188 int destLength, QudaGammaBasis destBasis, QudaGammaBasis srcBasis) { 00189 00190 int Vh = V/2; 00191 if (destBasis==srcBasis) { 00192 for (int i=0; i<V/2; i++) { 00193 00194 int boundaryCrossings = i/(x[0]/2) + i/(x[1]*(x[0]/2)) + i/(x[2]*x[1]*(x[0]/2)); 00195 00196 { // even sites 00197 int k = 2*i + boundaryCrossings%2; 00198 packQLASpinorField<Nc,Ns,N>(dest+N*i, src+2*Nc*Ns*k, Vh+pad); 00199 } 00200 00201 { // odd sites 00202 int k = 2*i + (boundaryCrossings+1)%2; 00203 packQLASpinorField<Nc,Ns,N>(dest+destLength/2+N*i, src+2*Nc*Ns*k, Vh+pad); 00204 } 00205 } 00206 } else if (destBasis == QUDA_UKQCD_GAMMA_BASIS && srcBasis == QUDA_DEGRAND_ROSSI_GAMMA_BASIS) { 00207 for (int i=0; i<V/2; i++) { 00208 00209 int boundaryCrossings = i/(x[0]/2) + i/(x[1]*(x[0]/2)) + i/(x[2]*x[1]*(x[0]/2)); 00210 00211 { // even sites 00212 int k = 2*i + boundaryCrossings%2; 00213 packNonRelQLASpinorField<Nc,N>(dest+N*i, src+2*Nc*Ns*k, Vh+pad); 00214 } 00215 00216 { // odd sites 00217 int k = 2*i + (boundaryCrossings+1)%2; 00218 packNonRelQLASpinorField<Nc,N>(dest+destLength/2+N*i, src+2*Nc*Ns*k, Vh+pad); 00219 } 00220 } 00221 } else { 00222 errorQuda("Basis change not supported"); 00223 } 00224 } 00225 00226 00227 /* 00228 00229 Unpacking routines 00230 00231 */ 00232 00233 // SPACE_SPIN_COLOR -> FLOAT1, FLOAT2 or FLOAT4 (no "internal re-ordering") 00234 template <int Nc, int Ns, int N, typename Float, typename FloatN> 00235 inline void unpackSpinorField(Float* a, FloatN *b, int V) { 00236 for (int sc=0; sc<(Ns*Nc*2)/N; sc++) { 00237 for (int zc=0; zc<N; zc++) { 00238 a[sc*N+zc] = (b+N*V*sc)[zc]; 00239 } 00240 } 00241 } 00242 00243 // SPACE_COLOR_SPIN -> FLOATN (maintain Dirac basis) 00244 template <int Nc, int Ns, int N, typename Float, typename FloatN> 00245 inline void unpackQLASpinorField(Float* a, FloatN *b, int V) { 00246 for (int s=0; s<Ns; s++) { 00247 for (int c=0; c<Nc; c++) { 00248 for (int z=0; z<2; z++) { 00249 a[(c*Ns+s)*2+z] = (b+(((s*Nc+c)*2+z)/N)*V*N) [((s*Nc+c)*2+z) % N]; 00250 } 00251 } 00252 } 00253 00254 } 00255 00256 // SPACE_SPIN_COLOR -> FLOATN (Chiral -> non-relativistic) 00257 template <int Nc, int N, typename Float, typename FloatN> 00258 inline void unpackNonRelSpinorField(Float* a, FloatN *b, int V) { 00259 int s1[4] = {1, 2, 3, 0}; 00260 int s2[4] = {3, 0, 1, 2}; 00261 Float K1[4] = {-kU, kU, kU, kU}; 00262 Float K2[4] = {-kU, kU, -kU, -kU}; 00263 00264 for (int s=0; s<4; s++) { 00265 for (int c=0; c<Nc; c++) { 00266 for (int z=0; z<2; z++) { 00267 a[(s*Nc+c)*2+z] = 00268 K1[s]*(b+(((s1[s]*Nc+c)*2+z)/N)*V*N )[((s1[s]*Nc+c)*2+z) % N] + 00269 K2[s]*(b+(((s2[s]*Nc+c)*2+z)/N)*V*N )[((s2[s]*Nc+c)*2+z) % N]; 00270 } 00271 } 00272 } 00273 00274 } 00275 00276 // SPACE_COLOR_SPIN -> FLOATN (Chiral -> non-relativistic) 00277 template <int Nc, int N, typename Float, typename FloatN> 00278 inline void unpackNonRelQLASpinorField(Float* a, FloatN *b, int V) { 00279 int s1[4] = {1, 2, 3, 0}; 00280 int s2[4] = {3, 0, 1, 2}; 00281 Float K1[4] = {-kU, kU, kU, kU}; 00282 Float K2[4] = {-kU, kU, -kU, -kU}; 00283 00284 for (int s=0; s<4; s++) { 00285 for (int c=0; c<Nc; c++) { 00286 for (int z=0; z<2; z++) { 00287 a[(c*4+s)*2+z] = 00288 K1[s]*(b+(((s1[s]*Nc+c)*2+z)/N)*V*N )[((s1[s]*Nc+c)*2+z) % N] + 00289 K2[s]*(b+(((s2[s]*Nc+c)*2+z)/N)*V*N )[((s2[s]*Nc+c)*2+z) % N]; 00290 } 00291 } 00292 } 00293 00294 } 00295 00296 // Standard spinor unpacking, colour inside spin 00297 template <int Nc, int Ns, int N, typename Float, typename FloatN> 00298 void unpackParitySpinor(Float *dest, FloatN *src, int Vh, int pad, 00299 QudaGammaBasis destBasis, QudaGammaBasis srcBasis) { 00300 if (destBasis==srcBasis) { 00301 for (int i = 0; i < Vh; i++) { 00302 unpackSpinorField<Nc, Ns, N>(dest+2*Nc*Ns*i, src+N*i, Vh+pad); 00303 } 00304 } else if (srcBasis == QUDA_UKQCD_GAMMA_BASIS && destBasis == QUDA_DEGRAND_ROSSI_GAMMA_BASIS) { 00305 for (int i = 0; i < Vh; i++) { 00306 unpackNonRelSpinorField<Nc, N>(dest+2*Nc*Ns*i, src+N*i, Vh+pad); 00307 } 00308 } else { 00309 errorQuda("Basis change from %d to %d not supported", srcBasis, destBasis); 00310 } 00311 } 00312 00313 // QLA spinor unpacking, spin inside colour 00314 template <int Nc, int Ns, int N, typename Float, typename FloatN> 00315 void unpackQLAParitySpinor(Float *dest, FloatN *src, int Vh, int pad, 00316 QudaGammaBasis destBasis, QudaGammaBasis srcBasis) { 00317 if (destBasis==srcBasis) { 00318 for (int i = 0; i < Vh; i++) { 00319 unpackQLASpinorField<Nc, Ns, N>(dest+2*Nc*Ns*i, src+N*i, Vh+pad); 00320 } 00321 } else if (srcBasis == QUDA_UKQCD_GAMMA_BASIS && destBasis == QUDA_DEGRAND_ROSSI_GAMMA_BASIS) { 00322 for (int i = 0; i < Vh; i++) { 00323 unpackNonRelQLASpinorField<Nc, N>(dest+2*Nc*Ns*i, src+N*i, Vh+pad); 00324 } 00325 } else { 00326 errorQuda("Basis change from %d to %d not supported", srcBasis, destBasis); 00327 } 00328 } 00329 00330 template <int Nc, int Ns, int N, typename Float, typename FloatN> 00331 void unpackFullSpinor(Float *dest, FloatN *src, int V, int pad, const int x[], 00332 int srcLength, QudaGammaBasis destBasis, QudaGammaBasis srcBasis) { 00333 00334 int Vh = V/2; 00335 if (destBasis==srcBasis) { 00336 for (int i=0; i<V/2; i++) { 00337 00338 int boundaryCrossings = i/(x[0]/2) + i/(x[1]*(x[0]/2)) + i/(x[2]*x[1]*(x[0]/2)); 00339 00340 { // even sites 00341 int k = 2*i + boundaryCrossings%2; 00342 unpackSpinorField<Nc,Ns,N>(dest+2*Ns*Nc*k, src+N*i, Vh+pad); 00343 } 00344 00345 { // odd sites 00346 int k = 2*i + (boundaryCrossings+1)%2; 00347 unpackSpinorField<Nc,Ns,N>(dest+2*Ns*Nc*k, src+srcLength/2+N*i, Vh+pad); 00348 } 00349 } 00350 } else if (srcBasis == QUDA_UKQCD_GAMMA_BASIS && destBasis == QUDA_DEGRAND_ROSSI_GAMMA_BASIS) { 00351 for (int i=0; i<V/2; i++) { 00352 00353 int boundaryCrossings = i/(x[0]/2) + i/(x[1]*(x[0]/2)) + i/(x[2]*x[1]*(x[0]/2)); 00354 00355 { // even sites 00356 int k = 2*i + boundaryCrossings%2; 00357 unpackNonRelSpinorField<Nc,N>(dest+2*Ns*Nc*k, src+N*i, Vh+pad); 00358 } 00359 00360 { // odd sites 00361 int k = 2*i + (boundaryCrossings+1)%2; 00362 unpackNonRelSpinorField<Nc,N>(dest+2*Ns*Nc*k, src+srcLength/2+N*i, Vh+pad); 00363 } 00364 } 00365 } else { 00366 errorQuda("Basis change not supported"); 00367 } 00368 } 00369 00370 template <int Nc, int Ns, int N, typename Float, typename FloatN> 00371 void unpackQLAFullSpinor(Float *dest, FloatN *src, int V, int pad, const int x[], 00372 int srcLength, QudaGammaBasis destBasis, QudaGammaBasis srcBasis) { 00373 00374 int Vh = V/2; 00375 if (destBasis==srcBasis) { 00376 for (int i=0; i<V/2; i++) { 00377 00378 int boundaryCrossings = i/(x[0]/2) + i/(x[1]*(x[0]/2)) + i/(x[2]*x[1]*(x[0]/2)); 00379 00380 { // even sites 00381 int k = 2*i + boundaryCrossings%2; 00382 unpackQLASpinorField<Nc,Ns,N>(dest+2*Nc*Ns*k, src+N*i, Vh+pad); 00383 } 00384 00385 { // odd sites 00386 int k = 2*i + (boundaryCrossings+1)%2; 00387 unpackQLASpinorField<Nc,Ns,N>(dest+2*Nc*Ns*k, src+srcLength/2+N*i, Vh+pad); 00388 } 00389 } 00390 } else if (srcBasis == QUDA_UKQCD_GAMMA_BASIS && destBasis == QUDA_DEGRAND_ROSSI_GAMMA_BASIS) { 00391 for (int i=0; i<V/2; i++) { 00392 00393 int boundaryCrossings = i/(x[0]/2) + i/(x[1]*(x[0]/2)) + i/(x[2]*x[1]*(x[0]/2)); 00394 00395 { // even sites 00396 int k = 2*i + boundaryCrossings%2; 00397 unpackNonRelQLASpinorField<Nc,N>(dest+2*Ns*Nc*k, src+N*i, Vh+pad); 00398 } 00399 00400 { // odd sites 00401 int k = 2*i + (boundaryCrossings+1)%2; 00402 unpackNonRelQLASpinorField<Nc,N>(dest+2*Ns*Nc*k, src+srcLength/2+N*i, Vh+pad); 00403 } 00404 } 00405 } else { 00406 errorQuda("Basis change not supported"); 00407 } 00408 } 00409 00410 template <int Nc, int Ns, int N, typename Float, typename FloatN> 00411 void packSpinor(FloatN *dest, Float *src, int V, int pad, const int x[], int destLength, 00412 int srcLength, QudaSiteSubset srcSubset, QudaSiteOrder siteOrder, 00413 QudaGammaBasis destBasis, QudaGammaBasis srcBasis, QudaFieldOrder srcOrder) { 00414 00415 // printf("%d %d %d %d %d %d %d %d %d %d %d\n", Nc, Ns, N, V, pad, length, srcSubset, subsetOrder, destBasis, srcBasis, srcOrder); 00416 00417 if (srcSubset == QUDA_FULL_SITE_SUBSET) { 00418 if (siteOrder == QUDA_LEXICOGRAPHIC_SITE_ORDER) { 00419 // We are copying from a full spinor field that is not parity ordered 00420 if (srcOrder == QUDA_SPACE_SPIN_COLOR_FIELD_ORDER) { 00421 packFullSpinor<Nc,Ns,N>(dest, src, V, pad, x, destLength, destBasis, srcBasis); 00422 } else if (srcOrder == QUDA_SPACE_COLOR_SPIN_FIELD_ORDER) { 00423 packQLAFullSpinor<Nc,Ns,N>(dest, src, V, pad, x, destLength, destBasis, srcBasis); 00424 } else { 00425 errorQuda("Source field order not supported"); 00426 } 00427 } else { 00428 // We are copying a parity ordered field 00429 00430 // check what src parity ordering is 00431 unsigned int evenOff, oddOff; 00432 if (siteOrder == QUDA_EVEN_ODD_SITE_ORDER) { 00433 evenOff = 0; 00434 oddOff = srcLength/2; 00435 } else { 00436 oddOff = 0; 00437 evenOff = srcLength/2; 00438 } 00439 00440 if (srcOrder == QUDA_SPACE_SPIN_COLOR_FIELD_ORDER) { 00441 packParitySpinor<Nc,Ns,N>(dest, src+evenOff, V/2, pad, destBasis, srcBasis); 00442 packParitySpinor<Nc,Ns,N>(dest + destLength/2, src+oddOff, V/2, pad, destBasis, srcBasis); 00443 } else if (srcOrder == QUDA_SPACE_COLOR_SPIN_FIELD_ORDER) { 00444 packQLAParitySpinor<Nc,Ns,N>(dest, src+evenOff, V/2, pad, destBasis, srcBasis); 00445 packQLAParitySpinor<Nc,Ns,N>(dest + destLength/2, src+oddOff, V/2, pad, destBasis, srcBasis); 00446 } else { 00447 errorQuda("Source field order not supported"); 00448 } 00449 } 00450 } else { 00451 // src is defined on a single parity only 00452 if (srcOrder == QUDA_SPACE_SPIN_COLOR_FIELD_ORDER) { 00453 packParitySpinor<Nc,Ns,N>(dest, src, V, pad, destBasis, srcBasis); 00454 } else if (srcOrder == QUDA_SPACE_COLOR_SPIN_FIELD_ORDER) { 00455 packQLAParitySpinor<Nc,Ns,N>(dest, src, V, pad, destBasis, srcBasis); 00456 } else { 00457 errorQuda("Source field order not supported"); 00458 } 00459 } 00460 00461 } 00462 00463 template <int Nc, int Ns, int N, typename Float, typename FloatN> 00464 void unpackSpinor(Float *dest, FloatN *src, int V, int pad, const int x[], int destLength, 00465 int srcLength, QudaSiteSubset destSubset, QudaSiteOrder siteOrder, 00466 QudaGammaBasis destBasis, QudaGammaBasis srcBasis, QudaFieldOrder destOrder) { 00467 00468 if (destSubset == QUDA_FULL_SITE_SUBSET) { 00469 if (siteOrder == QUDA_LEXICOGRAPHIC_SITE_ORDER) { 00470 // We are copying from a full spinor field that is not parity ordered 00471 if (destOrder == QUDA_SPACE_SPIN_COLOR_FIELD_ORDER) { 00472 unpackFullSpinor<Nc,Ns,N>(dest, src, V, pad, x, srcLength, destBasis, srcBasis); 00473 } else if (destOrder == QUDA_SPACE_COLOR_SPIN_FIELD_ORDER) { 00474 unpackQLAFullSpinor<Nc,Ns,N>(dest, src, V, pad, x, srcLength, destBasis, srcBasis); 00475 } else { 00476 errorQuda("Source field order not supported"); 00477 } 00478 } else { 00479 // We are copying a parity ordered field 00480 00481 // check what src parity ordering is 00482 unsigned int evenOff, oddOff; 00483 if (siteOrder == QUDA_EVEN_ODD_SITE_ORDER) { 00484 evenOff = 0; 00485 oddOff = srcLength/2; 00486 } else { 00487 oddOff = 0; 00488 evenOff = srcLength/2; 00489 } 00490 00491 if (destOrder == QUDA_SPACE_SPIN_COLOR_FIELD_ORDER) { 00492 unpackParitySpinor<Nc,Ns,N>(dest, src+evenOff, V/2, pad, destBasis, srcBasis); 00493 unpackParitySpinor<Nc,Ns,N>(dest + destLength/2, src+oddOff, V/2, pad, destBasis, srcBasis); 00494 } else if (destOrder == QUDA_SPACE_COLOR_SPIN_FIELD_ORDER) { 00495 unpackQLAParitySpinor<Nc,Ns,N>(dest, src+evenOff, V/2, pad, destBasis, srcBasis); 00496 unpackQLAParitySpinor<Nc,Ns,N>(dest + destLength/2, src+oddOff, V/2, pad, destBasis, srcBasis); 00497 } else { 00498 errorQuda("Source field order not supported"); 00499 } 00500 } 00501 } else { 00502 // src is defined on a single parity only 00503 if (destOrder == QUDA_SPACE_SPIN_COLOR_FIELD_ORDER) { 00504 unpackParitySpinor<Nc,Ns,N>(dest, src, V, pad, destBasis, srcBasis); 00505 } else if (destOrder == QUDA_SPACE_COLOR_SPIN_FIELD_ORDER) { 00506 unpackQLAParitySpinor<Nc,Ns,N>(dest, src, V, pad, destBasis, srcBasis); 00507 } else { 00508 errorQuda("Source field order not supported"); 00509 } 00510 } 00511 00512 } 00513
1.7.3