QUDA v0.4.0
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   Solution is to use class inheritance to defined different mappings,
00022   and combine it with templating on the return type.  Initial attempt
00023   at this is in the cpuColorSpinorField, but this will eventually roll
00024   out here too.
00025 
00026 */
00027 
00028 
00029 /*
00030 
00031   Packing routines
00032 
00033 */
00034 
00035 #define PRESERVE_SPINOR_NORM
00036 
00037 #ifdef PRESERVE_SPINOR_NORM // Preserve the norm regardless of basis
00038 double kP = (1.0/sqrt(2.0));
00039 double kU = (1.0/sqrt(2.0));
00040 #else // More numerically accurate not to preserve the norm between basis
00041 double kP = 0.5;
00042 double kU = 1.0;
00043 #endif
00044 
00045 // SPACE_SPIN_COLOR -> FLOAT1, FLOAT2 or FLOAT4 (no "internal re-ordering")
00046 template <int Nc, int Ns, int N, typename Float, typename FloatN>
00047 inline void packSpinorField(FloatN* a, Float *b, int V) {
00048   for (int sc=0; sc<(Ns*Nc*2)/N; sc++) {
00049     for (int zc=0; zc<N; zc++) {
00050       (a+N*V*sc)[zc] = b[sc*N+zc];
00051     }
00052   }
00053 }
00054 
00055 // SPACE_COLOR_SPIN -> FLOATN (maintain Dirac basis)
00056 template <int Nc, int Ns, int N, typename Float, typename FloatN>
00057 inline void packQLASpinorField(FloatN* a, Float *b, int V) {
00058   for (int s=0; s<Ns; s++) {
00059     for (int c=0; c<Nc; c++) {
00060       for (int z=0; z<2; z++) {
00061         (a+(((s*Nc+c)*2+z)/N)*V*N) [((s*Nc+c)*2+z) % N] = b[(c*Ns+s)*2+z];
00062       }
00063     }
00064   }
00065 
00066 }
00067 
00068 // SPACE_SPIN_COLOR -> FLOATN (Chiral -> non-relativistic)
00069 template <int Nc, int N, typename Float, typename FloatN>
00070 inline void packNonRelSpinorField(FloatN* a, Float *b, int V) {
00071   int s1[4] = {1, 2, 3, 0};
00072   int s2[4] = {3, 0, 1, 2};
00073   Float K1[4] = {kP, -kP, -kP, -kP};
00074   Float K2[4] = {kP, -kP, kP, kP};
00075 
00076   for (int s=0; s<4; s++) {
00077     for (int c=0; c<Nc; c++) {
00078       for (int z=0; z<2; z++) {
00079         (a+(((s*Nc+c)*2+z)/N)*V*N )[((s*Nc+c)*2+z) % N] =
00080           K1[s]*b[(s1[s]*Nc+c)*2+z] + K2[s]*b[(s2[s]*Nc+c)*2+z];
00081       }
00082     }
00083   }
00084 
00085 }
00086 
00087 // SPACE_COLOR_SPIN -> FLOATN (Chiral -> non-relativistic)
00088 template <int Nc, int N, typename Float, typename FloatN>
00089 inline void packNonRelQLASpinorField(FloatN* a, Float *b, int V) {
00090   int s1[4] = {1, 2, 3, 0};
00091   int s2[4] = {3, 0, 1, 2};
00092   Float K1[4] = {kP, -kP, -kP, -kP};
00093   Float K2[4] = {kP, -kP, kP, kP};
00094 
00095   for (int s=0; s<4; s++) {
00096     for (int c=0; c<Nc; c++) {
00097       for (int z=0; z<2; z++) {
00098         (a+(((s*Nc+c)*2+z)/N)*V*N )[((s*Nc+c)*2+z) % N] =
00099           K1[s]*b[(c*4+s1[s])*2+z] + K2[s]*b[(c*4+s2[s])*2+z];
00100       }
00101     }
00102   }
00103 
00104 }
00105 
00106 // Standard spinor packing, colour inside spin
00107 template <int Nc, int Ns, int N, typename Float, typename FloatN>
00108 void packParitySpinor(FloatN *dest, Float *src, int Vh, int pad, 
00109                       QudaGammaBasis destBasis, QudaGammaBasis srcBasis) {
00110   if (destBasis==srcBasis) {
00111     for (int i = 0; i < Vh; i++) {
00112       packSpinorField<Nc, Ns, N>(dest+N*i, src+2*Nc*Ns*i, Vh+pad);
00113     }
00114   } else if (destBasis == QUDA_UKQCD_GAMMA_BASIS && srcBasis == QUDA_DEGRAND_ROSSI_GAMMA_BASIS) {
00115     if (Ns != 4) errorQuda("Can only change basis with Nspin = 4, not Nspin = %d", Ns);
00116     for (int i = 0; i < Vh; i++) {
00117       packNonRelSpinorField<Nc, N>(dest+N*i, src+2*Nc*Ns*i, Vh+pad);
00118     }
00119   } else {
00120     errorQuda("Basis change not supported");
00121   }
00122 }
00123 
00124 // QLA spinor packing, spin inside colour
00125 template <int Nc, int Ns, int N, typename Float, typename FloatN>
00126 void packQLAParitySpinor(FloatN *dest, Float *src, int Vh, int pad,
00127                          QudaGammaBasis destBasis, QudaGammaBasis srcBasis) {
00128   if (destBasis==srcBasis) {
00129     for (int i = 0; i < Vh; i++) {
00130       packQLASpinorField<Nc, Ns, N>(dest+N*i, src+2*Nc*Ns*i, Vh+pad);
00131     }
00132   } else if (destBasis == QUDA_UKQCD_GAMMA_BASIS && srcBasis == QUDA_DEGRAND_ROSSI_GAMMA_BASIS) {
00133     if (Ns != 4) errorQuda("Can only change basis with Nspin = 4, not Nspin = %d", Ns);
00134     for (int i = 0; i < Vh; i++) {
00135       packNonRelQLASpinorField<Nc, N>(dest+N*i, src+2*Nc*Ns*i, Vh+pad);
00136     }
00137   } else {
00138     errorQuda("Basis change not supported");
00139   }
00140 }
00141 
00142 template <int Nc, int Ns, int N, typename Float, typename FloatN>
00143 void packFullSpinor(FloatN *dest, Float *src, int V, int pad, const int x[], int destLength,
00144                     QudaGammaBasis destBasis, QudaGammaBasis srcBasis) {
00145   
00146   int Vh = V/2;
00147   if (destBasis==srcBasis) {
00148     for (int i=0; i<V/2; i++) {
00149       
00150       int boundaryCrossings = i/(x[0]/2) + i/(x[1]*(x[0]/2)) + i/(x[2]*x[1]*(x[0]/2));
00151       
00152       { // even sites
00153         int k = 2*i + boundaryCrossings%2; 
00154         packSpinorField<Nc,Ns,N>(dest+N*i, src+2*Nc*Ns*k, Vh+pad);
00155       }
00156       
00157       { // odd sites
00158         int k = 2*i + (boundaryCrossings+1)%2;
00159         packSpinorField<Nc,Ns,N>(dest+destLength/2+N*i, src+ 2*Nc*Ns*k, Vh+pad);
00160       }
00161     }
00162   } else if (destBasis == QUDA_UKQCD_GAMMA_BASIS && srcBasis == QUDA_DEGRAND_ROSSI_GAMMA_BASIS) {
00163     if (Ns != 4) errorQuda("Can only change basis with Nspin = 4, not Nspin = %d", Ns);
00164     for (int i=0; i<V/2; i++) {
00165       
00166       int boundaryCrossings = i/(x[0]/2) + i/(x[1]*(x[0]/2)) + i/(x[2]*x[1]*(x[0]/2));
00167       
00168       { // even sites
00169         int k = 2*i + boundaryCrossings%2; 
00170         packNonRelSpinorField<Nc,N>(dest+N*i, src+2*Nc*Ns*k, Vh+pad);
00171       }
00172       
00173       { // odd sites
00174         int k = 2*i + (boundaryCrossings+1)%2;
00175         packNonRelSpinorField<Nc,N>(dest+destLength/2+N*i, src+2*Nc*Ns*k, Vh+pad);
00176       }
00177     }
00178   } else {
00179     errorQuda("Basis change not supported");
00180   }
00181 }
00182 
00183 template <int Nc, int Ns, int N, typename Float, typename FloatN>
00184 void packQLAFullSpinor(FloatN *dest, Float *src, int V, int pad, const int x[], 
00185                        int destLength, QudaGammaBasis destBasis, QudaGammaBasis srcBasis) {
00186   
00187   int Vh = V/2;
00188   if (destBasis==srcBasis) {
00189     for (int i=0; i<V/2; i++) {
00190       
00191       int boundaryCrossings = i/(x[0]/2) + i/(x[1]*(x[0]/2)) + i/(x[2]*x[1]*(x[0]/2));
00192       
00193       { // even sites
00194         int k = 2*i + boundaryCrossings%2; 
00195         packQLASpinorField<Nc,Ns,N>(dest+N*i, src+2*Nc*Ns*k, Vh+pad);
00196       }
00197       
00198       { // odd sites
00199         int k = 2*i + (boundaryCrossings+1)%2;
00200         packQLASpinorField<Nc,Ns,N>(dest+destLength/2+N*i, src+2*Nc*Ns*k, Vh+pad);
00201       }
00202     }
00203   } else if (destBasis == QUDA_UKQCD_GAMMA_BASIS && srcBasis == QUDA_DEGRAND_ROSSI_GAMMA_BASIS) {
00204     for (int i=0; i<V/2; i++) {
00205       
00206       int boundaryCrossings = i/(x[0]/2) + i/(x[1]*(x[0]/2)) + i/(x[2]*x[1]*(x[0]/2));
00207       
00208       { // even sites
00209         int k = 2*i + boundaryCrossings%2; 
00210         packNonRelQLASpinorField<Nc,N>(dest+N*i, src+2*Nc*Ns*k, Vh+pad);
00211       }
00212       
00213       { // odd sites
00214         int k = 2*i + (boundaryCrossings+1)%2;
00215         packNonRelQLASpinorField<Nc,N>(dest+destLength/2+N*i, src+2*Nc*Ns*k, Vh+pad);
00216       }
00217     }
00218   } else {
00219     errorQuda("Basis change not supported");
00220   }
00221 }
00222 
00223 
00224 /*
00225 
00226   Unpacking routines
00227 
00228 */
00229 
00230 // SPACE_SPIN_COLOR -> FLOAT1, FLOAT2 or FLOAT4 (no "internal re-ordering")
00231 template <int Nc, int Ns, int N, typename Float, typename FloatN>
00232 inline void unpackSpinorField(Float* a, FloatN *b, int V) {
00233   for (int sc=0; sc<(Ns*Nc*2)/N; sc++) {
00234     for (int zc=0; zc<N; zc++) {
00235       a[sc*N+zc] = (b+N*V*sc)[zc];
00236     }
00237   }
00238 }
00239 
00240 // SPACE_COLOR_SPIN -> FLOATN (maintain Dirac basis)
00241 template <int Nc, int Ns, int N, typename Float, typename FloatN>
00242 inline void unpackQLASpinorField(Float* a, FloatN *b, int V) {
00243   for (int s=0; s<Ns; s++) {
00244     for (int c=0; c<Nc; c++) {
00245       for (int z=0; z<2; z++) {
00246         a[(c*Ns+s)*2+z] = (b+(((s*Nc+c)*2+z)/N)*V*N) [((s*Nc+c)*2+z) % N];
00247       }
00248     }
00249   }
00250 
00251 }
00252 
00253 // SPACE_SPIN_COLOR -> FLOATN (Chiral -> non-relativistic)
00254 template <int Nc, int N, typename Float, typename FloatN>
00255 inline void unpackNonRelSpinorField(Float* a, FloatN *b, int V) {
00256   int s1[4] = {1, 2, 3, 0};
00257   int s2[4] = {3, 0, 1, 2};
00258   Float K1[4] = {-kU, kU,  kU,  kU};
00259   Float K2[4] = {-kU, kU, -kU, -kU};
00260 
00261   for (int s=0; s<4; s++) {
00262     for (int c=0; c<Nc; c++) {
00263       for (int z=0; z<2; z++) {
00264           a[(s*Nc+c)*2+z] =
00265             K1[s]*(b+(((s1[s]*Nc+c)*2+z)/N)*V*N )[((s1[s]*Nc+c)*2+z) % N] +
00266             K2[s]*(b+(((s2[s]*Nc+c)*2+z)/N)*V*N )[((s2[s]*Nc+c)*2+z) % N];
00267       }
00268     }
00269   }
00270 
00271 }
00272 
00273 // SPACE_COLOR_SPIN -> FLOATN (Chiral -> non-relativistic)
00274 template <int Nc, int N, typename Float, typename FloatN>
00275 inline void unpackNonRelQLASpinorField(Float* a, FloatN *b, int V) {
00276   int s1[4] = {1, 2, 3, 0};
00277   int s2[4] = {3, 0, 1, 2};
00278   Float K1[4] = {-kU, kU,  kU,  kU};
00279   Float K2[4] = {-kU, kU, -kU, -kU};
00280 
00281   for (int s=0; s<4; s++) {
00282     for (int c=0; c<Nc; c++) {
00283       for (int z=0; z<2; z++) {
00284           a[(c*4+s)*2+z] =
00285             K1[s]*(b+(((s1[s]*Nc+c)*2+z)/N)*V*N )[((s1[s]*Nc+c)*2+z) % N] +
00286             K2[s]*(b+(((s2[s]*Nc+c)*2+z)/N)*V*N )[((s2[s]*Nc+c)*2+z) % N];
00287       }
00288     }
00289   }
00290 
00291 }
00292 
00293 // Standard spinor unpacking, colour inside spin
00294 template <int Nc, int Ns, int N, typename Float, typename FloatN>
00295 void unpackParitySpinor(Float *dest, FloatN *src, int Vh, int pad, 
00296                       QudaGammaBasis destBasis, QudaGammaBasis srcBasis) {
00297   if (destBasis==srcBasis) {
00298     for (int i = 0; i < Vh; i++) {
00299       unpackSpinorField<Nc, Ns, N>(dest+2*Nc*Ns*i, src+N*i, Vh+pad);
00300     }
00301   } else if (srcBasis == QUDA_UKQCD_GAMMA_BASIS && destBasis == QUDA_DEGRAND_ROSSI_GAMMA_BASIS) {
00302     if (Ns != 4) errorQuda("Can only change basis with Nspin = 4, not Nspin = %d", Ns);
00303     for (int i = 0; i < Vh; i++) {
00304       unpackNonRelSpinorField<Nc, N>(dest+2*Nc*Ns*i, src+N*i, Vh+pad);
00305     }
00306   } else {
00307     errorQuda("Basis change from %d to %d not supported", srcBasis, destBasis);
00308   }
00309 }
00310 
00311 // QLA spinor unpacking, spin inside colour
00312 template <int Nc, int Ns, int N, typename Float, typename FloatN>
00313 void unpackQLAParitySpinor(Float *dest, FloatN *src, int Vh, int pad,
00314                          QudaGammaBasis destBasis, QudaGammaBasis srcBasis) {
00315   if (destBasis==srcBasis) {
00316     for (int i = 0; i < Vh; i++) {
00317       unpackQLASpinorField<Nc, Ns, N>(dest+2*Nc*Ns*i, src+N*i, Vh+pad);
00318     }
00319   } else if (srcBasis == QUDA_UKQCD_GAMMA_BASIS && destBasis == QUDA_DEGRAND_ROSSI_GAMMA_BASIS) {
00320     if (Ns != 4) errorQuda("Can only change basus with Nspin = 4, not Nspin = %d", Ns);
00321     for (int i = 0; i < Vh; i++) {
00322       unpackNonRelQLASpinorField<Nc, N>(dest+2*Nc*Ns*i, src+N*i, Vh+pad);
00323     }
00324   } else {
00325     errorQuda("Basis change from %d to %d not supported", srcBasis, destBasis);
00326   }
00327 }
00328 
00329 template <int Nc, int Ns, int N, typename Float, typename FloatN>
00330 void unpackFullSpinor(Float *dest, FloatN *src, int V, int pad, const int x[], 
00331                       int srcLength, QudaGammaBasis destBasis, QudaGammaBasis srcBasis) {
00332   
00333   int Vh = V/2;
00334   if (destBasis==srcBasis) {
00335     for (int i=0; i<V/2; i++) {
00336       
00337       int boundaryCrossings = i/(x[0]/2) + i/(x[1]*(x[0]/2)) + i/(x[2]*x[1]*(x[0]/2));
00338       
00339       { // even sites
00340         int k = 2*i + boundaryCrossings%2; 
00341         unpackSpinorField<Nc,Ns,N>(dest+2*Ns*Nc*k, src+N*i, Vh+pad);
00342       }
00343       
00344       { // odd sites
00345         int k = 2*i + (boundaryCrossings+1)%2;
00346         unpackSpinorField<Nc,Ns,N>(dest+2*Ns*Nc*k, src+srcLength/2+N*i, Vh+pad);
00347       }
00348     }
00349   } else if (srcBasis == QUDA_UKQCD_GAMMA_BASIS && destBasis == QUDA_DEGRAND_ROSSI_GAMMA_BASIS) {
00350     if (Ns != 4) errorQuda("Can only change basis with Nspin = 4, not Nspin = %d", Ns);
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 Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines