Skip to content
Snippets Groups Projects
Commit acdb15b8 authored by Pietro Incardona's avatar Pietro Incardona
Browse files

Added missing files

parent f0dbf3ce
No related branches found
No related tags found
No related merge requests found
/*
* CartDecomposition.cpp
*
* Created on: Aug 15, 2014
* Author: Pietro Incardona
*/
#include "CartDecomposition.hpp"
/*! \brief The the bulk part of the data set, or the data that does not depend
* from the ghosts layers
*
* The the bulk part of the data set, or the data that does not depend from the
* ghosts layers
*
*/
/*template<typename T> T CartDecomposition<T>::getBulk(T data)
{
// for each element in data
for (size_t i = 0; i < data.size() ; i++)
{
if (localSpace.isInside())
}
}
template<typename T> T CartDecomposition<T>::getInternal()
{
}*/
/*! \brief Check if is border or bulk
*
* \param neighboorhood define the neighboorhood of all the points
* \return true if border, false if bulk
*
*/
bool borderOrBulk(neighborhood & nb)
{
device::grid<1,size_t> nbr = nb.next();
// check the neighborhood
// get neighborhood iterator
grid_key_dx_iterator<dim> iterator_nbr = nbr.getIterator();
while (iterator_nbr.hasNext())
{
grid_key_dx key_nbr = iterator_nbr.next();
// check if the neighboorhood is internal
if(subspace.isBound(data.template get<Point::x>(key_nbr)) == false)
{
// it is border
return true;
ret.bord.push_back(key);
break;
}
}
return false;
}
/*! \brief This function divide the data set into bulk, border, external and internal part
*
* \tparam dim dimensionality of the structure storing your data
* (example if they are in 3D grid, has to be 3)
* \tparam T type of object we are dividing
* \tparam device type of layout selected
* \param data 1-dimensional grid of point
* \param nb define the neighborhood of all the points
* \return a structure with the set of objects divided
*
*/
template<unsigned int dim, typename T, template<typename> class layout, typename Memory, template<unsigned int, typename> class Domain, template<typename, typename, typename> class data_s>
dataDiv<T> CartDecomposition<dim,T,layout>::divide(device::grid<1,Point<dim,T>> & data, neighborhood & nb)
{
//! allocate the 3 subset
dataDiv<T> ret;
ret.bord = new boost::shared_ptr<T>(new T());
ret.inte = new boost::shared_ptr<T>(new T());
ret.ext = new boost::shared_ptr<T>(new T());
//! get grid iterator
grid_key_dx_iterator<dim> iterator = data.getIterator();
//! we iterate trough all the set of objects
while (iterator.hasNext())
{
grid_key_dx<dim> key = iterator.next();
//! Check if the object is inside the subspace
if (subspace.isBound(data.template get<Point<3,T>::x>(key)))
{
//! Check if the neighborhood is inside the subspace
if (borderOrBulk(nb) == true)
{
// It is border
ret.bord.push_back(key);
}
else
{
// It is bulk
ret.bulk.push_back(key);
}
}
else
{
//! it is external
ret.ext.push_back(key);
}
}
}
/*
* CartDecomposition.hpp
*
* Created on: Aug 15, 2014
* Author: Pietro Incardona
*/
#ifndef CARTDECOMPOSITION_HPP
#define CARTDECOMPOSITION_HPP
#include "config.h"
#include "Decomposition.hpp"
#include "map_vector.hpp"
#include <vector>
#include "global_const.hpp"
#include <initializer_list>
#include "map_vector.hpp"
#include "SubdomainGraphNodes.hpp"
#include "metis_util.hpp"
#include "dec_optimizer.hpp"
#include "Space/Shape/Box.hpp"
/**
* \brief This class decompose a space into subspaces
*
* This class decompose a space into regular hyper-cube subspaces, and give the possibilities to
* select one subspace
*
* \tparam dim is the dimensionality of the physical domain we are going to decompose.
* \tparam T type of the space we decompose, Real, Integer, Complex ...
* \tparam layout to use
* \tparam Memory Memory factory used to allocate memory
* \tparam Domain Structure that contain the information of your physical domain
* \tparam data type of structure that store the sub-domain decomposition can be an openfpm structure like
* vector, ...
*
* \note if PARALLEL_DECOMPOSITION macro is defined a parallel decomposition algorithm is used, basically
* each processor does not recompute the same decomposition
*
*/
template<unsigned int dim, typename T, template<typename> class device_l=openfpm::device_cpu, typename Memory=HeapMemory, template<unsigned int, typename> class Domain=Box, template<typename, typename, typename, typename> class data_s = openfpm::vector>
class CartDecomposition
{
public:
//! Type of the domain we are going to decompose
typedef T domain_type;
//! It simplify to access the SpaceBox element
typedef SpaceBox<dim,T> Box;
private:
//! This is the access_key to data_s, for example in the case of vector
//! acc_key is size_t
typedef typename data_s<SpaceBox<dim,T>,device_l<SpaceBox<dim,T>>,Memory,openfpm::vector_grow_policy_default>::access_key acc_key;
//! Subspace selected
//! access_key in case of grid is just the set of the index to access the grid
std::vector<acc_key> id_sub;
//! the margin of the sub-domain selected
SpaceBox<dim,T> sub_domain;
//! the set of all local sub-domain as vector
data_s<SpaceBox<dim,T>,device_l<SpaceBox<dim,T>>,Memory,openfpm::vector_grow_policy_default> sub_domains;
//! number of total sub-domain
size_t N_tot;
//! number of sub-domain on each dimension
size_t div[dim];
//! rectangular domain to decompose
Domain<dim,T> domain;
//! Box Spacing
T spacing[dim];
//! Runtime virtual cluster machine
Vcluster & v_cl;
/*! \brief Create internally the decomposition
*
* \param v_cl Virtual cluster, used internally to handle or pipeline communication
*
*/
void CreateDecomposition(Vcluster & v_cl)
{
// Calculate the total number of box and and the spacing
// on each direction
N_tot = 1;
// Get the box containing the domain
SpaceBox<dim,T> bs = domain.getBox();
for (unsigned int i = 0; i < dim ; i++)
{
// Calculate the spacing
spacing[i] = (bs.getHigh(i) - bs.getLow(i)) / div[i];
N_tot *= div[i];
}
// Here we use METIS
// Create a cartesian grid graph
CartesianGraphFactory<3,Graph_CSR<nm_part_v,nm_part_e>> g_factory_part;
// Processor graph
Graph_CSR<nm_part_v,nm_part_e> gp = g_factory_part.construct<NO_EDGE,float,2>(div,domain);
// Get the number of processing units
size_t Np = v_cl.getProcessingUnits();
// Get the processor id
long int p_id = v_cl.getProcessUnitID();
// Convert the graph to metis
Metis<Graph_CSR<nm_part_v,nm_part_e>> met(gp,Np);
// decompose
met.decompose<nm_part_v::id>();
// Optimize the decomposition creating bigger spaces
// And reducing Ghost over-stress
dec_optimizer<3,Graph_CSR<nm_part_v,nm_part_e>> d_o(gp,div);
// set of Boxes produced by the decomposition optimizer
openfpm::vector<::Box<dim,size_t>> loc_box;
grid_key_dx<3> keyZero(0,0,0);
d_o.optimize<nm_part_v::sub_id,nm_part_v::id>(keyZero,gp,p_id,loc_box);
// convert into sub-domain
for (size_t s = 0 ; s < loc_box.size() ; s++)
{
SpaceBox<dim,T> sub_d(loc_box.get(s));
// re-scale with the spacing
sub_d.mul(spacing);
// add the sub-domain
sub_domains.add(sub_d);
}
}
/*! \brief Create the subspaces that decompose your domain
*
* Create the subspaces that decompose your domain
*
*/
void CreateSubspaces()
{
// Create a grid where each point is a space
grid<3,void> g(div);
// create a grid_key_dx iterator
grid_key_dx_iterator<dim> gk_it(g);
// Divide the space into subspaces
while (gk_it.isNext())
{
//! iterate through all subspaces
grid_key_dx<dim> key = gk_it.get();
//! Create a new subspace
SpaceBox<dim,T> tmp;
//! fill with the Margin of the box
for (int i = 0 ; i < dim ; i++)
{
tmp.setHigh(i,(key.get(i)+1)*spacing[i]);
tmp.setLow(i,key.get(i)*spacing[i]);
}
//! add the space box
sub_domains.add(tmp);
// add the iterator
++gk_it;
}
}
public:
/*! \brief Cartesian decomposition copy constructor
*
* \param v_cl Virtual cluster, used internally to handle or pipeline communication
*
*/
CartDecomposition(CartDecomposition<dim,T,device_l,Memory,Domain,data_s> && cd)
:sub_domain(cd.sub_domain),N_tot(cd.N_tot),domain(cd.domain),v_cl(cd.v_cl)
{
//! Subspace selected
//! access_key in case of grid is just the set of the index to access the grid
id_sub.swap(cd.id_sub);
//! the set of all local sub-domain as vector
sub_domains.swap(cd.sub_domains);
for (int i = 0 ; i < dim ; i++)
{
this->div[i] = div[dim];
//! Box Spacing
this->spacing[i] = spacing[i];
}
}
/*! \brief Cartesian decomposition constructor
*
* \param v_cl Virtual cluster, used internally to handle or pipeline communication
*
*/
CartDecomposition(Vcluster & v_cl)
:id_sub(0),N_tot(0),v_cl(v_cl)
{}
/*! \brief Cartesian decomposition constructor, it divide the space in boxes
*
* \param dec is a vector that store how to divide on each dimension
* \param domain is the domain to divide
* \param v_cl are information of the cluster runtime machine
*
*/
CartDecomposition(std::vector<size_t> dec, Domain<dim,T> domain, Vcluster & v_cl)
:id_sub(0),div(dec),domain(domain),v_cl(v_cl)
{
// Create the decomposition
CreateDecomposition(v_cl);
}
//! Cartesian decomposition destructor
~CartDecomposition()
{}
/*! \brief Set the parameter of the decomposition
*
* \param div_ std::vector storing into how many domain to decompose on each dimension
* \param domain_ domain to decompose
*
*/
void setParameters(std::vector<size_t> div_, Domain<dim,T> domain_)
{
// Set the decomposition parameters
div = div_;
domain = domain_;
//! Create the decomposition
CreateDecomposition(v_cl);
}
/*! \brief Set the parameter of the decomposition
*
* \param div_ std::vector storing into how many domain to decompose on each dimension
* \param domain_ domain to decompose
*
*/
void setParameters(size_t div_[dim], Domain<dim,T> domain_)
{
// Set the decomposition parameters
for (int i = 0 ; i < dim ; i++)
div[i] = div_[i];
domain = domain_;
//! Create the decomposition
CreateDecomposition(v_cl);
}
/*! \brief Get the number of local local hyper-cubes or sub-domains
*
* \return the number of sub-domains
*
*/
size_t getNLocalHyperCube()
{
return sub_domains.size();
}
/*! The the bulk part of the data set, or the data that
* does not depend from the ghosts layers
*
* \return the bulk of your data
*
*/
T getBulk()
{
}
/*! \brief This function divide the data set into bulk, border, external and internal part
*
* \tparam dim dimensionality of the structure storing your data
* (example if they are in 3D grid, has to be 3)
* \tparam T type of object we are dividing
* \tparam device type of layout selected
* \param data 1-dimensional grid of point
* \param nb define the neighborhood of all the points
* \return a structure with the set of objects divided
*
*/
// dataDiv<T> CartDecomposition<dim,T,layout>::divide(layout::grid<1,Point<dim,T>> & data, neighborhood & nb);
/*! The the internal part of the data set, or the data that
* are inside the local space
*
* \return the internal part of your data
*
*/
T getInternal()
{
}
/*! Get the internal part of the dataset, or the data that
* depend from the ghost layers
*
* \return the ghost part of your data
*
*/
T getBorder()
{
}
/*! Get the external part of the dataset, or the data that
* are outside localSpace including ghost
*
* \return the external part of your data
*
*/
T getExternal()
{
}
/*! \brief Get the number of one set of hyper-cube enclosing one particular
* subspace, the hyper-cube enclose your space, even if one box is enough
* can be more that one to increase occupancy
*
* In case of Cartesian decomposition it just return 1, each subspace
* has one hyper-cube, and occupancy 1
*
* \param id of the subspace
* \return the number of hyper-cube enclosing your space
*
*/
size_t getNHyperCube(size_t id)
{
return 1;
}
/*! \brief Get the hyper-cube margins id_c has to be 0
*
* Get the hyper-cube margins id_c has to be 0, each subspace
* has one hyper-cube
*
* \param id of the subspace
* \param id_c
* \return The specified hyper-cube space
*
*/
SpaceBox<dim,T> & getHyperCubeMargins(size_t id, size_t id_c)
{
#ifdef DEBUG
// Check if this subspace exist
if (id >= N_tot)
{
std::cerr << "Error CartDecomposition: id > N_tot";
}
else if (id_c > 0)
{
// Each subspace is an hyper-cube so return error if id_c > 0
std::cerr << "Error CartDecomposition: id_c > 0";
}
#endif
return sub_domains.get<Object>(id);
}
/*! \brief Get the total number of Hyper-cube
*
* Get the total number of Hyper-cube
*
* \return The total number of hyper-cube
*
*/
size_t getNHyperCube()
{
return N_tot;
}
/*! \brief produce an hyper-cube approximation of the space decomposition
*
*/
void hyperCube()
{
}
/*! \brief Select the local space
*
* Select the local space
*
* \param sub select the sub-space
*
*/
void setSpace(size_t sub)
{
id_sub.push_back(sub);
}
/*! \brief Get the local grids
*
* Get the local grids
*
* \return the local grids
*
*/
auto getLocalHyperCubes() -> decltype(sub_domains) &
{
return sub_domains;
}
/*! \brief Get the local hyper-cubes
*
* Get the local hyper-cubes
*
* \param lc is the id of the space
* \return the local hyper-cube
*
*/
SpaceBox<dim,T> getLocalHyperCube(size_t lc)
{
// Create a space box
SpaceBox<dim,T> sp;
// fill the space box
for (size_t k = 0 ; k < dim ; k++)
{
// create the SpaceBox Low and High
sp.setLow(k,sub_domains.template get<Box::p1>(lc)[k]);
sp.setHigh(k,sub_domains.template get<Box::p2>(lc)[k]);
}
return sp;
}
/*! \brief Return the structure that store the physical domain
*
* Return the structure that store the physical domain
*
* \return The physical domain
*
*/
Domain<dim,T> & getDomain()
{
return domain;
}
/*! \brief It return a graph that represent the domain decomposed into the cartesian grid
*
* It return a graph that represent the domain decomposed into the cartesian grid
*
*/
/* Graph<> createGraphModel()
{
}*/
/*! \brief It return a graph that represent the domain decomposed into the cartesian grid
*
* It return a graph that represent the domain decomposed into the cartesian grid
*
*
*/
/* Graph<> createLocalGraphMode()
{
}*/
};
#endif
#ifndef CARTDECOMPOSITION_UNIT_TEST_HPP
#define CARTDECOMPOSITION_UNIT_TEST_HPP
#include "CartDecomposition.hpp"
#include "mathutil.hpp"
BOOST_AUTO_TEST_SUITE( CartDecomposition_test )
#define SUB_UNIT_FACTOR 64
BOOST_AUTO_TEST_CASE( CartDecomposition_test_use)
{
// Virtual cluster
Vcluster vcl(&boost::unit_test::framework::master_test_suite().argc,&boost::unit_test::framework::master_test_suite().argv);
CartDecomposition<3,float> dec(vcl);
// Physical domain
Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0});
size_t div[3];
// Get the number of processor and calculate the number of sub-domain
// for decomposition
size_t n_proc = vcl.getProcessingUnits();
size_t n_sub = n_proc * SUB_UNIT_FACTOR;
// Calculate the number of sub-domain on each dimension
for (int i = 0 ; i < 3 ; i++)
{div[i] = round_big_2(pow(n_sub,1.0/3));}
// Decompose
dec.setParameters(div,box);
}
BOOST_AUTO_TEST_SUITE_END()
#endif
#include "Space/SpaceBox.hpp"
#ifndef DECOMPOSITION_HPP_
#define DECOMPOSITION_HPP_
/**
*
* \brief class that store Internal part external and border part of a dataset
*
*/
template <typename T> class dataDiv
{
//! Border part of the data
boost::shared_ptr<T> bord;
//! internal part of your data
boost::shared_ptr<T> inte;
//! external part of your data
boost::shared_ptr<T> ext;
};
/*! \brief This class define the domain decomposition interface
*
* This class define the domain decomposition interface, its main functionality
* is to divide a domain in several subspaces
*
* \tparam T structure that store the dataset
* \tparam S type of space is decomposing Real integer complex ...
*
*/
template<typename T, typename S>
class Decomposition
{
/*! \brief The the internal part of the data set, or the data that
* does not depend from the ghosts layers
*
* \return The internal part of the dataset
*
*/
virtual T getInternal();
/*! Get the ghost part of the dataset
*
* \return The internal part of the dataset
*
*/
virtual T getBorder();
/*! Get the external part of the dataset (outside the ghost)
*
* \return The external part of the dataset
*
*/
virtual T getExternal();
//! divide the dataset from internal part and border
virtual dataDiv<T> divide();
//! Get the number of hyper-cube the space id is divided into
virtual size_t getNHyperCube(size_t id);
//! Get the hyper-cube margins
virtual std::vector<T> & getHyperCube(size_t id, size_t id_c);
//! destructor
virtual ~Decomposition(){}
};
#endif
#ifndef DIST_MODEL_HPP
#define DIST_MODEL_HPP
#include "metis.h"
/*! \brief This class do graph partitioning
*
* This class do graph partitioning, it use METIS internaly
*
*/
template<typename Graph, typename algorithm>
class GraphPartitioning
{
//! Structure that store the graph
Graph & grp;
/*! Constructor
*
* It load the graph to partition
*
* \param g Graph to store
*
*/
GraphPartitioning(Graph & g)
:grp(g)
{}
};
#endif
#ifndef COM_UNIT_HPP
#define COM_UNIT_HPP
#include <vector>
#include "Grid/map_grid.hpp"
#include "VCluster.hpp"
#include "Space/SpaceBox.hpp"
#include "mathutil.hpp"
#include "grid_dist_id_iterator.hpp"
#include "grid_dist_id_iterator_margin.hpp"
#include "grid_dist_key.hpp"
#define SUB_UNIT_FACTOR 64
/*! \brief This is a distributed grid
*
* Implementation of a distributed grid with id decomposition. A distributed grid is a grid distributed
* across processors. The decomposition is performed on the id of the elements
*
* [Examples]
*
* on 1D where the id is from 1 to N
* processor k take M contiguous elements
*
* on 3D where (for example)
* processor k take M id-connected elements
*
* \param dim Dimensionality of the grid
* \param T type of grid
* \param Decomposition Class that decompose the grid for example CartDecomposition
* \param Mem Is the allocator
* \param device type of base structure is going to store the data
*
*/
template<unsigned int dim, typename T, typename Decomposition,typename Memory=HeapMemory , typename device_grid=grid_cpu<dim,T> >
class grid_dist_id
{
// Ghost expansion
Box<dim,size_t> ghost;
//! Local grids
Vcluster_object_array<device_grid> loc_grid;
//! Space Decomposition
Decomposition dec;
//! Size of the grid on each dimension
size_t g_sz[dim];
//! Communicator class
Vcluster & v_cl;
/*! \brief Get the grid size
*
* Get the grid size, given a domain, the resolution on it and another spaceBox
* it give the size on all directions of the local grid
*
* \param sp SpaceBox enclosing the local grid
* \param domain Space box enclosing the physical domain or part of it
* \param v_size grid size on this physical domain
*
* \return An std::vector representing the local grid on each dimension
*
*/
std::vector<size_t> getGridSize(SpaceBox<dim,typename Decomposition::domain_type> & sp, Box<dim,typename Decomposition::domain_type> & domain, size_t (& v_size)[dim])
{
std::vector<size_t> tmp;
for (size_t d = 0 ; d < dim ; d++)
{
//! Get the grid size compared to the domain space and its resolution
typename Decomposition::domain_type dim_sz = (sp.getHigh(d) - sp.getLow(d)) / ((domain.getHigh(d) - domain.getLow(d)) / v_size[d]) + 0.5;
// push the size of the local grid
tmp.push_back(dim_sz);
}
return tmp;
}
/*! \brief Get the grid size
*
* Get the grid size, given a spaceBox
* it give the size on all directions of the local grid
*
* \param sp SpaceBox enclosing the local grid
* \param sz array to fill with the local grid size on each dimension
*
*/
void getGridSize(SpaceBox<dim,size_t> & sp, size_t (& v_size)[dim])
{
for (size_t d = 0 ; d < dim ; d++)
{
// push the size of the local grid
v_size[d] = sp.getHigh(d) - sp.getLow(d);
}
}
public:
//! constructor
grid_dist_id(Vcluster v_cl, Decomposition & dec, size_t (& g_sz)[dim], Box<dim,size_t> & ghost)
:ghost(ghost),loc_grid(NULL),v_cl(v_cl),dec(dec)
{
// fill the global size of the grid
for (int i = 0 ; i < dim ; i++) {this->g_sz[i] = g_sz[i];}
// Get the number of processor and calculate the number of sub-domain
// for decomposition
size_t n_proc = v_cl.getProcessingUnits();
size_t n_sub = n_proc * SUB_UNIT_FACTOR;
// Calculate the maximum number (before merging) of sub-domain on
// each dimension
size_t div[dim];
for (int i = 0 ; i < dim ; i++)
{div[i] = round_big_2(pow(n_sub,1.0/dim));}
// Create the sub-domains
dec.setParameters(div);
}
//! constructor
grid_dist_id(size_t (& g_sz)[dim])
:v_cl(*global_v_cluster),dec(Decomposition(v_cl))
{
// fill the global size of the grid
for (int i = 0 ; i < dim ; i++) {this->g_sz[i] = g_sz[i];}
// first compute a decomposition
Create();
}
/*! \brief Get the object that store the decomposition information
*
* \return the decomposition object
*
*/
Decomposition & getDecomposition()
{
return dec;
}
/*! \brief Create the grid on memory
*
*/
void Create()
{
// ! Create an hyper-cube approximation.
// ! In order to work on grid_dist the decomposition
// ! has to be a set of hyper-cube
dec.hyperCube();
// Get the number of local grid needed
size_t n_grid = dec.getNLocalHyperCube();
// create local grids for each hyper-cube
loc_grid = v_cl.allocate<device_grid>(n_grid);
// Size of the grid on each dimension
size_t l_res[dim];
// Allocate the grids
for (size_t i = 0 ; i < n_grid ; i++)
{
// Get the local hyper-cube
SpaceBox<dim,size_t> sp = dec.getLocalHyperCube(i);
// Calculate the local grid size
getGridSize(sp,l_res);
// Set the dimensions of the local grid
loc_grid.get(i).template resize<Memory>(l_res);
}
}
/*! \brief It return an iterator of the bulk part of the grid with a specified margin
*
* For margin we mean that every point is at least m points far from the border
*
* \param m margin
*
* \return An iterator to a grid with specified margins
*
*/
grid_dist_iterator_margin<dim,device_grid> getBulkIterator(size_t margin)
{
grid_dist_iterator_margin<dim,device_grid> it(loc_grid,margin);
return it;
}
//! Destructor
~grid_dist_id()
{
}
};
#endif
/*
* grid_dist_id_iterator.hpp
*
* Created on: Feb 4, 2015
* Author: Pietro Incardona
*/
#ifndef GRID_DIST_ID_ITERATOR_HPP_
#define GRID_DIST_ID_ITERATOR_HPP_
#include "grid_dist_key.hpp"
#include "Grid/grid.hpp"
/*! \brief Distributed grid iterator
*
* Iterator across the local element of the distributed grid
*
*/
template<unsigned int dim, typename l_grid>
class grid_dist_iterator
{
//! grid list counter
size_t g_c;
//! List of the grids we are going to iterate
std::vector<l_grid> & gList;
//! Actual iterator
grid_key_dx_iterator<dim> a_it;
public:
/*! \brief Constructor of the distributed grid
*
* \param gk std::vector of the local grid
*
*/
grid_dist_iterator(std::vector<l_grid> & gk)
:g_c(0),gList(gk)
{
// Initialize with the current iterator
// with the first grid
a_it = gList[0].getIterator();
}
// Destructor
~grid_dist_iterator()
{}
/*! \brief Get the next element
*
* \return the next grid_key
*
*/
grid_key_dx_iterator<dim> operator++()
{
a_it++;
// check if a_it is at the end
if (a_it.isEnd() == false)
return *this;
else
{
// switch to the new grid
g_c++;
// get the next grid iterator
a_it = a_it = gList[g_c].getIterator();
// increment to a valid point
a_it++;
}
return *this;
}
/*! \brief Check if there is the next element
*
* \return true if there is the next, false otherwise
*
*/
bool isEnd()
{
// If there are no other grid stop
if (g_c >= gList.size())
return true;
}
/*! \brief Get the actual key
*
* \return the actual key
*
*/
grid_dist_key_dx<dim> get()
{
return a_it;
}
};
#endif /* GRID_DIST_ID_ITERATOR_HPP_ */
/*
* grid_dist_id_iterator_sub.hpp
*
* Created on: Feb 4, 2015
* Author: Pietro Incardona
*/
#ifndef GRID_DIST_ID_ITERATOR_SUB_HPP_
#define GRID_DIST_ID_ITERATOR_SUB_HPP_
#include "VCluster.hpp"
/*! \brief Distributed grid iterator
*
* Iterator across the local element of the distributed grid
*
*/
template<unsigned int dim, typename device_grid>
class grid_dist_iterator_margin
{
//! grid list counter
size_t g_c;
//! List of the grids we are going to iterate
Vcluster_object_array<device_grid> & gList;
//! Actual iterator
grid_key_dx_iterator_sub<dim> * a_it;
//! margin of the grid iterator
size_t m;
public:
/*! \brief Constructor of the distributed grid
*
* \param gk std::vector of the local grid
*
*/
grid_dist_iterator_margin(Vcluster_object_array<device_grid> & gk, size_t m)
:g_c(0),gList(gk),m(m)
{
// Initialize the current iterator
// with the first grid
a_it = new grid_key_dx_iterator_sub<dim>(gList[0].getSubIterator(m));
}
// Destructor
~grid_dist_iterator_margin()
{
// delete the grid iterator
delete a_it;
}
/*! \brief Get the next element
*
* \return the next grid_key
*
*/
grid_key_dx_iterator<dim> operator++()
{
a_it++;
// check if a_it is at the end
if (a_it.isEnd() == false)
return *this;
else
{
// switch to the new grid
g_c++;
// get the next grid iterator
a_it = a_it = gList[g_c].getIterator();
// increment to a valid point
a_it++;
}
return *this;
}
/*! \brief Check if there is the next element
*
* \return true if there is the next, false otherwise
*
*/
bool isEnd()
{
// If there are no other grid stop
if (g_c >= gList.size())
return true;
}
/*! \brief Get the actual key
*
* \return the actual key
*
*/
grid_dist_key_dx<dim> get()
{
return a_it;
}
};
#endif /* GRID_DIST_ID_ITERATOR_SUB_HPP_ */
#ifndef GRID_DIST_UNIT_TEST_HPP
#define GRID_DIST_UNIT_TEST_HPP
#include "grid_dist_id.hpp"
#include "data_type/scalar.hpp"
BOOST_AUTO_TEST_SUITE( grid_dist_id_test )
template<typename iterator> void jacobi_iteration(iterator g_it, grid_dist_id<2, scalar<float>, CartDecomposition<2,size_t>> & g_dist)
{
// scalar
typedef scalar<size_t> S;
// iterator
while(g_it.isNext())
{
// Jacobi update
auto pos = g_it.get();
g_dist.template get<S::ele>(pos) = (g_dist.template get<S::ele>(pos.move(0,1)) +
g_dist.template get<S::ele>(pos.move(0,-1)) +
g_dist.template get<S::ele>(pos.move(1,1)) +
g_dist.template get<S::ele>(pos.move(1,-1)) / 4.0);
++g_it;
}
}
BOOST_AUTO_TEST_CASE( grid_dist_id_iterator_test_use)
{
// grid size
size_t sz[2] = {1024,1024};
// Distributed grid with id decomposition
grid_dist_id<2, scalar<float>, CartDecomposition<2,size_t>> g_dist(sz);
// Create the grid on memory
g_dist.Create();
// get the Bulk iterator
auto bulk = g_dist.getBulkIterator(2);
/* auto g_it = g_dist.getIteratorBulk();
auto g_it_halo = g_dist.getHalo();
// Let try to solve the poisson equation d2(u) = f with f = 1 and computation
// comunication overlap (100 Jacobi iteration)
for (int i = 0 ; i < 100 ; i++)
{
g_dist.ghost_get();
// Compute the bulk
jacobi_iteration(g_it);
g_dist.ghost_sync();
// Compute the halo
jacobi_iteration(g_it_halo);
}*/
}
BOOST_AUTO_TEST_CASE( grid_dist_id_poisson_test_use)
{
// grid size
size_t sz[2] = {1024,1024};
// Distributed grid with id decomposition
grid_dist_id<2, scalar<float>, CartDecomposition<2,size_t>> g_dist(sz);
// Create the grid on memory
g_dist.Create();
/* auto g_it = g_dist.getIteratorBulk();
auto g_it_halo = g_dist.getHalo();
// Let try to solve the poisson equation d2(u) = f with f = 1 and computation
// comunication overlap (100 Jacobi iteration)
for (int i = 0 ; i < 100 ; i++)
{
g_dist.ghost_get();
// Compute the bulk
jacobi_iteration(g_it);
g_dist.ghost_sync();
// Compute the halo
jacobi_iteration(g_it_halo);
}*/
}
BOOST_AUTO_TEST_SUITE_END()
#endif
#ifndef GRID_DIST_KEY_DX_HPP
#define GRID_DIST_KEY_DX_HPP
/*! \brief Grid key for a distributed grid
*
* Grid key for a distributed grid
*
*/
template<unsigned int dim>
class grid_dist_key_dx
{
//! grid list counter
size_t g_c;
//! Local grid iterator
grid_key_dx_iterator<dim> a_it;
};
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment