Commit 5449ffff authored by Pietro Incardona's avatar Pietro Incardona

Grid iterator from decomposition

parent fc389ca6
......@@ -352,6 +352,10 @@ private:
public:
static constexpr int dims = dim;
typedef T stype;
//! Increment the reference counter
void incRef()
{ref_cnt++;}
......
......@@ -7,6 +7,7 @@
#include "VCluster.hpp"
#include "Space/SpaceBox.hpp"
#include "util/mathutil.hpp"
#include "grid_dist_id_iterator_dec.hpp"
#include "grid_dist_id_iterator.hpp"
#include "grid_dist_id_iterator_sub.hpp"
#include "grid_dist_key.hpp"
......@@ -56,7 +57,7 @@ class grid_dist_id
Ghost<dim,St> ghost;
//! Local grids
Vcluster_object_array<device_grid> loc_grid;
openfpm::vector<device_grid> loc_grid;
//! Space Decomposition
Decomposition & dec;
......@@ -369,8 +370,11 @@ class grid_dist_id
// Get the number of local grid needed
size_t n_grid = dec.getNLocalHyperCube();
// create gdb
create_gdb_ext<dim,Decomposition>(gdb_ext,dec,cd_sm);
// create local grids for each hyper-cube
loc_grid = v_cl.allocate<device_grid>(n_grid);
loc_grid.resize(n_grid);
// Size of the grid on each dimension
size_t l_res[dim];
......@@ -378,32 +382,16 @@ class grid_dist_id
// Allocate the grids
for (size_t i = 0 ; i < n_grid ; i++)
{
gdb_ext.add();
// Get the local hyper-cube
SpaceBox<dim,St> sp = dec.getLocalHyperCube(i);
SpaceBox<dim,St> sp_g = dec.getSubDomainWithGhost(i);
// Convert from SpaceBox<dim,St> to SpaceBox<dim,long int>
SpaceBox<dim,long int> sp_t = cd_sm.convertDomainSpaceIntoGridUnits(sp);
SpaceBox<dim,long int> sp_tg = cd_sm.convertDomainSpaceIntoGridUnits(sp_g);
//! Save the origin of the sub-domain of the local grid
gdb_ext.last().origin = sp_tg.getP1();
// save information about the local grid: domain box seen inside the domain + ghost box (see GDBoxes for a visual meaning)
// and where the GDBox start, or the origin of the local grid (+ghost) in global coordinate
gdb_ext.last().Dbox = sp_t;
gdb_ext.last().Dbox -= sp_tg.getP1();
gdb_ext.last().GDbox = sp_tg;
gdb_ext.last().GDbox -= sp_tg.getP1();
// center to zero
sp_tg -= sp_tg.getP1();
SpaceBox<dim,long int> sp_tg = gdb_ext.get(i).GDbox;
// Get the size of the local grid
for (size_t i = 0 ; i < dim ; i++) {l_res[i] = (sp_tg.getHigh(i) >= 0)?(sp_tg.getHigh(i)+1):0;}
// The boxes indicate the extension of the index the size
// is this extension +1
// for example a 1D box (interval) from 0 to 3 in one dimension have
// the points 0,1,2,3 = so a total of 4 points
for (size_t i = 0 ; i < dim ; i++)
l_res[i] = (sp_tg.getHigh(i) >= 0)?(sp_tg.getHigh(i)+1):0;
// Set the dimensions of the local grid
loc_grid.get(i).resize(l_res);
......@@ -591,6 +579,7 @@ public:
InitializeStructures(g_sz);
}
/*! \brief Get an object containing the grid informations
*
* \return an information object about this grid
......
......@@ -85,7 +85,7 @@ class grid_dist_iterator<dim,device_grid,FREE>
size_t g_c;
//! List of the grids we are going to iterate
Vcluster_object_array<device_grid> & gList;
openfpm::vector<device_grid> & gList;
//! Extension of each grid: domain and ghost + domain
openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext;
......@@ -102,12 +102,12 @@ class grid_dist_iterator<dim,device_grid,FREE>
void selectValidGrid()
{
// When the grid has size 0 potentially all the other informations are garbage
while (g_c < gList.size() && (gList[g_c].size() == 0 || gdb_ext.get(g_c).Dbox.isValid() == false ) ) g_c++;
while (g_c < gList.size() && (gList.get(g_c).size() == 0 || gdb_ext.get(g_c).Dbox.isValid() == false ) ) g_c++;
// get the next grid iterator
if (g_c < gList.size())
{
a_it.reinitialize(gList[g_c].getIterator(gdb_ext.get(g_c).Dbox.getKP1(),gdb_ext.get(g_c).Dbox.getKP2()));
a_it.reinitialize(gList.get(g_c).getIterator(gdb_ext.get(g_c).Dbox.getKP1(),gdb_ext.get(g_c).Dbox.getKP2()));
}
}
......@@ -134,7 +134,7 @@ class grid_dist_iterator<dim,device_grid,FREE>
* \param gk std::vector of the local grid
*
*/
grid_dist_iterator(Vcluster_object_array<device_grid> & gk, openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext)
grid_dist_iterator(openfpm::vector<device_grid> & gk, openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext)
:g_c(0),gList(gk),gdb_ext(gdb_ext),m(0)
{
// Initialize the current iterator
......@@ -215,7 +215,7 @@ class grid_dist_iterator<dim,device_grid,FIXED>
size_t g_c;
//! List of the grids we are going to iterate
Vcluster_object_array<device_grid> & gList;
openfpm::vector<device_grid> & gList;
//! Extension of each grid: domain and ghost + domain
const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext;
......@@ -229,12 +229,12 @@ class grid_dist_iterator<dim,device_grid,FIXED>
void selectValidGrid()
{
// When the grid has size 0 potentially all the other informations are garbage
while (g_c < gList.size() && (gList[g_c].size() == 0 || gdb_ext.get(g_c).Dbox.isValid() == false ) ) g_c++;
while (g_c < gList.size() && (gList.get(g_c).size() == 0 || gdb_ext.get(g_c).Dbox.isValid() == false ) ) g_c++;
// get the next grid iterator
if (g_c < gList.size())
{
a_it.reinitialize(gList[g_c].getIterator(gdb_ext.get(g_c).Dbox.getKP1(),gdb_ext.get(g_c).Dbox.getKP2()));
a_it.reinitialize(gList.get(g_c).getIterator(gdb_ext.get(g_c).Dbox.getKP1(),gdb_ext.get(g_c).Dbox.getKP2()));
}
}
......@@ -260,7 +260,7 @@ class grid_dist_iterator<dim,device_grid,FIXED>
* \param gk std::vector of the local grid
*
*/
grid_dist_iterator(Vcluster_object_array<device_grid> & gk, const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext)
grid_dist_iterator(openfpm::vector<device_grid> & gk, const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext)
:g_c(0),gList(gk),gdb_ext(gdb_ext)
{
// Initialize the current iterator
......
......@@ -34,7 +34,7 @@ class grid_dist_iterator_sub
size_t g_c;
//! List of the grids we are going to iterate
Vcluster_object_array<device_grid> & gList;
openfpm::vector<device_grid> & gList;
//! Extension of each grid: domain and ghost + domain
openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext;
......@@ -97,13 +97,13 @@ class grid_dist_iterator_sub
// When the grid has size 0 potentially all the other informations are garbage
while (g_c < gList.size() &&
(gList[g_c].size() == 0 || gdb_ext.get(g_c).Dbox.isValid() == false || compute_subset(g_c,start_c,stop_c) == false ))
(gList.get(g_c).size() == 0 || gdb_ext.get(g_c).Dbox.isValid() == false || compute_subset(g_c,start_c,stop_c) == false ))
{g_c++;}
// get the next grid iterator
if (g_c < gList.size())
{
a_it.reinitialize(gList[g_c].getIterator(start_c,stop_c));
a_it.reinitialize(gList.get(g_c).getIterator(start_c,stop_c));
}
}
......@@ -144,7 +144,7 @@ class grid_dist_iterator_sub
* \param gdb_ext information about the local grids
*
*/
grid_dist_iterator_sub(const grid_key_dx<dim> & start, const grid_key_dx<dim> & stop ,Vcluster_object_array<device_grid> & gk, openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext)
grid_dist_iterator_sub(const grid_key_dx<dim> & start, const grid_key_dx<dim> & stop ,openfpm::vector<device_grid> & gk, openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext)
:g_c(0),gList(gk),gdb_ext(gdb_ext),start(start),stop(stop),m(0)
{
// Initialize the current iterator
......@@ -229,8 +229,4 @@ class grid_dist_iterator_sub
}
};
#endif /* SRC_GRID_GRID_DIST_ID_ITERATOR_SUB_HPP_ */
......@@ -1007,6 +1007,83 @@ void Test3D_dup(const Box<3,float> & domain, long int k)
}
}
// Test decomposition grid iterator
void Test3D_decit(const Box<3,float> & domain, long int k)
{
typedef Point_test<float> p;
Vcluster & v_cl = *global_v_cluster;
if ( v_cl.getProcessingUnits() > 32 )
return;
long int big_step = k / 30;
big_step = (big_step == 0)?1:big_step;
long int small_step = 21;
print_test( "Testing grid iterator from decomposition k<=",k);
// 3D test
for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
{
BOOST_TEST_CHECKPOINT( "Testing grid iterator from decomposition k<=" << k );
// grid size
size_t sz[3];
sz[0] = k;
sz[1] = k;
sz[2] = k;
// factor
float factor = pow(global_v_cluster->getProcessingUnits()/2.0f,1.0f/3.0f);
// Ghost
Ghost<3,float> g(0.01 / factor);
// Distributed grid with id decomposition
grid_dist_id<3, float, Point_test<float>, CartDecomposition<3,float>> g_dist(sz,domain,g);
// check the consistency of the decomposition
bool val = g_dist.getDecomposition().check_consistency();
BOOST_REQUIRE_EQUAL(val,true);
// Grid sm
grid_sm<3,void> info(sz);
auto dom = g_dist.getSubDomainIterator({0,0,0},{sz[0]-1,sz[1]-1,sz[2]-1});
bool match = true;
// create a grid iterator from the decomposition
grid_dist_id_iterator_dec<CartDecomposition<3,float>> it_dec(g_dist.getDecomposition(),g_dist.getGridInfoVoid().getSize());
while (dom.isNext())
{
auto key = dom.get();
auto key_g = g_dist.getGKey(key);
auto key_dec = it_dec.get();
// Check if the two keys match
match &= key_dec == key_g;
if (match == false)
{
int debug = 0;
debug++;
}
++dom;
++it_dec;
}
BOOST_REQUIRE_EQUAL(match,true);
}
}
BOOST_AUTO_TEST_CASE( grid_dist_id_iterator_test_use)
{
// Domain
......@@ -1074,7 +1151,6 @@ BOOST_AUTO_TEST_CASE( grid_dist_id_with_grid_unit_ghost )
long int k = 1024*1024*global_v_cluster->getProcessingUnits();
k = std::pow(k, 1/2.);
// Test2D_gg(domain,k);
// Domain
Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
......@@ -1083,6 +1159,25 @@ BOOST_AUTO_TEST_CASE( grid_dist_id_with_grid_unit_ghost )
Test3D_gg(domain3,k,1);
}
BOOST_AUTO_TEST_CASE( grid_dist_id_decomposition )
{
// Domain
Box<2,float> domain({0.0,0.0},{1.0,1.0});
// Initialize the global VCluster
init_global_v_cluster(&boost::unit_test::framework::master_test_suite().argc,&boost::unit_test::framework::master_test_suite().argv);
long int k = 1024*1024*global_v_cluster->getProcessingUnits();
k = std::pow(k, 1/2.);
// Domain
Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
k = 128*128*128*global_v_cluster->getProcessingUnits();
k = std::pow(k, 1/3.);
Test3D_decit(domain3,k);
}
BOOST_AUTO_TEST_SUITE_END()
#endif
/*
* grid_dist_util.hpp
*
* Created on: Jan 28, 2016
* Author: i-bird
*/
#ifndef SRC_GRID_GRID_DIST_UTIL_HPP_
#define SRC_GRID_GRID_DIST_UTIL_HPP_
#include "NN/CellList/CellDecomposer.hpp"
/*! \brief Create the gdb_ext
*
* \param gdb_ext Vector of Boxes that define the local grids extension
* \param dec Decomposition
* \param cd_sm CellDecomposer the size of cell is equal to the distance between grid points
*
*/
template<int dim, typename Decomposition> inline void create_gdb_ext(openfpm::vector<GBoxes<Decomposition::dims>> & gdb_ext, Decomposition & dec, CellDecomposer_sm<Decomposition::dims,typename Decomposition::stype> & cd_sm)
{
Box<Decomposition::dims, typename Decomposition::stype> g_rnd_box;
for (size_t i = 0 ; i < Decomposition::dims ; i++) {g_rnd_box.setHigh(i,0.5); g_rnd_box.setLow(i,-0.5);}
// Get the number of local grid needed
size_t n_grid = dec.getNLocalHyperCube();
// Allocate the grids
for (size_t i = 0 ; i < n_grid ; i++)
{
gdb_ext.add();
// Get the local hyper-cube
SpaceBox<Decomposition::dims, typename Decomposition::stype> sp = dec.getLocalHyperCube(i);
SpaceBox<Decomposition::dims, typename Decomposition::stype> sp_g = dec.getSubDomainWithGhost(i);
// Convert from SpaceBox<dim,St> to SpaceBox<dim,long int>
SpaceBox<Decomposition::dims,long int> sp_t = cd_sm.convertDomainSpaceIntoGridUnits(sp);
SpaceBox<Decomposition::dims,long int> sp_tg = cd_sm.convertDomainSpaceIntoGridUnits(sp_g);
//! Save the origin of the sub-domain of the local grid
gdb_ext.last().origin = sp_tg.getP1();
// save information about the local grid: domain box seen inside the domain + ghost box (see GDBoxes for a visual meaning)
// and where the GDBox start, or the origin of the local grid (+ghost) in global coordinate
gdb_ext.last().Dbox = sp_t;
gdb_ext.last().Dbox -= sp_tg.getP1();
gdb_ext.last().GDbox = sp_tg;
gdb_ext.last().GDbox -= sp_tg.getP1();
}
}
/*! \brief Create the gdb_ext
*
* \param gdb_ext Vector of Boxes that define the local grids extension
* \param dec Decomposition
* \param Global grid grid size
*
*/
template<int dim, typename Decomposition> inline void create_gdb_ext(openfpm::vector<GBoxes<dim>> & gdb_ext, Decomposition & dec, const size_t (& sz)[dim], const Box<Decomposition::dims,typename Decomposition::stype> & domain)
{
// Create the cell decomposer
CellDecomposer_sm<Decomposition::dims,typename Decomposition::stype> cd_sm;
cd_sm.setDimensions(domain,sz,0);
create_gdb_ext<dim,Decomposition>(gdb_ext,dec,cd_sm);
}
#endif /* SRC_GRID_GRID_DIST_UTIL_HPP_ */
......@@ -822,6 +822,43 @@ BOOST_AUTO_TEST_CASE( vector_dist_not_periodic_map )
}
}
BOOST_AUTO_TEST_CASE( vector_dist_cell_verlet_test )
{
/* typedef Point<3,float> s;
Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0});
// Boundary conditions
size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
// factor
float factor = pow(global_v_cluster->getProcessingUnits()/2.0f,1.0f/3.0f);
// ghost
Ghost<3,float> ghost(0.05 / factor);
// Distributed vector
vector_dist<3,float, Point_test<float>, CartDecomposition<3,float> > vd(1,box,bc,ghost);
// Put particles on a grid creating a Grid iterator
auto it = vd.getGridIterator(sz);
while (it.isNext())
{
auto key = it.get();
vd.template getPos<s::x>(key)[0] = key.get(0);
vd.template getPos<s::x>(key)[1] = key.get(1);
vd.template getPos<s::x>(key)[2] = key.get(2);
++it;
}
vd.map();*/
}
BOOST_AUTO_TEST_SUITE_END()
#endif /* VECTOR_DIST_UNIT_TEST_HPP_ */
......@@ -389,4 +389,236 @@
>>>>>>> Jenkin script for taurus
/*! \brief Allocate a set of objects
*
* \tparam obj
* \param n number of object
*
* \return an object representing an array of objects
*
*/
/* template <typename obj> Vcluster_object_array<obj> allocate(size_t n)
{
// Vcluster object array
Vcluster_object_array<obj> vo;
// resize the array
vo.resize(n);
// Create the object on memory and return a Vcluster_object_array
return vo;
}*/
/*template<typename T>
class Vcluster_object_array : public VObject
{
std::vector<T> objects;
public:*/
/*! \brief Constructor of object array
*
*/
/* Vcluster_object_array()
{
}*/
/*! \brief Return the size of the objects array
*
* \return the size of the array
*
*/
/* size_t size() const
{
return objects.size();
}*/
/*! \brief Return the element i
*
* \return a reference to the object i
*
*/
/* T & get(unsigned int i)
{
return objects[i];
}*/
/*! \brief Return the element i
*
* \return a reference to the object i
*
*/
/* const T & get(unsigned int i) const
{
return objects[i];
}*/
/*! \brief Check if this Object is an array
*
* \return true, it is an array
*
*/
/* bool isArray()
{
return true;
}*/
/*! \brief Destroy the object
*
*/
/* virtual void destroy()
{
// Destroy the objects
objects.clear();
}*/
/*! \brief Get the size of the memory needed to pack the object
*
* \return the size of the message to pack the object
*
*/
/* size_t packObjectSize()
{
size_t message = 0;
// Destroy each objects
for (size_t i = 0 ; i < objects.size() ; i++)
{
message += objects[i].packObjectSize();
}
return message;
}*/
/*! \brief Get the size of the memory needed to pack the object
*
* \param Memory where to write the packed object
*
* \return the size of the message to pack the object
*
*/
/* size_t packObject(void * mem)
{
// Pointer is zero
size_t ptr = 0;
unsigned char * m = (unsigned char *)mem;
// pack each object
for (size_t i = 0 ; i < objects.size() ; i++)
{
ptr += objects[i].packObject(&m[ptr]);
}
#ifdef DEBUG
if (ptr != packObjectSize())
{
std::cerr << "Error " << __FILE__ << " " << __LINE__ << " the pack object size does not match the message" << "\n";
}
#endif
return ptr;
}*/
/*! \brief Calculate the size to pack an object in the array
*
* \param array object index
*
*/
/* size_t packObjectInArraySize(size_t i)
{
return objects[i].packObjectSize();
}*/
/*! \brief pack the object in the array (the message produced can be used to move one)
* object from one processor to another
*
* \param i index of the object to pack
* \param p Memory of the packed object message
*
*/
/* size_t packObjectInArray(size_t i, void * p)
{
return objects[i].packObject(p);
}*/
/*! \brief Destroy an object from the array
*
* \param i object to destroy
*
*/
/* void destroy(size_t i)
{
objects.erase(objects.begin() + i);
}*/
/*! \brief Return the object j in the array
*
* \param j element j
*
*/
/* T & operator[](size_t j)
{
return objects[j];
}*/
/*! \brief Return the object j in the array
*
* \param j element j
*
*/
/* const T & operator[](size_t j) const
{
return objects[j];
}*/
/*! \brief Resize the array
*
* \param size
*
*/
/* void resize(size_t n)
{
objects.resize(n);
}
};*/
/*! \brief VObject
*
* Any object produced by the Virtual cluster (MUST) inherit this class
*
*/
/*class VObject
{
public:
// Check if this Object is an array
virtual bool isArray() = 0;
// destroy the object
virtual void destroy() = 0;