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

Added vector iterator

parent 9cc682a6
No related branches found
No related tags found
No related merge requests found
......@@ -38,7 +38,7 @@
*
*/
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>
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, unsigned int> class data_s = openfpm::vector>
class CartDecomposition
{
public:
......@@ -52,7 +52,7 @@ 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;
typedef typename data_s<SpaceBox<dim,T>,device_l<SpaceBox<dim,T>>,Memory,openfpm::vector_grow_policy_default,openfpm::vect_isel<SpaceBox<dim,T>>::value >::access_key acc_key;
//! Subspace selected
//! access_key in case of grid is just the set of the index to access the grid
......@@ -62,7 +62,7 @@ private:
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;
data_s<SpaceBox<dim,T>,device_l<SpaceBox<dim,T>>,Memory,openfpm::vector_grow_policy_default, openfpm::vect_isel<SpaceBox<dim,T>>::value > sub_domains;
//! number of total sub-domain
size_t N_tot;
......
......@@ -234,6 +234,195 @@ public:
{
return v_cl;
}
/*! \brief Get the reference of the selected element
*
*
* \param p property to get (is an integer)
* \param v1 grid_key that identify the element in the grid
*
*/
template <unsigned int p>inline auto get(grid_dist_key_dx<dim> & v1) -> typename std::add_lvalue_reference<decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))>::type
{
return loc_grid.get(v1.getSub()).template get<p>(v1.getKey());
}
};
/*! \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<typename T, typename Decomposition,typename Memory , typename device_grid >
class grid_dist_id<1,T,Decomposition,Memory,device_grid>
{
// Ghost expansion
Box<1,size_t> ghost;
//! Local grids
Vcluster_object_array<device_grid> loc_grid;
//! Size of the grid on each dimension
size_t g_sz[1];
//! 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<1,typename Decomposition::domain_type> & sp, Box<1,typename Decomposition::domain_type> & domain, size_t (& v_size)[1])
{
std::vector<size_t> tmp;
for (size_t d = 0 ; d < 1 ; d++)
{
// push the size of the local grid
tmp.push_back(g_sz[0]);
}
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<1,size_t> & sp, size_t (& v_size)[1])
{
for (size_t d = 0 ; d < 1 ; d++)
{
// push the size of the local grid
v_size[d] = sp.getHigh(d) - sp.getLow(d) + 1;
}
}
public:
//! constructor
grid_dist_id(Vcluster v_cl, Decomposition & dec, size_t (& g_sz)[1], Box<1,size_t> & ghost)
:ghost(ghost),loc_grid(NULL),v_cl(v_cl)
{
// fill the global size of the grid
for (int i = 0 ; i < 1 ; i++) {this->g_sz[i] = g_sz[i];}
// Create local memory
Create();
}
//! constructor
grid_dist_id(size_t (& g_sz)[1])
:v_cl(*global_v_cluster)
{
// fill the global size of the grid
for (int i = 0 ; i < 1 ; i++) {this->g_sz[i] = g_sz[i];}
// Create local memory
Create();
}
/*! \brief Create the grid on memory
*
*/
void Create()
{
size_t n_grid = 1;
// 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[1];
// Calculate the local grid size
l_res[0] = g_sz[0] / v_cl.getProcessingUnits();
// Distribute the remaining
size_t residual = g_sz[0] % v_cl.getProcessingUnits();
if (v_cl.getProcessUnitID() < residual)
l_res[0]++;
// Set the dimensions of the local grid
loc_grid.get(0).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<1,device_grid> getDomainIterator()
{
grid_dist_iterator<1,device_grid> it(loc_grid,0);
return it;
}
//! Destructor
~grid_dist_id()
{
}
/*! \brief Get the Virtual Cluster machine
*
* \return the Virtual cluster machine
*
*/
Vcluster & getVC()
{
return v_cl;
}
/*! \brief Get the reference of the selected element
*
*
* \param p property to get (is an integer)
* \param v1 grid_key that identify the element in the grid
*
*/
template <unsigned int p>inline auto get(grid_dist_key_dx<1> & v1) -> typename std::add_lvalue_reference<decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))>::type
{
return loc_grid.get(0).template get<p>(v1.getKey());
}
};
#endif
......@@ -53,6 +53,21 @@ class grid_dist_iterator
{
}
/*! \brief operator=
*
* assign
*
*/
grid_dist_iterator<dim,device_grid> & operator=(const grid_dist_iterator<dim,device_grid> & gdi)
{
g_c = gdi.g_c;
gList = gdi.gList;
a_it = gdi.a_it;
m = gdi.m;
return *this;
}
/*! \brief Get the next element
*
* \return the next grid_key
......
......@@ -50,11 +50,27 @@ BOOST_AUTO_TEST_CASE( grid_dist_id_iterator_test_use)
{
auto key = dom.get();
g_dist.template get<0>(key) = count;
// Count the point
count++;
++dom;
}
size_t count_check = 0;
dom = g_dist.getDomainIterator();
while (dom.isNext())
{
auto key = dom.get();
BOOST_REQUIRE_EQUAL(g_dist.template get<0>(key),count_check);
count_check++;
++dom;
}
// Get the virtual cluster machine
Vcluster & vcl = g_dist.getVC();
......
......@@ -20,6 +20,26 @@ class grid_dist_key_dx
public:
/*! \brief Get the local grid
*
* \return the id of the local grid
*
*/
size_t getSub()
{
return g_c;
}
/*! \brief Get the key
*
* \return the local key
*
*/
grid_key_dx<dim> getKey()
{
return key;
}
grid_dist_key_dx(int g_c, grid_key_dx<dim> key)
:g_c(g_c),key(key)
{
......
/*
* spaces.hpp
*
* Created on: Mar 10, 2015
* Author: Pietro Incardona
*/
#ifndef SPACES_HPP_
#define SPACES_HPP_
template<unsigned int dim, typename T> class space
{
public:
typedef boost::fusion::vector<> type;
typedef typename memory_traits_inte<type>::type memory_int;
typedef typename memory_traits_lin<type>::type memory_lin;
type data;
static const unsigned int max_prop = 0;
};
template<typename T> class space<1,T>
{
public:
typedef boost::fusion::vector<T> type;
typedef typename memory_traits_inte<type>::type memory_int;
typedef typename memory_traits_lin<type>::type memory_lin;
type data;
static const unsigned int x = 0;
static const unsigned int max_prop = 1;
};
template<typename T> class space<2,T>
{
public:
typedef boost::fusion::vector<T,T> type;
typedef typename memory_traits_inte<type>::type memory_int;
typedef typename memory_traits_lin<type>::type memory_lin;
type data;
static const unsigned int x = 0;
static const unsigned int y = 1;
static const unsigned int max_prop = 2;
};
template<typename T> class space<3,T>
{
public:
typedef boost::fusion::vector<T,T,T> type;
typedef typename memory_traits_inte<type>::type memory_int;
typedef typename memory_traits_lin<type>::type memory_lin;
type data;
static const unsigned int x = 0;
static const unsigned int y = 1;
static const unsigned int z = 2;
static const unsigned int max_prop = 3;
};
template<typename T> class space<4,T>
{
public:
typedef boost::fusion::vector<T,T,T,T> type;
typedef typename memory_traits_inte<type>::type memory_int;
typedef typename memory_traits_lin<type>::type memory_lin;
type data;
static const unsigned int x = 0;
static const unsigned int y = 1;
static const unsigned int z = 2;
static const unsigned int t = 3;
static const unsigned int max_prop = 4;
};
template<typename T> class space<5,T>
{
public:
typedef boost::fusion::vector<T,T,T,T,T> type;
typedef typename memory_traits_inte<type>::type memory_int;
typedef typename memory_traits_lin<type>::type memory_lin;
type data;
static const unsigned int max_prop = 5;
};
template<typename T> class space<6,T>
{
public:
typedef boost::fusion::vector<T,T,T,T,T,T> type;
typedef typename memory_traits_inte<type>::type memory_int;
typedef typename memory_traits_lin<type>::type memory_lin;
type data;
static const unsigned int max_prop = 6;
};
template<typename T> class space<7,T>
{
public:
typedef boost::fusion::vector<T,T,T,T,T,T,T> type;
typedef typename memory_traits_inte<type>::type memory_int;
typedef typename memory_traits_lin<type>::type memory_lin;
type data;
static const unsigned int max_prop = 7;
};
template<typename T> class space<8,T>
{
public:
typedef boost::fusion::vector<T,T,T,T,T,T,T,T> type;
typedef typename memory_traits_inte<type>::type memory_int;
typedef typename memory_traits_lin<type>::type memory_lin;
type data;
static const unsigned int max_prop = 8;
};
#endif /* SPACES_HPP_ */
/*
* space_key.hpp
*
* Created on: Mar 6, 2015
* Author: Pietro Incardona
*/
#ifndef SPACE_KEY_HPP_
#define SPACE_KEY_HPP_
/*! \brief grid_key_dx is the key to access any element in the grid
*
* grid_key_dx is the key to access any element in the grid
*
* \tparam dim dimensionality of the grid
* \tparam T type of the space float, double, complex, ...
*
*/
template<unsigned int dim, typename T>
class space_key_dx
{
public:
//! Constructor
space_key_dx()
{}
//! Constructor from buffer
space_key_dx(T (& k)[dim])
{
for (int i = 0 ; i < dim ; i++)
this->k[i] = k[i];
}
//! Constructor from buffer
space_key_dx(const T (& k)[dim])
{
for (int i = 0 ; i < dim ; i++)
this->k[i] = k[i];
}
//! Construct a grid key from a list of numbers
space_key_dx(const T v,const T...t)
{
k[dim-1] = v;
invert_assign(t...);
}
/*! \brief Set to zero the key
*/
inline void zero()
{
for (int i = 0 ; i < dim ; i++)
{
k[i] = 0;
}
}
/*! \brief Set to invalid the key
*/
inline void invalid()
{
for (int i = 0 ; i < dim ; i++)
{
k[i] = -1;
}
}
/* \brief Check if two key are the same
*
* \param key_t key to check
*
* \return true if the two key are identical
*
*/
template<unsigned int dim_t> bool operator==(space_key_dx<dim_t,T> & key_t)
{
if (dim != dim_t)
{
return false;
}
// Check the two key index by index
for (int i = 0 ; i < dim ; i++)
{
if (k[i] != key_t.k[i])
{
return false;
}
}
// identical key
return true;
}
//! set the grid key from a list of numbers
template<typename a, typename ...T>void set(a v, T...t)
{
k[dim-1] = v;
invert_assign(t...);
}
/*! \brief Get the i index
*
* \param i index to get
*
* \return the index value
*
*/
mem_id value(size_t i) const
{
return k[i];
}
/*! \brief Get the i index
*
*
* \param i index to get
*
* \return the index value
*
*/
mem_id get(size_t i) const
{
return k[i];
}
/*! \brief Set the i index
*
* Set the i index
*
* \param i index to set
* \param id value to set
*
*/
void set_d(size_t i, mem_id id)
{
#ifdef DEBUG
if (i >= dim)
std::cerr << "grid_key_dx error: " << __FILE__ << " " << __LINE__ << " try to access dimension " << i << " on a grid_key_dx of size " << dim << "\n";
#endif
k[i] = id;
}
//! structure that store all the index
mem_id k[dim];
private:
/*! \brief Recursively invert the assignment
*
* Recursively invert the assignment at compile-time
*
*/
template<typename a, typename ...T>void invert_assign(a v,T...t)
{
k[sizeof...(T)] = v;
invert_assign(t...);
}
template<typename a, typename ...T>void invert_assign(a v)
{
k[0] = v;
}
void invert_assign()
{
}
};
#endif /* SPACE_KEY_HPP_ */
/*
* Vector.hpp
*
* Created on: Mar 5, 2015
* Author: Pietro Incardona
*/
#ifndef VECTOR_HPP_
#define VECTOR_HPP_
#include "Space/space.hpp"
#define NO_ID false
#define ID true
/*! \brief Distributed vector
*
*
*
*/
template<typename space, typename prop, typename Box, typename Decomposition , typename Memory=HeapMemory, bool with_id=false>
class vector_dist
{
private:
//! Space Decomposition
Decomposition dec;
// Space for space position
grid_dist_id<1,space,Decomposition,Memory> pos;
// Space for properties
grid_dist_id<1,prop,Decomposition,Memory> prp;
// Virtual cluster
Vcluster & v_cl;
public:
/*! \brief Constructor
*
* \param number of elements
*
*/
vector_dist(size_t np)
:dec(Decomposition(*global_v_cluster)),v_cl(*global_v_cluster)
{
// resize the position vector
pos.resize(np);
// resize the properties vector
prp.resize(np);
// Create a valid decomposition of the space
// 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[space::size];
for (int i = 0 ; i < space::size ; i++)
{div[i] = round_big_2(pow(n_sub,1.0/space::size));}
// Create the sub-domains
dec.setParameters(div);
}
/*! \brief Get position of an object
*
* \param vec_key vector element
*
*/
template<unsigned int id> auto getPos(size_t vec_key) -> decltype(pos.template get<id>(vec_key))
{
return pos.template get<id>(vec_key);
}
/*! \brief Get the property of the object
*
* \param vec_key vector element
*
*/
template<unsigned int id> auto getProp(size_t vec_key) -> decltype(prp.template get<id>(vec_key))
{
return prp.template get<id>(vec_key);
}
/*! \brief It communicate the particle to the respective processor
*
*/
void map()
{
// allocate n vector with n = number of processors
// boost::shared_ptr<openfpm::vector<space>> (new openfpm::vector<space>[v_cl.getProcessingUnits()]);
// allocate n vector with n = number of processors
// boost::shared_ptr<openfpm::vector<prop>> (new openfpm::vector<space>[v_cl.getProcessingUnits()]);
// Contain the map of the processor should communicate
openfpm::vector<unsigned char> p_map;
// Contain the processor id of each particle (basically where they have to go)
openfpm::vector<size_t> lbl_p(pos.size());
// It contain the list of the processors it should to communicate
openfpm::vector<size_t> p_list;
auto it = pos.getIterator();
// Label all the particles it the processor id where they should go
while (it.isNext())
{
auto key = it.get();
size_t p_id = dec.processorID(pos.get_o(key));
lbl_p.get(key) = p_id;
// It has to communicate
p_map.get(p_id) = 1;
++it;
}
}
};
#endif /* VECTOR_HPP_ */
/*
* vector_dist_iterator.hpp
*
* Created on: Mar 10, 2015
* Author: Pietro Incardona
*/
#ifndef VECTOR_DIST_ITERATOR_HPP_
#define VECTOR_DIST_ITERATOR_HPP_
#include "VCluster.hpp"
template<unsigned int dim, typename device_v>
class vector_dist_iterator
{
//! vector list counter
size_t v_c;
//! List of the grids we are going to iterate
Vcluster_object_array<device_v> & vList;
//! Actual iterator
size_t v_it;
public:
/*! \brief Constructor of the distributed grid
*
* \param gk std::vector of the local grid
*
*/
vector_dist_iterator(Vcluster_object_array<device_v> & gk)
:v_c(0),vList(gk),v_it(0)
{
}
// Destructor
~vector_dist_iterator()
{
}
/*! \brief operator=
*
* assign
*
*/
vector_dist_iterator<dim,device_v> & operator=(const vector_dist_iterator<dim,device_v> & vdi)
{
v_c = vdi.v_c;
vList = vdi.vList;
v_it = vdi.v_it;
return *this;
}
/*! \brief Get the next element
*
* \return the next grid_key
*
*/
vector_dist_iterator<dim,device_v> operator++()
{
++v_it;
// check if a_it is at the end
if (v_it.isNext() == true)
return *this;
else
{
// switch to the new grid
v_c++;
// get the next grid iterator
if (v_c < vList.size())
v_it = vList[v_c].getDomainIterator();
}
return *this;
}
/*! \brief Check if there is the next element
*
* \return true if there is the next, false otherwise
*
*/
bool isNext()
{
// If there are no other grid stop
if (v_c >= vList.size())
return false;
return true;
}
/*! \brief Get the actual key
*
* \return the actual key
*
*/
size_t get()
{
return vect_dist_key_dx<dim>(v_c,v_it.get());
}
};
#endif /* VECTOR_DIST_ITERATOR_HPP_ */
/*
* vector_dist_key.hpp
*
* Created on: Mar 10, 2015
* Author: i-bird
*/
#ifndef VECTOR_DIST_KEY_HPP_
#define VECTOR_DIST_KEY_HPP_
/*! \brief Grid key for a distributed grid
*
* Grid key for a distributed grid
*
*/
template<unsigned int dim>
class vect_dist_key_dx
{
//! grid list counter
size_t v_c;
//! Local grid iterator
size_t key;
public:
/*! \brief Get the local grid
*
* \return the id of the local grid
*
*/
size_t getSub()
{
return v_c;
}
/*! \brief Get the key
*
* \return the local key
*
*/
size_t getKey()
{
return key;
}
vect_dist_key_dx(int v_c, size_t key)
:v_c(v_c),key(key)
{
}
};
#endif /* VECTOR_DIST_KEY_HPP_ */
/*
* vector_dist_unit_test.hpp
*
* Created on: Mar 6, 2015
* Author: Pietro Incardona
*/
#ifndef VECTOR_DIST_UNIT_TEST_HPP_
#define VECTOR_DIST_UNIT_TEST_HPP_
#include "Vector/vector_dist.hpp"
BOOST_AUTO_TEST_SUITE( vector_dist_test )
BOOST_AUTO_TEST_CASE( vector_dist_iterator_test_use)
{
vector_dist<space<2,float>, Point_test<float>, Box<2,float>, CartDecomposition<2,float> > vd(4096);
auto it = vd.getIterator();
while (it.isNext())
{
++it;
}
}
BOOST_AUTO_TEST_SUITE_END()
#endif /* VECTOR_DIST_UNIT_TEST_HPP_ */
......@@ -19,5 +19,6 @@
#include "metis_util_unit_test.hpp"
#include "dec_optimizer_unit_test.hpp"
#include "Grid/grid_dist_id_unit_test.hpp"
#include "Vector/vector_dist_unit_test.hpp"
#include "Decomposition/CartDecomposition_unit_test.hpp"
......@@ -44,7 +44,7 @@ BOOST_AUTO_TEST_CASE( Metis_test_use)
// Convert the graph to metis
Metis<Graph_CSR<nm_v,nm_e>> met(g,16);
Metis<Graph_CSR<nm_v,nm_e>> met(g,8);
// decompose
......
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