SortAtoms.C File Reference

#include "SortAtoms.h"
#include "NamdTypes.h"
#include <algorithm>

Go to the source code of this file.

Classes

struct  sortop_base
struct  sortop_x
struct  sortop_y
struct  sortop_z

Defines

#define PARTWIDTH   32
#define NTH_ELEMENT(BEGIN, SPLIT, END, OP)   std::nth_element(BEGIN,SPLIT,END,OP)

Functions

static void partition (int *order, const FullAtom *atoms, int begin, int end)
void sortAtomsForCUDA (int *order, const FullAtom *atoms, int nfree, int n)
void sortAtomsForPatches (int *order, int *breaks, const FullAtom *atoms, int nmgrps, int natoms, int ni, int nj, int nk)

Define Documentation

#define NTH_ELEMENT ( BEGIN,
SPLIT,
END,
OP   )     std::nth_element(BEGIN,SPLIT,END,OP)

Referenced by partition().

#define PARTWIDTH   32

Referenced by partition().


Function Documentation

static void partition ( int *  order,
const FullAtom atoms,
int  begin,
int  end 
) [static]

Definition at line 41 of file SortAtoms.C.

References NTH_ELEMENT, PARTWIDTH, CompAtom::position, split(), Vector::x, Vector::y, and Vector::z.

Referenced by Sequencer::calcKineticEnergy(), HomePatch::hardWallDrude(), Sequencer::langevinVelocities(), Sequencer::langevinVelocitiesBBK2(), Sequencer::multigratorPressure(), HomePatch::rattle1old(), Sequencer::reassignVelocities(), Sequencer::reinitVelocities(), sortAtomsForCUDA(), Sequencer::submitHalfstep(), and Sequencer::submitReductions().

00041                                                                              {
00042 
00043   //  Applies orthogonal recursive bisection with splittings limited
00044   //  to multiples of 32 for warps and a final split on multiples of 16.
00045 
00046 #ifdef NAMD_AVXTILES
00047 #define PARTWIDTH 16
00048 #else
00049 #define PARTWIDTH 32
00050 #endif
00051 
00052   int split;
00053   // must be a multiple of 32 or 16 between begin and end to split at
00054   if ( begin/PARTWIDTH < (end-1)/PARTWIDTH ) {
00055     // find a multiple of 32 near the median
00056     split = ((begin + end + PARTWIDTH) / (PARTWIDTH*2)) * PARTWIDTH;
00057   } else if ( begin/(PARTWIDTH/2) < (end-1)/(PARTWIDTH/2) ) {
00058     // find a multiple of 16 near the median
00059     split = ((begin + end + (PARTWIDTH/2)) / PARTWIDTH) * (PARTWIDTH/2);
00060   } else {
00061     return;
00062   }
00063 
00064   BigReal xmin, ymin, zmin, xmax, ymax, zmax;
00065   {
00066     const Position &pos = atoms[order[begin]].position;
00067     xmin = pos.x;
00068     ymin = pos.y;
00069     zmin = pos.z;
00070     xmax = pos.x;
00071     ymax = pos.y;
00072     zmax = pos.z;
00073   }
00074   for ( int i=begin+1; i<end; ++i ) {
00075     const Position &pos = atoms[order[i]].position;
00076     if ( pos.x < xmin ) { xmin = pos.x; }
00077     if ( pos.y < ymin ) { ymin = pos.y; }
00078     if ( pos.z < zmin ) { zmin = pos.z; }
00079     if ( pos.x > xmax ) { xmax = pos.x; }
00080     if ( pos.y > ymax ) { ymax = pos.y; }
00081     if ( pos.z > zmax ) { zmax = pos.z; }
00082   }
00083   xmax -= xmin;
00084   ymax -= ymin;
00085   zmax -= zmin;
00086 
00087 #define NTH_ELEMENT(BEGIN,SPLIT,END,OP) std::nth_element(BEGIN,SPLIT,END,OP)
00088 #if defined(NAMD_CUDA) && defined(__GNUC_PATCHLEVEL__)
00089 #if __GNUC__ == 4 && __GNUC_MINOR__ == 8 && __GNUC_PATCHLEVEL__ == 2
00090 #define NTH_ELEMENT(BEGIN,SPLIT,END,OP) std::sort(BEGIN,END,OP)
00091 #warning gcc 4.8.2 std::nth_element would segfault (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58800)
00092 #endif
00093 #endif
00094 
00095   if ( xmax >= ymax && xmax >= zmax ) {
00096     NTH_ELEMENT(order+begin, order+split, order+end, sortop_x(atoms));
00097   } else if ( ymax >= xmax && ymax >= zmax ) {
00098     NTH_ELEMENT(order+begin, order+split, order+end, sortop_y(atoms));
00099   } else {
00100     NTH_ELEMENT(order+begin, order+split, order+end, sortop_z(atoms));
00101   }
00102 
00103   if ( split & PARTWIDTH/2 ) return;
00104 
00105 #undef PARTWIDTH
00106 
00107   // recursively partition before and after split
00108   partition(order, atoms, begin, split);
00109   partition(order, atoms, split, end);
00110 
00111 }

void sortAtomsForCUDA ( int *  order,
const FullAtom atoms,
int  nfree,
int  n 
)

Definition at line 119 of file SortAtoms.C.

References partition().

Referenced by HomePatch::positionsReady().

00119                                                                            {
00120 
00121   // partition free atoms
00122   // CkPrintf("%d %d\n", 0, nfree);
00123   partition(order, atoms, 0, nfree);
00124 
00125   // partition fixed atoms
00126   // CkPrintf("%d %d\n", nfree, n);
00127   partition(order, atoms, nfree, n);
00128 
00129 }

void sortAtomsForPatches ( int *  order,
int *  breaks,
const FullAtom atoms,
int  nmgrps,
int  natoms,
int  ni,
int  nj,
int  nk 
)

Definition at line 131 of file SortAtoms.C.

References FullAtom::migrationGroupSize, and sort.

Referenced by WorkDistrib::createAtomLists().

00133                                                  {
00134 
00135 //CkPrintf("sorting %d atoms in %d groups to %d x %d x %d\n",
00136 //    natoms, nmgrps, nk, nj, ni);
00137   std::sort(order, order+nmgrps, sortop_z(atoms));
00138   int pid = 0;
00139   int ibegin = 0;
00140   int nai = 0;
00141   for ( int ip=0; ip < ni; ++ip ) {
00142     int naj = nai;
00143     int targi = nai + (natoms - nai - 1) / (ni - ip) + 1;
00144     int iend;
00145     for ( iend=ibegin; iend<nmgrps; ++iend ) { 
00146       int mgs = atoms[order[iend]].migrationGroupSize;
00147       if (nai + mgs <= targi) nai += mgs;
00148       else break;
00149     }
00150 //CkPrintf("  Z %d %d (%d) %d\n", ibegin, iend, iend-ibegin, nai);
00151     std::sort(order+ibegin, order+iend, sortop_y(atoms));
00152     int jbegin = ibegin;
00153     for ( int jp=0; jp < nj; ++jp ) {
00154       int nak = naj;
00155       int targj = naj + (nai - naj - 1) / (nj - jp) + 1;
00156       int jend;
00157       for ( jend=jbegin; jend<iend; ++jend ) { 
00158         int mgs = atoms[order[jend]].migrationGroupSize;
00159         if (naj + mgs <= targj) naj += mgs;
00160         else break;
00161       }
00162 
00163 //CkPrintf("    Y %d %d (%d) %d\n", jbegin, jend, jend-jbegin, naj);
00164       std::sort(order+jbegin, order+jend, sortop_x(atoms));
00165       int kbegin = jbegin;
00166       for ( int kp=0; kp < nk; ++kp ) {
00167         int targk = nak + (naj - nak - 1) / (nk - kp) + 1;
00168         int kend;  
00169         for ( kend=kbegin; kend<jend; ++kend ) {
00170           int mgs = atoms[order[kend]].migrationGroupSize;
00171           if (nak + mgs <= targk) nak += mgs;
00172           else break;
00173 //CkPrintf("        atom %d %d %.2f\n", atoms[order[kend]].id, mgs,
00174 //                  atoms[order[kend]].position.x);
00175         }
00176 //CkPrintf("      X %d %d (%d) %d\n", kbegin, kend, kend-kbegin, nak);
00177         breaks[pid++] = kend;
00178         kbegin = kend;
00179       }
00180       jbegin = jend;
00181     }
00182     ibegin = iend;
00183   }
00184 
00185 }


Generated on 21 Sep 2020 for NAMD by  doxygen 1.6.1