Example #1
0
/**
* 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, &centers[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, &centers[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]();
}
Example #2
0
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);
    }
}