https://github.com/N-BodyShop/changa
Raw File
Tip revision: c6335b7cc4d17bacde16b994abc4285af92cdb65 authored by Harshitha on 09 May 2014, 19:42:20 UTC
Change the tree build to use splitter keys given by DD instead sending the key of the first and the last particle. This is to make the tree build process scalable.
Tip revision: c6335b7
MapStructures.h
#ifndef _MAP_STRUCTURES_H_
#define _MAP_STRUCTURES_H_
///
/// @file MapStructures.h
/// Data structures for spacially aware load balancing.
///
#include <iostream>

#include "Vector3D.h"
#include "TaggedVector3D.h"
#include "OrientedBox.h"
using namespace std;

#define XDIM 0
#define YDIM 1
#define ZDIM 2
#define NDIMS 3

#define LEFT_PARTITION 0
#define RIGHT_PARTITION 1
#define INVALID_PARTITION -1

template <class T>
class Volume{
	
  public:
  T lesser[3];          // lesser corner
  T greater[3];         // greater corner 
  
  void halve(int whichAxis, Volume<T> &secondhalf);
  void split(int whichAxis, T *where, Volume<T> &secondhalf);
  int decideSplitAxis();

  Volume(){}
  Volume(T *l, T *g){
    for (int i= 0; i < 3; i++){
     lesser[i] = l[i];
     greater[i] = g[i];
    }
  }
};

class Cluster{
  public:
  int load;     // total load induced by this cluster
  int proc;     // which processor this cluster will be assigned to - one cluster per processor
  Volume <int>* partition;      // the lowest level process partition that this cluster belongs to
  float centroid[3];    // cluster centroid - calculated like center of mass, with unit mass for each participating TP. FIXME - refine
  int count;    // this cluster comprises 'count' tree pieces

  CkVec<int> tps;   // to check metis efficacy only. remove later on FIXME

  Cluster& operator= (Cluster& in){
    load = in.load;
    proc = in.proc;
    partition = in.partition;
    count = in.count;
    for(int i=0; i < 2; i++)
      centroid[i] = in.centroid[i];
    return *this;
  }

  Cluster(){
    for(int i = 0; i < 3; i++)
      centroid[i] = 0.0;
      count = 0;
      proc = -1;
  }
};

class ClusterSection{   // indicates which section of the clusterArray is to be worked upon
  public:
  int beg, end;
  ClusterSection(int b, int e): beg(b), end(e){}
};

template <class T>
int Volume<T>::decideSplitAxis(){

  int which = 0;
  T max = abs(greater[0] - lesser[0]);
  
  for(int i = 1; i < 3; i++)
    if(abs(greater[i] - lesser[i]) >= max){
      max = abs(greater[i] - lesser[i]);
      which = i;
    }
  return which;
}

template <class T>
void Volume<T>::halve(int axis, Volume<T> &secondhalf){

  secondhalf = *this;
  greater[axis] = (lesser[axis]+greater[axis])/2;
  secondhalf.lesser[axis] = greater[axis]+1;
}

template <class T>
void Volume<T>::split(int axis, T* where, Volume<T> &secondhalf){
  secondhalf = *this;
  greater[axis] = where[axis];
  secondhalf.lesser[axis] = where[axis];
}

#define NDIMS 3
class Centroid3d{
  public:
  float x;
  float y;
  float z;

  float *pointers[NDIMS];

  Centroid3d(){
    pointers[0] = &x;
    pointers[1] = &y;
    pointers[2] = &z;
  }

  float& operator[](int i){
    return *(pointers[i]);
  }

};

// Each tpobject has three events, one for 
// each component of its centroid. This helps
// us avoid sorting after each recursive partitioning
// step.

class TPObject;

///
/// @brief structure for sorting TreePieces in one dimension for load
/// balancing.
///
struct Event {
    /// Index within TreePiece array or stats->objData array of this TreePiece.
  int owner;
    /// load of this TreePiece
  float load;
    /// Centroid of this TreePiece in a particular dimension.
  float position;

  Event(float pos, float ld, int o) : 
    position(pos),
    load(ld),
    owner(o)
  {
  }

  Event() : 
    owner(-1),
    load(0.0),
    position(0.0)
  {
  }

  bool operator<(const Event &e) const {
    return position < e.position;
  }

  bool operator<=(const Event &e) const {
    return position <= e.position;
  }

  bool operator>=(const Event &e) const {
    return position >= e.position;
  }

  void pup(PUP::er &p){
    p|owner;
    p|load;
    p|position;
  }
};

///
/// @brief data for Orb3D load balancing.
///
struct OrbObject {
  int partition;
  /// index into LB stats->objData
  int lbindex;
  /// Spacial location of TreePiece
  Vector3D<float> centroid;
  /// Particles in the TreePiece
  int numParticles;

  OrbObject(int tag) : 
    partition(-1),
    lbindex(tag),
    numParticles(0)
   {
   }

  OrbObject() : 
    partition(-1),
    lbindex(-1),
    numParticles(0)
  {
  }

  OrbObject(int tag, int np) : 
    partition(-1),
    lbindex(tag),
    numParticles(np)
  {
  }

  void pup(PUP::er &p){
    p|partition;
    p|lbindex;
    p|centroid;
    p|numParticles;
  }
};

class TPObject{
  public:

  Vector3D<float> centroid;
  float load;
  //int index;
  int lbindex;
  bool migratable;
  //int nparticles;

  int whichPartition;

  bool operator<(const TPObject &t) const{
    return load < t.load;
  }

  TPObject() : 
    load(0.0),
    lbindex(-1),
    whichPartition(-1)
  {
  }

};

class Processor{
  public:

  float load;
  int t;

  bool operator<(const Processor &p) const{
    return load > p.load;
  }
  Processor(){
    load = 0.0;
    t = -1;
  }

  Processor(int pe){
    load = 0.0;
    t = pe;
  }

};

class Node {
  public:
  int x, y, z;
  CkVec<int> procRanks;
#ifdef PRINT_BOUNDING_BOXES
  OrientedBox<float> box;
#endif
};

typedef int (*ComparatorFn) (const void *, const void *);
#endif // _MAP_STRUCTURES_H_
back to top