Download User Guide - Scientific Computing Associates
Transcript
Molecular Dynamics Finish initialization. return; } After performing the same initial setup steps as the sequential version, the parallel version of nb_energy_setup places some global data in tuple space. The majority of the code shown in this routine is concerned with dividing the work up among the worker processes. The tasks created here define the range of the data each worker is responsible for. This represents a somewhat different technique from the usual master/worker scenario. In the latter, the work is divided into tasks which are independent of any particular worker, and each worker grabs a task when it needs one. Here, the total work is divided among the workers at the beginning of the calculation; the work each worker does is essentially part of its structure—in this case, a function of its worker ID number. This technique of dividing the problem space into discrete chunks and assigning each to one worker is known as domain decomposition. The parameters calculated here and communicated to each worker via tuple space will be used in both the summing of special charges done in the setup phase (with results collected at the end of this routine), and in the actual nonbonded interactions computation later in the program. The scheme for dividing the work here is somewhat complex, but it is designed to ensure good load balancing among the worker processes—this is always a concern when a domain decomposition approach is taken. For a molecular dynamics calculation, the total number of nonbonded interactions for an N-atom molecule is approximately N*(N-1)/2, and so we want each worker to do about (N*(N-1)/2) / num_workers of them. If there are N atoms, there are N2 possible interactions, but we throw out pairs where an atom is interacting with itself. The factor of 1/2 comes from the fact that the interactions are symmetric (A’s effect on B is equivalent to B’s effect on A) and thus only need to be computed once. We should also remove bonded pairs, but if this number is small compared to the total number of interactions, then our formula is a reasonable approximation to the ideal number of interactions per worker. In some cases, the total work can just be divided as evenly as possible among the workers. Here, we might like to just give each worker the number of interactions we computed above, correcting the last worker’s amount for any remainder and other integer rounding we had to do. However, the interaction pairs are actually stored as rows in a lower triangular matrix (a matrix with all of its non-zero elements on or below the diagonal), and for maximal efficiency, we want to give only complete rows of the matrix to each worker. Given this constraint, it is necessary to figure out how many rows to give each worker so that the number of elements each one gets comes out about the same (and close to the target number). To do so, the program uses the fact that there are I non-zero elements in row I of a lower triangular matrix, and assigns consecutive rows to each successive workers until the number of elements it has exceeds the target number, or until all the rows are gone. This Linda User Guide 91