/* Compresses all the neighbor lists into a single message and sends to the master node * * arguments: * neighbors: The set of neighbor lists that are being sent * particles: The spatially decomposed particle information * my_rank: Rank of the node * nvlists: The arrays which mark where each list ends */ void send_neighborlists(Neighbor** neighbors, Particle* particles[XDiv][YDiv][ZDiv], int my_rank, int* nvlists){ #pragma omp single { int x, y, z, i; int j = 0; int sum[NUM_LISTS]; // Allocate the message array, which is used to send the lists int size = num_neighbors * (n / num_work_nodes); int * message = malloc(sizeof(int) * size); int k = 0; int index = 0; int temp_index; // Iterate through all the particle arrays, and for each particle in the blocks // copy its neighbor list to the message array for (x = node_boundries[my_rank][0]; x <= node_boundries[my_rank][1]; ++x) { for (y = node_boundries[my_rank][2]; y <= node_boundries[my_rank][3]; ++y) { for (z = node_boundries[my_rank][4]; z <= node_boundries[my_rank][5]; ++z) { for (i = 0; i < block_size; ++i) { if (particles[x][y][z][i].index != -1) { temp_index = particles[x][y][z][i].index; message[index] = -1; index++; message[index] = temp_index; index++; //The sum array is used to calculate the nvlst array, which is // where each list ends for (j = 0; j < NUM_LISTS; ++j){ sum[j] = 0; } for (j = 0; j < num_neighbors; ++j) { if(neighbors[k][j].index != -1) { sum[neighbors[k][j].list - 1] += 1; message[index] = neighbors[k][j].index; index++; } } for (j = 0; j < NUM_LISTS; ++j){ if (j != 0) sum[j] = sum[j-1] + sum[j]; nvlists[j*n + pIndex(temp_index)] = sum[j]; } } k++; } } } } message[index] = -2; index++; MPI_Send(message, index , MPI_INT, 0, 0, MPI_COMM_WORLD); MPI_Send(nvlists, NUM_LISTS * n, MPI_INT, 0, 0, MPI_COMM_WORLD); free(message); } }
/* * Receives the fully built neighbor lists from work nodes and decompresses the message * * arguments: * neighbors: The location that the completed neighbor lists will be stored * nvlst: The number of particles in each list * n: The total number of particles in the system */ void receive_neighborlists(int* neighbors, int* nvlst, int n){ int i, j, k, x, y, z, tag; int index, array_index; int size = num_neighbors * (n / num_work_nodes); int* message = malloc(sizeof(int) * size); int* nvlst_temp = malloc(sizeof(int) * n * NUM_LISTS); for (i = 0; i < num_work_nodes; ++i){ MPI_Recv(message, size, MPI_INT, i+1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(nvlst_temp, NUM_LISTS * n, MPI_INT, i+1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); k = 0; while (k < size) { // End of Message if (message[k] == -2) { break; } // End of single neighborlist else if (message[k] == -1) { ++k; if (k < size) index = message[k]; ++k; } // Copy nvlst for the particles each work node was responsible for for (j = 0; j < NUM_LISTS; ++j){ nvlst[j*n + pIndex(index)] = nvlst_temp[j*n + pIndex(index)]; } //Copy the neighbor list j = 0; while(message[k] != -1 && message[k] != -2 && j < num_neighbors && k < size){ if (j >= num_neighbors) printf("Exceeded size of neighborlist. Increse maxvlst"); array_index = pIndex(index) * num_neighbors + j ; neighbors[array_index] = message[k]; ++k; ++j; } } } free(message); free(nvlst_temp); }
int CGitIndexFileMap::LoadIndex(const CString &gitdir) { SHARED_INDEX_PTR pIndex(new CGitIndexList); if (pIndex->ReadIndex(g_AdminDirMap.GetAdminDir(gitdir))) return -1; this->SafeSet(gitdir, pIndex); return 0; }
int CGitIndexFileMap::LoadIndex(const CString &gitdir) { try { SHARED_INDEX_PTR pIndex(new CGitIndexList); if(pIndex->ReadIndex(gitdir + _T("\\.git\\index"))) return -1; this->SafeSet(gitdir, pIndex); }catch(...) { return -1; } return 0; }
/* * Organize the particle location information in every iteration past the initial * * arguments: * x_coords_new: The x coordinates of the particles * y_coords_new: The y coordinates of the particles * z_coords_new: The z coordinates of the particles * n: The number of particles * indexes(OUT): The number of particles in each block */ void organize_data_new(double* x_coords_new, double* y_coords_new, double* z_coords_new, int n, int indexes[XDiv][YDiv][ZDiv]){ //Iterate through blocks, update each location. Move between blocks if necessary int i, j, x, y, z; int xnew, ynew, znew; int index; Particle* p; // Mark all particles as not having moved to reset the previous iteration's information for (x = 0; x < XDiv; ++x) { for (y = 0; y < YDiv; ++y) { for (z = 0; z < ZDiv; ++z){ for (i = 0; i < block_size; ++i) { particles[x][y][z][i].moved = 0; } } } } // Instead of placing particles in blocks, this goes through each particle already in a block // updates its location information, and moves it between blocks if necessary for (x = 0; x < XDiv; ++x) { for (y = 0; y < YDiv; ++y) { for (z = 0; z < ZDiv; ++z) { for (i = 0; i < block_size; ++i) { p = &particles[x][y][z][i]; if (p->index != -1 && p->moved != 1){ index = pIndex(p->index); image_(&x_coords_new[index], &y_coords_new[index], &z_coords_new[index]); xnew = (x_coords_new[index] + offsetx)/WIDTH_X * XDiv; ynew = (y_coords_new[index] + offsety)/WIDTH_Y * YDiv; znew = (z_coords_new[index] + offsetz)/WIDTH_Z * ZDiv; if (x != xnew || y != ynew || z != znew){ //Find a new empty location for the particle for (j = 0; j < block_size; ++j) { if (particles[xnew][ynew][znew][j].index == -1) break; } particles[xnew][ynew][znew][j] = particles[x][y][z][i]; particles[xnew][ynew][znew][j].moved = 1; particles[x][y][z][i].index = -1; p = &particles[xnew][ynew][znew][j]; } p->pos[0] = x_coords_new[index]; p->pos[1] = y_coords_new[index]; p->pos[2] = z_coords_new[index]; double xDif = p->pos[0] - p->oldPos[0]; //The difference between the current double yDif = p->pos[1] - p->oldPos[1]; //position and the position the last double zDif = p->pos[2] - p->oldPos[2]; //time that particle's list was rebuilt if ((xDif*xDif) + (yDif* yDif) + (zDif * zDif) > MOVE_THRESHOLD_2) { p->moved = 1; } if (p->moved == 1) { p->oldPos[0] = x_coords_new[index]; p->oldPos[1] = y_coords_new[index]; p->oldPos[2] = z_coords_new[index]; } } } } } } }