Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

ComputeNonbondedInl.h File Reference

#include "ComputeNonbondedUtil.h"
#include "SimParameters.h"
#include "Node.h"
#include "Molecule.h"
#include "LJTable.h"
#include "ReductionMgr.h"
#include "ReserveArray.h"
#include "PressureProfile.h"

Go to the source code of this file.

Defines

#define restrict
#define NBPAIR   1
#define NBSELF   2
#define __TERNARY_ASSIGN(test, val0, val1)   ((test * val0) + ((1 - test) * val1))

Functions

int pairlist_from_pairlist (BigReal cutoff2, BigReal p_i_x, BigReal p_i_y, BigReal p_i_z, const CompAtom *p_j, const plint *list, int list_size, plint *newlist, BigReal r2_delta, BigReal *r2list)
void sortEntries_selectionSort (SortEntry *const se, const int seLen)
void sortEntries_bubbleSort (SortEntry *const se, const int seLen)
void sortEntries_mergeSort_v1 (SortEntry *&se, SortEntry *&buf, int seLen)
void sortEntries_mergeSort_v2 (SortEntry *&se, SortEntry *&buf, int seLen)


Define Documentation

#define __TERNARY_ASSIGN test,
val0,
val1   )     ((test * val0) + ((1 - test) * val1))
 

Referenced by sortEntries_mergeSort_v2().

#define NBPAIR   1
 

Definition at line 179 of file ComputeNonbondedInl.h.

#define NBSELF   2
 

Definition at line 180 of file ComputeNonbondedInl.h.

#define restrict
 

Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000 by The Board of Trustees of the University of Illinois. All rights reserved.

Definition at line 15 of file ComputeNonbondedInl.h.


Function Documentation

int pairlist_from_pairlist BigReal  cutoff2,
BigReal  p_i_x,
BigReal  p_i_y,
BigReal  p_i_z,
const CompAtom p_j,
const plint list,
int  list_size,
plint newlist,
BigReal  r2_delta,
BigReal r2list
[inline]
 

Definition at line 28 of file ComputeNonbondedInl.h.

References BigReal, j, p_j, plint, CompAtom::position, Vector::x, Vector::y, and Vector::z.

Referenced by SELF().

00032                                                                      {
00033   
00034   BigReal cutoff2_delta = cutoff2 + r2_delta;
00035   plint *nli = newlist;
00036   BigReal *r2i = r2list;
00037 
00038   if ( list_size <= 0) return 0;
00039 
00040   int g = 0;
00041 
00042 #ifndef SIMPLE_PAIRLIST
00043   //***************************************************************
00044   //* 4-way unrolled and software-pipelined 
00045   //***************************************************************
00046 
00047   int jout = 0;
00048   if ( list_size > 16) {
00049     // prefetch
00050     int jcur0 = list[g];
00051     int jcur1 = list[g + 1];
00052     int jcur2 = list[g + 2];
00053     int jcur3 = list[g + 3];
00054     
00055     int j0, j1, j2, j3;
00056     
00057     register  BigReal pj_x_0, pj_x_1, pj_x_2, pj_x_3; 
00058     register  BigReal pj_y_0, pj_y_1, pj_y_2, pj_y_3; 
00059     register  BigReal pj_z_0, pj_z_1, pj_z_2, pj_z_3; 
00060     
00061     register BigReal t_0, t_1, t_2, t_3, r2_0, r2_1, r2_2, r2_3;
00062     
00063     pj_x_0 = p_j[jcur0].position.x;
00064     pj_x_1 = p_j[jcur1].position.x;  
00065     pj_x_2 = p_j[jcur2].position.x;  
00066     pj_x_3 = p_j[jcur3].position.x;  
00067     pj_y_0 = p_j[jcur0].position.y; 
00068     pj_y_1 = p_j[jcur1].position.y;  
00069     pj_y_2 = p_j[jcur2].position.y;  
00070     pj_y_3 = p_j[jcur3].position.y;  
00071     pj_z_0 = p_j[jcur0].position.z; 
00072     pj_z_1 = p_j[jcur1].position.z;
00073     pj_z_2 = p_j[jcur2].position.z; 
00074     pj_z_3 = p_j[jcur3].position.z;
00075     
00076     for ( g = 4 ; g < list_size - 4; g += 4 ) {
00077       // compute 1d distance, 4-way parallel
00078       
00079       //Save the previous iterations values, gives more flexibility 
00080       //to the compiler to schedule the loads and the computation
00081       j0   =   jcur0;           j1   =   jcur1;
00082       j2   =   jcur2;           j3   =   jcur3;
00083       
00084       jcur0  =  list[g    ];    jcur1  =  list[g + 1];
00085       jcur2  =  list[g + 2];    jcur3  =  list[g + 3];
00086 
00087 #ifdef ARCH_POWERPC
00088       __dcbt ((void *) &p_j[jcur0]);
00089 #endif      
00090 
00091       //Compute X distance
00092       t_0   =  p_i_x - pj_x_0;   t_1   =  p_i_x - pj_x_1;
00093       t_2   =  p_i_x - pj_x_2;   t_3   =  p_i_x - pj_x_3;
00094       
00095       r2_0  =  t_0 * t_0 + r2_delta; 
00096       r2_1  =  t_1 * t_1 + r2_delta;
00097       r2_2  =  t_2 * t_2 + r2_delta;
00098       r2_3  =  t_3 * t_3 + r2_delta;
00099       
00100       //Compute y distance
00101       t_0    =  p_i_y - pj_y_0;   t_1    =  p_i_y - pj_y_1;
00102       t_2    =  p_i_y - pj_y_2;   t_3    =  p_i_y - pj_y_3;
00103       r2_0  +=  t_0 * t_0;        r2_1  +=  t_1 * t_1;
00104       r2_2  +=  t_2 * t_2;        r2_3  +=  t_3 * t_3;
00105       
00106       //compute z distance
00107       t_0    =  p_i_z - pj_z_0;   t_1    =  p_i_z - pj_z_1;
00108       t_2    =  p_i_z - pj_z_2;   t_3    =  p_i_z - pj_z_3;
00109       r2_0  +=  t_0 * t_0;        r2_1  +=  t_1 * t_1;
00110       r2_2  +=  t_2 * t_2;        r2_3  +=  t_3 * t_3;
00111       
00112       pj_x_0 = p_j[jcur0].position.x;
00113       pj_x_1 = p_j[jcur1].position.x;  
00114       pj_x_2 = p_j[jcur2].position.x;  
00115       pj_x_3 = p_j[jcur3].position.x;  
00116       pj_y_0 = p_j[jcur0].position.y; 
00117       pj_y_1 = p_j[jcur1].position.y;  
00118       pj_y_2 = p_j[jcur2].position.y;  
00119       pj_y_3 = p_j[jcur3].position.y;  
00120       pj_z_0 = p_j[jcur0].position.z; 
00121       pj_z_1 = p_j[jcur1].position.z;
00122       pj_z_2 = p_j[jcur2].position.z; 
00123       pj_z_3 = p_j[jcur3].position.z;
00124       
00125       bool test0, test1, test2, test3;
00126       
00127       test0 = ( r2_0   <   cutoff2_delta );
00128       test1 = ( r2_1   <   cutoff2_delta );
00129       test2 = ( r2_2   <   cutoff2_delta );
00130       test3 = ( r2_3   <   cutoff2_delta );
00131       
00132       int jout0, jout1, jout2, jout3;
00133 
00134       jout0 = jout;
00135       nli[ jout0 ]  = j0;         r2i[ jout0 ] = r2_0;
00136       jout += test0;              jout1 = jout;
00137       nli[ jout1 ]  = j1;         r2i[ jout1 ] = r2_1;
00138       jout += test1;              jout2 = jout;
00139       nli[ jout2 ]  = j2;         r2i[ jout2 ] = r2_2;
00140       jout += test2;              jout3 = jout;
00141       nli[ jout3 ]  = j3;         r2i[ jout3 ] = r2_3;
00142 
00143       jout += test3;
00144     }
00145     g -= 4;
00146   }
00147 
00148   nli += jout;
00149   r2i += jout;  
00150 #endif
00151 
00152   int j2 = list[g];
00153   BigReal p_j_x = p_j[j2].position.x;
00154   BigReal p_j_y = p_j[j2].position.y;
00155   BigReal p_j_z = p_j[j2].position.z;
00156   while ( g < list_size ) {
00157     int j = j2;
00158     j2 = list[++g];
00159     BigReal t2 = p_i_x - p_j_x;
00160     BigReal r2 = t2 * t2 + r2_delta;
00161     p_j_x = p_j[j2].position.x;
00162     t2 = p_i_y - p_j_y;
00163     r2 += t2 * t2;
00164     p_j_y = p_j[j2].position.y;
00165     t2 = p_i_z - p_j_z;
00166     r2 += t2 * t2;
00167     p_j_z = p_j[j2].position.z;
00168     if ( r2 <= cutoff2_delta ) {
00169       *nli= j; ++nli;
00170       *r2i = r2; ++r2i;
00171     }
00172   }
00173 
00174   return nli - newlist;
00175 }

void sortEntries_bubbleSort SortEntry *const   se,
const int  seLen
[inline]
 

Definition at line 221 of file ComputeNonbondedInl.h.

References BigReal, __sort_entry::index, SortEntry, and __sort_entry::sortValue.

Referenced by SELF().

00221                                                                           {
00222 
00223   register int keepSorting = 0;
00224 
00225   do {
00226 
00227     // Reset the keepSorting flag (assume no swaps will occur)
00228     keepSorting = 0;
00229 
00230     // Loop through the pairs and swap if needed
00231     register SortEntry* sortEntry1 = se;
00232     for (int i = 1; i < seLen; i++) {
00233 
00234       register SortEntry* sortEntry0 = sortEntry1;
00235       sortEntry1 = se + i;
00236       register BigReal sortEntry0_sortValue = sortEntry0->sortValue;
00237       register BigReal sortEntry1_sortValue = sortEntry1->sortValue;
00238 
00239       if (sortEntry0_sortValue > sortEntry1_sortValue) {
00240         register int sortEntry0_index = sortEntry0->index;
00241         register int sortEntry1_index = sortEntry1->index;
00242         sortEntry0->index = sortEntry1_index;
00243         sortEntry0->sortValue = sortEntry1_sortValue;
00244         sortEntry1->index = sortEntry0_index;
00245         sortEntry1->sortValue = sortEntry0_sortValue;
00246         keepSorting = 1;
00247       }
00248     }
00249 
00250   } while (keepSorting != 0);  // Loop again if at least one set of
00251                                //   elements was swapped.
00252 }

void sortEntries_mergeSort_v1 SortEntry *&  se,
SortEntry *&  buf,
int  seLen
[inline]
 

Setup pointers and counts for sublists in the pair. ///

Merge the sublists ///

Definition at line 258 of file ComputeNonbondedInl.h.

References BigReal, __sort_entry::index, SortEntry, and __sort_entry::sortValue.

Referenced by SELF().

00258                                                                                    {
00259 
00260   register SortEntry* srcArray = se;
00261   register SortEntry* dstArray = buf;
00262 
00263   // Start with each element being a separate list.  Start
00264   //   merging the "lists" into larger lists.
00265   register int subListSize = 1;
00266   while (subListSize < seLen) {
00267 
00268     // NOTE: This iteration consumes sublists of length
00269     //   subListSize and produces sublists of length
00270     //   (2*subListSize).  So, keep looping while the length of a
00271     //   single sorted sublist is not the size of the entire array.
00272 
00273     // Iterate through the lists, merging each consecutive pair of lists.
00274     register int firstListOffset = 0;
00275     while (firstListOffset < seLen) {
00276 
00278 
00279       register int numElements = min(2 * subListSize, seLen - firstListOffset);
00280       register int list0len;
00281       register int list1len;
00282       if (numElements > subListSize) {
00283         list0len = subListSize;                // First list full
00284         list1len = numElements - subListSize;  // 1+ elements in second list
00285       } else {
00286         list0len = numElements;                // 1+ elements in first list
00287         list1len = 0;                          // Zero elements in second list
00288       }
00289 
00290       register SortEntry* list0ptr = srcArray + firstListOffset;
00291       register SortEntry* list1ptr = list0ptr + subListSize;
00292       register SortEntry* dstptr = dstArray + firstListOffset;
00293 
00295 
00296       // While there are elements in both lists, pick from one
00297       while (list0len > 0 && list1len > 0) {
00298 
00299         register BigReal sortValue0 = list0ptr->sortValue;
00300         register BigReal sortValue1 = list1ptr->sortValue;
00301 
00302         if (sortValue0 < sortValue1) {  // choose first list (list0)
00303 
00304           // Copy the value from srcArray to dstArray
00305           register int index0 = list0ptr->index;
00306           dstptr->sortValue = sortValue0;
00307           dstptr->index = index0;
00308 
00309           // Move the pointers forward for the sublists
00310           dstptr++;
00311           list0ptr++;
00312           list0len--;
00313 
00314         } else {                        // choose second list (list1)
00315 
00316           // Copy the value from srcArray to dstArray
00317           register int index1 = list1ptr->index;
00318           dstptr->sortValue = sortValue1;
00319           dstptr->index = index1;
00320 
00321           // Move the pointers forward for the sublists
00322           dstptr++;
00323           list1ptr++;
00324           list1len--;
00325         }
00326 
00327       } // end while (list0len > 0 && list1len > 0)
00328 
00329       // NOTE: Either list0len or list1len is zero at this point
00330       //   so only one of the following loops should execute.
00331 
00332       // Drain remaining elements from the first list (list0)
00333       while (list0len > 0) {
00334 
00335         // Copy the value from srcArray to dstArray
00336         register BigReal sortValue0 = list0ptr->sortValue;
00337         register int index0 = list0ptr->index;
00338         dstptr->sortValue = sortValue0;
00339         dstptr->index = index0;
00340 
00341         // Move the pointers forward for the sublists
00342         dstptr++;
00343         list0ptr++;
00344         list0len--;
00345 
00346       } // end while (list0len > 0)
00347 
00348       // Drain remaining elements from the first list (list1)
00349       while (list1len > 0) {
00350 
00351         // Copy the value from srcArray to dstArray
00352         register BigReal sortValue1 = list1ptr->sortValue;
00353         register int index1 = list1ptr->index;
00354         dstptr->sortValue = sortValue1;
00355         dstptr->index = index1;
00356 
00357         // Move the pointers forward for the sublists
00358         dstptr++;
00359         list1ptr++;
00360         list1len--;
00361 
00362       } // end while (list1len > 0)
00363 
00364       // Move forward to the next pair of sub-lists
00365       firstListOffset += (2 * subListSize);
00366 
00367     } // end while (firstListOffset < seLen) {
00368 
00369     // Swap the dstArray and srcArray pointers
00370     register SortEntry* tmpPtr = dstArray;
00371     dstArray = srcArray;
00372     srcArray = tmpPtr;
00373 
00374     // Double the subListSize
00375     subListSize <<= 1;
00376 
00377   }  // end while (subListSize < seLen)
00378 
00379   // Set the sort values pointers (NOTE: srcArray and dstArray are
00380   //   swapped at the end of each iteration of the merge sort outer-loop).
00381   buf = dstArray;
00382   se = srcArray;
00383 }

void sortEntries_mergeSort_v2 SortEntry *&  se,
SortEntry *&  buf,
int  seLen
[inline]
 

Setup pointers and counts for sublists in the pair. ///

Merge the sublists ///

Definition at line 389 of file ComputeNonbondedInl.h.

References __TERNARY_ASSIGN, BigReal, __sort_entry::index, SortEntry, and __sort_entry::sortValue.

Referenced by SELF().

00389                                                                                    {
00390 
00391   // NOTE: This macro "returns" either val0 (if test == 0) or val1 (if
00392   // test == 1).  It expects test to be either 0 or 1 (no other values).
00393   #define __TERNARY_ASSIGN(test, val0, val1)   ((test * val0) + ((1 - test) * val1))
00394 
00395   register SortEntry* srcArray = se;
00396   register SortEntry* dstArray = buf;
00397 
00398   // Start with each element being a separate list.  Start
00399   //   merging the "lists" into larger lists.
00400   register int subListSize = 1;
00401   while (subListSize < seLen) {
00402 
00403     // NOTE: This iteration consumes sublists of length
00404     //   subListSize and produces sublists of length
00405     //   (2*subListSize).  So, keep looping while the length of a
00406     //   single sorted sublist is not the size of the entire array.
00407 
00408     // Iterate through the lists, merging each consecutive pair of lists.
00409     register int firstListOffset = 0;
00410     while (firstListOffset < seLen) {
00411 
00413 
00414       // Calculate the number of elements for both sublists...
00415       //   min(2 * subListSize, seLen - firstListOffset);
00416       register int numElements;
00417       {
00418         register int numElements_val0 = 2 * subListSize;
00419         register int numElements_val1 = seLen - firstListOffset;
00420         register bool numElements_test = (numElements_val0 < numElements_val1);
00421         numElements = __TERNARY_ASSIGN(numElements_test, numElements_val0, numElements_val1);
00422       }
00423 
00424       // Setup the pointers for the source and destination arrays
00425       register SortEntry* dstptr = dstArray + firstListOffset;    // destination array pointer
00426       register SortEntry* list0ptr = srcArray + firstListOffset;  // source list 0 pointer
00427       register SortEntry* list1ptr = list0ptr + subListSize;      // source list 1 pointer
00428       register SortEntry* list0ptr_end;  // pointer to end of source list0's elements (element after last)
00429       register SortEntry* list1ptr_end;  // pointer to end of source list1's elements (element after last)
00430       {
00431         register bool lenTest = (numElements > subListSize);
00432         register int list0len_val0 = subListSize;
00433         register int list1len_val0 = numElements - subListSize;
00434         register int list0len_val1 = numElements;  // NOTE: list1len_val1 = 0
00435         register int list0len = __TERNARY_ASSIGN(lenTest, list0len_val0, list0len_val1);
00436         register int list1len = __TERNARY_ASSIGN(lenTest, list1len_val0, 0);
00437         list0ptr_end = list0ptr + list0len;
00438         list1ptr_end = list1ptr + list1len;
00439       }
00440 
00441       // The firstListOffset variable won't be used again until the next
00442       //   iteration, so go ahead and update it now...
00443       //   Move forward to the next pair of sub-lists
00444       firstListOffset += (2 * subListSize);
00445 
00447 
00448       // Pre-load values from both source arrays
00449       register BigReal sortValue0 = list0ptr->sortValue;
00450       register BigReal sortValue1 = list1ptr->sortValue;
00451       register int index0 = list0ptr->index;
00452       register int index1 = list1ptr->index;
00453 
00454       // While both lists have at least one element in them, compare the
00455       //   heads of each list and place the smaller of the two in the
00456       //   destination array.
00457       while (list0ptr < list0ptr_end && list1ptr < list1ptr_end) {
00458 
00459         // Compare the values
00460         register bool test = (sortValue0 < sortValue1);
00461 
00462         // Place the "winner" in the destination array
00463         dstptr->sortValue = __TERNARY_ASSIGN(test, sortValue0, sortValue1);
00464         dstptr->index = __TERNARY_ASSIGN(test, index0, index1);
00465         dstptr++;
00466 
00467         // Update the pointers
00468         list0ptr += __TERNARY_ASSIGN(test, 1, 0);
00469         list1ptr += __TERNARY_ASSIGN(test, 0, 1);
00470 
00471         // Refill the sortValue and index register
00472         // NOTE: These memory locations are likely to be in cache
00473         sortValue0 = list0ptr->sortValue;
00474         sortValue1 = list1ptr->sortValue;
00475         index0 = list0ptr->index;
00476         index1 = list1ptr->index;
00477 
00478       } // end while (list0ptr < list0ptr_end && list1ptr < list1ptr_end)
00479 
00480       // NOTE: At this point, at least one of the lists is empty so no
00481       //   more than one of the loops will be executed.
00482 
00483       // Drain the remaining elements from list0
00484       while (list0ptr < list0ptr_end) {
00485 
00486         // Place the value into the destination array
00487         dstptr->sortValue = sortValue0;
00488         dstptr->index = index0;
00489         dstptr++;
00490 
00491         // Load the next entry in list0
00492         list0ptr++;
00493         sortValue0 = list0ptr->sortValue;
00494         index0 = list0ptr->index;
00495 
00496       } // end while (list0ptr < list0ptr_end)
00497 
00498       // Drain the remaining elements from list1
00499       while (list1ptr < list1ptr_end) {
00500 
00501         // Place the value into the destination array
00502         dstptr->sortValue = sortValue1;
00503         dstptr->index = index1;
00504         dstptr++;
00505 
00506         // Load the next entry in list1
00507         list1ptr++;
00508         sortValue1 = list1ptr->sortValue;
00509         index1 = list1ptr->index;
00510 
00511       } // end while (list1ptr < list1ptr_end)
00512 
00513     } // end while (firstListOffset < seLen) {
00514 
00515     // Swap the dstArray and srcArray pointers
00516     register SortEntry* tmpPtr = dstArray;
00517     dstArray = srcArray;
00518     srcArray = tmpPtr;
00519 
00520     // Double the subListSize
00521     subListSize <<= 1;
00522 
00523   }  // end while (subListSize < seLen)
00524 
00525   // Set the sort values pointers (NOTE: srcArray and dstArray are
00526   //   swapped at the end of each iteration of the merge sort outer-loop).
00527   buf = dstArray;
00528   se = srcArray;
00529 
00530   #undef __TERNARY_ASSIGN
00531 }

void sortEntries_selectionSort SortEntry *const   se,
const int  seLen
[inline]
 

Definition at line 187 of file ComputeNonbondedInl.h.

References BigReal, __sort_entry::index, j, SortEntry, and __sort_entry::sortValue.

Referenced by SELF().

00187                                                                              {
00188 
00189   register int i;
00190 
00191   for (i = 0; i < seLen; i++) {
00192 
00193     // Search through the remaining elements, finding the lowest
00194     //   value, and then swap it with the first remaining element.
00195     //   Start by assuming the first element is the smallest.
00196     register int smallestIndex = i;
00197     register BigReal smallestValue = se[i].sortValue;
00198     register int j;
00199     for (j = i + 1; j < seLen; j++) {
00200       register BigReal currentValue = se[j].sortValue;
00201       if (currentValue < smallestValue) {
00202         smallestIndex = j;
00203         smallestValue = currentValue;
00204       }
00205     }
00206 
00207     // Swap the first remaining element with the smallest element
00208     if (smallestIndex != i) {
00209       register SortEntry* entryA = se + i;
00210       register SortEntry* entryB = se + smallestIndex;
00211       register unsigned int tmpIndex = entryA->index;
00212       register BigReal tmpSortValue = entryA->sortValue;
00213       entryA->index = entryB->index;
00214       entryA->sortValue = entryB->sortValue;
00215       entryB->index = tmpIndex;
00216       entryB->sortValue = tmpSortValue;
00217     }
00218   }
00219 }


Generated on Tue Nov 24 04:07:46 2009 for NAMD by  doxygen 1.3.9.1