void deallocate_tree(node_t* node) { if ((node == NULL) || (node->type == 0)) return; else { deallocate_tree(node->cell.childs[0]); deallocate_tree(node->cell.childs[1]); deallocate_tree(node->cell.childs[2]); deallocate_tree(node->cell.childs[3]); deallocate_tree(node->cell.childs[4]); deallocate_tree(node->cell.childs[5]); deallocate_tree(node->cell.childs[6]); deallocate_tree(node->cell.childs[7]); free(node); } }
void deallocate_tree(struct Node *tree) { if (!tree) return; deallocate_tree(tree->one); deallocate_tree(tree->zero); Free(tree); }
int main(int argc, char* argv[]) { int* bodies_off; int* n_bodies_split; int n_local_bodies; const MPI_Comm comm = MPI_COMM_WORLD; FILE *inputf; FILE *outputf; double clockStart, clockEnd; int rc, n_proc, rank; rc = MPI_Init(&argc, &argv); if (rc != MPI_SUCCESS) { puts("MPI_Init failed"); exit(-1); } MPI_Comm_size(comm, &n_proc); MPI_Comm_rank(comm, &rank); //creazione datatype per mpi! MPI_Datatype bodytype; MPI_Datatype type[6] = { MPI_LB, MPI_DOUBLE, MPI_DOUBLE, MPI_DOUBLE, MPI_DOUBLE, MPI_UB }; int block_len[6] = {1, 1, 3, 3, 3, 1}; MPI_Aint disp[6]; leaf_t example[2]; MPI_Get_address(&example[0], &disp[0]); MPI_Get_address(&(example[0].mass), &disp[1]); MPI_Get_address(&(example[0].pos), &disp[2]); MPI_Get_address(&(example[0].vel), &disp[3]); MPI_Get_address(&(example[0].acc), &disp[4]); MPI_Get_address(&(example[1].acc), &disp[5]); // int i; // for(i = 6; i >= 0; --i) // disp[i] -= disp[0]; disp[1] = disp[1] - disp[0]; disp[2] = disp[2] - disp[0]; disp[3] = disp[3] - disp[0]; disp[4] = disp[4] - disp[0]; disp[5] = disp[5] - disp[0]; MPI_Type_create_struct(6, block_len, disp, type, &bodytype); MPI_Type_commit(&bodytype); bodies_off = malloc((n_proc + 1) * sizeof(int)); n_bodies_split = malloc((n_proc) * sizeof(int)); bodies = malloc(nbodies * sizeof(node_t*)); leafs = malloc(nbodies * sizeof(leaf_t)); char* inputfile = argv[1]; inputf = fopen(inputfile, "r"); if (inputf == NULL) { printf("impossibile leggere da file"); exit(1); } fscanf(inputf, "%d", &nbodies); fscanf(inputf, "%d", &steps); fscanf(inputf, "%lf", &dt); fscanf(inputf, "%lf", &eps); fscanf(inputf, "%lf", &tol); fclose(inputf); if (rank == 0) { int i; create_bodies(); quicksort(0, nbodies - 1); // bublesort(); // int i = 0; // for (i = 0; i < nbodies; i++) { // printf("%lf, %lf, %lf \n", bodies[i]->pos[0], bodies[i]->pos[1], // bodies[i]->pos[2]); // } n_local_bodies = nbodies / n_proc; //split delle particelle secondo shark & fish // split_bodies(n_proc, bodies_off, n_bodies_split); // n_local_bodies = n_bodies_split[rank]; // // MPI_Bcast(n_bodies_split, n_proc, MPI_INT, 0, comm); MPI_Bcast(leafs, nbodies, bodytype, 0, comm); dthf = 0.5 * dt; epssq = eps * eps; itolsq = 1.0 / (tol * tol); clockStart = MPI_Wtime(); int step = 0; root = NULL; for (step = 0; step < steps; step++) { compute_center_and_diameter(); root = malloc(sizeof(struct node_t)); // "new" is like "malloc" double mass_root = 0.0; root->type = 1; root->mass = &mass_root; root->pos = center; root->cell.childs[0] = NULL; root->cell.childs[1] = NULL; root->cell.childs[2] = NULL; root->cell.childs[3] = NULL; root->cell.childs[4] = NULL; root->cell.childs[5] = NULL; root->cell.childs[6] = NULL; root->cell.childs[7] = NULL; double radius = diameter * 0.5; int i = 0; for (i = 0; i < nbodies; i++) { insert(root, bodies[i], radius); // questo è il modo per passare i dati per riferimento... cioè mandare l'indirizzo della struttura puntata dal puntatore } curr = 0; compute_center_of_mass(&(*root)); for (i = 0; i < n_local_bodies; i++) { compute_force(&(*root), &(*bodies[i]), diameter, step); } // for (i = 0; i < nbodies; i++) { // } deallocate_tree(root); //inserire all gather MPI_Allgather(leafs, n_local_bodies, bodytype, leafs, n_local_bodies, bodytype, comm); for (i = 0; i < nbodies; i++) { advance(&(*bodies[i])); } // int p = 0; // for (p = 0; p < nbodies; p++) // printf("%lf, %lf, %lf \n", bodies[p]->pos[0], bodies[p]->pos[1], // bodies[p]->pos[2]); // printf("*************************************** \n"); } // int i = 0; // dopo l'esecuzione!! // int proc_rec = 1; // while (proc_rec < n_proc) { // MPI_Status status; // int proc_rank; // int cap = nbodies / n_proc; // node_t temp[cap]; // MPI_Recv(temp, cap, bodytype, MPI_ANY_SOURCE, MPI_ANY_TAG, comm, // &status); // proc_rank = status.MPI_SOURCE; // // int idx = 0; // for (idx = proc_rec * (cap); idx < cap; idx++) // *bodies[idx] = temp[idx]; // proc_rec++; // } clockEnd = MPI_Wtime(); if (nbodies == 16384) { system("echo 'Host:' `hostname` >> output16384 "); outputf = fopen("output16384", "a"); fprintf(outputf, "Tempo di esecuzione: %lf \n", clockEnd - clockStart); for (i = 0; i < nbodies; i++) { fprintf(outputf, "%lf, %lf, %lf \n", bodies[i]->pos[0], bodies[i]->pos[1], bodies[i]->pos[2]); } } else if (nbodies == 32768) { system("echo 'Host:' `hostname` >> output32768 "); outputf = fopen("output32768", "a"); fprintf(outputf, "Tempo di esecuzione: %lf \n", clockEnd - clockStart); for (i = 0; i < nbodies; i++) { fprintf(outputf, "%lf, %lf, %lf \n", bodies[i]->pos[0], bodies[i]->pos[1], bodies[i]->pos[2]); } } else if (nbodies == 65536) { system("echo 'Host:' `hostname` >> output65536 "); outputf = fopen("output65536", "a"); fprintf(outputf, "Tempo di esecuzione: %lf \n", clockEnd - clockStart); for (i = 0; i < nbodies; i++) { fprintf(outputf, "%lf, %lf, %lf \n", bodies[i]->pos[0], bodies[i]->pos[1], bodies[i]->pos[2]); } } else { system("echo 'Host:' `hostname` >> output "); outputf = fopen("output", "a"); fprintf(outputf, "Tempo di esecuzione: %lf \n", clockEnd - clockStart); for (i = 0; i < nbodies; i++) { fprintf(outputf, "%lf, %lf, %lf \n", bodies[i]->pos[0], bodies[i]->pos[1], bodies[i]->pos[2]); } } fflush(outputf); fclose(outputf); printf("Esecuzione completata\n"); } else { int low = 1, up = 0; int i; dthf = 0.5 * dt; epssq = eps * eps; itolsq = 1.0 / (tol * tol); // if (PAPI_library_init(PAPI_VER_CURRENT) != PAPI_VER_CURRENT) { // printf("Inizializzazione della libreria di papi fallita \n"); // exit(1); // } // // if (PAPI_create_eventset(&event_set) != PAPI_OK) { // printf("E' andata a male la creazione dell'eventSet \n"); // exit(1); // } // // if (PAPI_add_events(event_set, events, 2) != PAPI_OK) { // printf("E' andata a male l'aggiunta degli eventi\n"); // exit(1); // } n_local_bodies = nbodies / n_proc; MPI_Bcast(leafs, nbodies, bodytype, 0, comm); int step = 0; root = NULL; low += (rank * n_local_bodies); up = low + n_local_bodies; // PAPI_start(event_set); // clockStart = PAPI_get_real_usec(); for (step = 0; step < steps; step++) { compute_center_and_diameter(); root = malloc(sizeof(struct node_t)); // "new" is like "malloc" root->type = 1; *(root->mass) = 0.0; root->pos = center; root->cell.childs[0] = NULL; root->cell.childs[1] = NULL; root->cell.childs[2] = NULL; root->cell.childs[3] = NULL; root->cell.childs[4] = NULL; root->cell.childs[5] = NULL; root->cell.childs[6] = NULL; root->cell.childs[7] = NULL; double radius = diameter * 0.5; for (i = 0; i < nbodies; i++) { bodies[i] = malloc(sizeof(node_t)); bodies[i]->cell.leaf = &leafs[i]; bodies[i]->mass = &leafs[i].mass; bodies[i]->pos = leafs[i].pos; insert(&(*root), &(*bodies[i]), radius); // questo è il modo per passare i dati per riferimento... cioè mandare l'indirizzo della struttura puntata dal puntatore } curr = 0; compute_center_of_mass(&(*root)); for (i = low; i < up; i++) { compute_force(&(*root), &(*bodies[i]), diameter, step); } // for (i = 0; i < nbodies; i++) { // } deallocate_tree(root); local_leafs = &leafs[low]; //inserire all_gather MPI_Allgather(local_leafs, up - low, bodytype, leafs, up - low, bodytype, comm); for (i = 0; i < nbodies; i++) { advance(&(*bodies[i])); } // int p = 0; // for (p = 0; p < nbodies; p++) // printf("%lf, %lf, %lf \n", bodies[p]->pos[0], bodies[p]->pos[1], // bodies[p]->pos[2]); // printf("*************************************** \n"); } // clockEnd = PAPI_get_real_usec(); // PAPI_stop(event_set, values); // int i = 0; // MPI_Send(bodies[low], up - low + 1, bodytype, 0, MPI_ANY_TAG, comm); } MPI_Finalize(); return 0; }