QUDA v0.3.2
A library for QCD on GPUs

quda/lib/pack_spinor.h

Go to the documentation of this file.
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 
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines