/** * This function * @param * nbElemPerNode : Array of number of elements, per octree node * @param * firstElemAdress : Array of Indexes. * Gives the index(address) first element's data in the Id's array fmmData%elem, per octree node. * @param * nbSonsPerNode : Array of number of sons, per octree node * @param * firstSonId : Array of number of first son Id, per octree node * @param * nodeOwners : Array of responsible mpi ranks, per octree node. (From 1 to nbRanks, Fortran's style) * The Result of the load balancing is read here. * @param * nodeCenters : Array of octree node centers * @param * endlev : Array of last octree node id, per octree level * @param * nbLevels : Number of Octree levels * @param * maxEdge : Edge of the first octree node. (the biggest) * @param *LBstrategy : integer used to choose the load balancing strategy */ void fmm_load_balance_( i64 * nbElemPerNode, i64 * firstElemAdress, i64 * nbSonsPerNode, i64 * firstSonId, i64 * nodeOwners, double * nodeCenters, i64 * endlev, i64 * nbLevels, double * maxEdge, int * LBstrategy) { // MPI parameters int size; MPI_Comm_size(MPI_COMM_WORLD, &size); int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); // create Particles vec3D center(nodeCenters[0], nodeCenters[1], nodeCenters[2]); scale(center); Particles p; p.setAttributes(0,nbElemPerNode[0],*maxEdge, center); int nbElements = nbElemPerNode[0]; p.setNewCoordinates(elements, nbElements); p.scale(); // creatre Octree Node<Particles> * octree = nullptr; octree = new Node<Particles>(p); octree -> read_octree(nbElemPerNode, firstElemAdress, nbSonsPerNode, firstSonId, nodeCenters); // Octree useful characteristics int height = (*nbLevels) - 1; int nbLeaves = endlev[height] - endlev[height-1]; int firstLeave = endlev[height-1]; // endlev[height-1] +1(next node) -1(F to C) int firstElem = 0; int lastElem = nbElemPerNode[0]-1; int nbNodes = endlev[height]*3; double * centers = new double[nbNodes]; // Load Balancing useful parameters decompo nb1ers(size); // Load Balance LB_Base * LBB = nullptr; switch (*LBstrategy) { case MORTON_MPI_SYNC : cout << "*** ----- MORTON -----" << endl; LBB = new LoadBalancer<Particles, MortonSyncMPI>(octree, nb1ers, 0, 0, firstElem, lastElem, *maxEdge, center, nullptr, nullptr/*centers*/, nodeOwners, 0); break; case HIST_APPROX : cout << "*** ----- KD TREE -----" << endl; // Get a copy of the octree centers, scale them and apply load balancing strategy copyAndScaleArray(nodeCenters, centers, nbNodes); LBB = new LoadBalancer<Particles, HistApprox>(octree, nb1ers, 0, 0, firstElem, lastElem, *maxEdge, center, nullptr, ¢ers[firstLeave*3], &nodeOwners[firstLeave], nbLeaves); break; case HIST_APPROX_X : cout << "*** ----- SAUCISONNAGE EN X -----" << endl; // Get a copy of the octree centers, scale them and apply load balancing strategy copyAndScaleArray(nodeCenters, centers, nbNodes); // test rapide - saucissonnage en X cout << "Decomposition has been modified to : " << endl; nb1ers._list.resize(1); nb1ers._list[0] = size; nb1ers.display(); LBB = new LoadBalancer<Particles, HistApprox>(octree, nb1ers, 0, 0, firstElem, lastElem, *maxEdge, center, nullptr, ¢ers[firstLeave*3], &nodeOwners[firstLeave], nbLeaves); break; default : cerr << "No identified Load Balancing strategy" << endl; exit(0); } LBB->run(); delete Particles::_coordinates; cout << "---- Load Balancing ----> TERMINATED !" <<endl; int * counters = new int[size + 1](); }
void FMM_load_balance(string file, int nbParticles, double dist, double tolerance, double maxEdge, int LBStrategy) { int size; MPI_Comm_size(MPI_COMM_WORLD,&size); decompo nb1ers(size); int first = 0; int last = nbParticles-1; vec3D center(0,0,0); Node<Particles> * treeHead = nullptr; Gaspi_communicator * gComm = nullptr; // tree creation Particles p; if ( LBStrategy == HIST_EXACT || LBStrategy == HIST_APPROX || LBStrategy == MORTON_MPI_SYNC) { p.loadCoordinatesASCII(nbParticles, file); } else { gComm = new Gaspi_communicator(512, nbParticles); p.loadCoordinatesASCII(nbParticles, file, gComm); } p.scale(); treeHead = new Node<Particles>(p); // Node Owners array i64 * nodeOwners = nullptr; // Load Balancing LB_Base * LBB = nullptr; switch (LBStrategy) { case HIST_EXACT : cout <<"--> Exact Histograms" << endl; LBB = new LoadBalancer<Particles, HistExact> (treeHead, nb1ers, dist, tolerance, first, last, maxEdge, center, gComm, nullptr, nodeOwners, 0); LBB->run(); break; case HIST_APPROX : cout <<"--> Approx Histograms" << endl; LBB = new LoadBalancer<Particles, HistApprox> (treeHead, nb1ers, dist, tolerance, first, last, maxEdge, center, gComm, nullptr, nodeOwners, 0); LBB->run(); break; case MORTON_MPI_SYNC : cout <<"--> Morton DFS, with tolerance : " << tolerance << endl; LBB = new LoadBalancer<Particles, MortonSyncMPI>(treeHead, nb1ers, dist, tolerance, first, last, maxEdge, center, gComm, nullptr, nodeOwners, 0); LBB->run(); break; case MORTON_GASPI_ASYNC : cout <<"--> Morton DFS Async, with tolerance : " << tolerance << endl; LBB = new LoadBalancer<Particles, MortonAsyncGASPI>(treeHead, nb1ers, dist, tolerance, first, last, maxEdge, center, gComm, nullptr, nodeOwners, 0); LBB->run(); break; default : cerr << "No load balancing strategy detected !"; exit(5); } }