diff --git a/src/Decomposition/CartDecomposition.hpp b/src/Decomposition/CartDecomposition.hpp index 9d0ffaee6e77ccd4c3004a7f15f8f8c982dbc142..c1c4ea33b3e151c82cf7cf7c9aff83fe4b35ca32 100644 --- a/src/Decomposition/CartDecomposition.hpp +++ b/src/Decomposition/CartDecomposition.hpp @@ -18,6 +18,7 @@ #include "metis_util.hpp" #include "dec_optimizer.hpp" #include "Space/Shape/Box.hpp" +#include "Space/space.hpp" /** * \brief This class decompose a space into subspaces @@ -64,6 +65,9 @@ private: //! 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, openfpm::vect_isel<SpaceBox<dim,T>>::value > sub_domains; + //! base structure + openfpm::vector<size_t> fine_s; + //! number of total sub-domain size_t N_tot; @@ -247,6 +251,24 @@ public: ~CartDecomposition() {} + /*! \brief processorID return in which processor the particle should go + * + * \return processorID + * + */ + + template<typename Mem> size_t inline processorID(encapc<1, space<dim,T>, Mem> p) + { + size_t pid = 0; + + for (size_t i = 0 ; i < dim ; i++) + { + pid += p.get().get(i); + } + + return pid; + } + /*! \brief Set the parameter of the decomposition * * \param div_ std::vector storing into how many domain to decompose on each dimension diff --git a/src/Graph/CartesianGraphFactory_unit_test.hpp b/src/Graph/CartesianGraphFactory_unit_test.hpp new file mode 100644 index 0000000000000000000000000000000000000000..bbba04e43234a0093b49a14d2c5e22b9d471257e --- /dev/null +++ b/src/Graph/CartesianGraphFactory_unit_test.hpp @@ -0,0 +1,60 @@ +#ifndef CARTESIAN_GRAPH_UNIT_TEST_HPP +#define CARTESIAN_GRAPH_UNIT_TEST_HPP + +#include "Graph/CartesianGraphFactory.hpp" +#include "Graph/map_graph.hpp" + +#define GS_SIZE 8 + +/*! + * + * Test node + * + */ + +struct node_cp +{ + //! The node contain 3 unsigned long integer for comunication computation and memory + typedef boost::fusion::vector<size_t,size_t,size_t> type; + + //! Attributes name + struct attributes + { + static const std::string name[]; + }; + + //! The data + type data; + + //! communication property id in boost::fusion::vector + static const unsigned int communication = 0; + //! computation property id in boost::fusion::vector + static const unsigned int computation = 1; + //! memory property id in boost::fusion::vector + static const unsigned int memory = 2; + //! total number of properties boost::fusion::vector + static const unsigned int max_prop = 3; +}; + +const std::string node_cp::attributes::name[] = {"communication","computation","memory"}; + +BOOST_AUTO_TEST_SUITE( CartesianGraphFactory_test ) + +BOOST_AUTO_TEST_CASE( CartesianGraphFactory_use) +{ + typedef node_cp node; + + CartesianGraphFactory<3,Graph_CSR<Point_test<float>,Point_test<float>>> g_factory; + + // Cartesian grid + size_t sz[3] = {GS_SIZE,GS_SIZE,GS_SIZE}; + + // Box + Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); + + Graph_CSR<Point_test<float>,Point_test<float>> g = g_factory.construct<node::communication,float,2>(sz,box); +} + +BOOST_AUTO_TEST_SUITE_END() + +#endif diff --git a/src/Space/space.hpp b/src/Space/space.hpp index 87fa266276c7c1854efe0fe9fbae3a5eb0c8ed5c..b34a99af8309ab5f8dcd2e01aa6b80a4de61b186 100644 --- a/src/Space/space.hpp +++ b/src/Space/space.hpp @@ -29,6 +29,7 @@ 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; + typedef T stype; type data; @@ -44,6 +45,7 @@ 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; + typedef T stype; type data; @@ -60,6 +62,7 @@ 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; + typedef T stype; type data; @@ -77,6 +80,7 @@ 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; + typedef T stype; type data; @@ -95,6 +99,7 @@ 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; + typedef T stype; type data; @@ -109,6 +114,7 @@ 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; + typedef T stype; type data; @@ -123,6 +129,7 @@ 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; + typedef T stype; type data; @@ -136,6 +143,7 @@ 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; + typedef T stype; type data; diff --git a/src/SubdomainGraphNodes.hpp b/src/SubdomainGraphNodes.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ce5326820e532e7dce64d7f412534b66ca5ac6ec --- /dev/null +++ b/src/SubdomainGraphNodes.hpp @@ -0,0 +1,161 @@ +#ifndef SUBDOMAIN_NODES_HPP +#define DUBDOMAIN_NODES_HPP + +/* In a decomposition graph each node represent a sub-domain while an edge represent + * an interaction between sub-domain (it mean that they have to communicate). + * + * Here we list the of property that a vertex node can carry with a brief + * explanation: + * + * x = position x of the sub-domain + * y = position y of the sub-domain + * z = position z of the sub-domain + * communication = is the estimated total communication produced by the sub-domain + * computation = the total computation produced by the sub-domain + * memory = estimated memory required by the sub-domain + * id = which processor own this sub-domain + * sub-id = sub-decomposition where each group of sub-domain is organized in an + * hyper-cube + * + * Here we list the properties that an edge node can carry with a brief explanation + * + * communication = is the estimated communication between sub-domains + * + */ + +/* \brief Sub-domain vertex graph node + * + */ + +struct nm_v +{ + //! The node contain 3 unsigned long integer for communication computation memory and id + typedef boost::fusion::vector<float,float,float,size_t,size_t,size_t,size_t,long int> type; + + typedef typename memory_traits_inte<type>::type memory_int; + typedef typename memory_traits_lin<type>::type memory_lin; + + //! type of the positional field + typedef float s_type; + + //! Attributes name + struct attributes + { + static const std::string name[]; + }; + + //! The data + type data; + + //! computation property id in boost::fusion::vector + static const unsigned int x = 0; + //! computation property id in boost::fusion::vector + static const unsigned int y = 1; + //! memory property id in boost::fusion::vector + static const unsigned int z = 2; + //! computation property id in boost::fusion::vector + static const unsigned int communication = 3; + //! computation property id in boost::fusion::vector + static const unsigned int computation = 4; + //! memory property id in boost::fusion::vector + static const unsigned int memory = 5; + //! memory property id in boost::fusion::vector + static const unsigned int id = 6; + //! memory property sub_id in boost::fusion::vector + static const unsigned int sub_id = 7; + + //! total number of properties boost::fusion::vector + static const unsigned int max_prop = 8; +}; + +const std::string nm_v::attributes::name[] = {"x","y","z","communication","computation","memory","id","sub_id"}; + +/*! \brief sub-domain edge graph node + * + */ + +struct nm_e +{ + //! The node contain 3 unsigned long integer for comunication computation and memory + typedef boost::fusion::vector<size_t> type; + + typedef typename memory_traits_inte<type>::type memory_int; + typedef typename memory_traits_lin<type>::type memory_lin; + + //! Attributes name + struct attributes + { + static const std::string name[]; + }; + + //! The data + type data; + + //! computation property id in boost::fusion::vector + static const unsigned int communication = 0; + //! total number of properties boost::fusion::vector + static const unsigned int max_prop = 1; +}; + +const std::string nm_e::attributes::name[] = {"communication"}; + +/*! \brief Reduced sub-domain vertex graph node + * + * It contain only the processor id for each node + * + */ + +struct nm_part_v +{ + //! The node contain 3 unsigned long integer for comunication computation and memory + typedef boost::fusion::vector<size_t,size_t> type; + + typedef typename memory_traits_inte<type>::type memory_int; + typedef typename memory_traits_lin<type>::type memory_lin; + + typedef float s_type; + + //! Attributes name + struct attributes + { + static const std::string name[]; + }; + + //! The data + + type data; + + //! partition id in the boost::fusion::vector + static const unsigned int id = 0; + //! partition id in the boost::fusion::vector + static const unsigned int sub_id = 1; + + //! total number of properties + static const unsigned int max_prop = 2; +}; + +const std::string nm_part_v::attributes::name[] = {"id"}; + +/*! \brief Reduced edge graph node + * + * It contain only the communication between nodes + * + */ + +struct nm_part_e +{ + //! The node contain 3 unsigned long integer for comunication computation and memory + typedef boost::fusion::vector<> type; + + typedef typename memory_traits_inte<type>::type memory_int; + typedef typename memory_traits_lin<type>::type memory_lin; + + //! The data + + type data; + + //! total number of properties + static const unsigned int max_prop = 0; +}; + +#endif diff --git a/src/Vector/vector_dist.hpp b/src/Vector/vector_dist.hpp index f84e9cd87527826be7031247f8fcf71ea0826632..63d3d667e72971e81bfc45df8712c126fa449abb 100644 --- a/src/Vector/vector_dist.hpp +++ b/src/Vector/vector_dist.hpp @@ -8,14 +8,16 @@ #ifndef VECTOR_HPP_ #define VECTOR_HPP_ +#include "VCluster.hpp" #include "Space/space.hpp" +#include "Vector/vector_dist_iterator.hpp" +#include "Space/Shape/Box.hpp" +#include "Vector/vector_dist_key.hpp" #define NO_ID false #define ID true /*! \brief Distributed vector - * - * * */ @@ -27,11 +29,11 @@ private: //! Space Decomposition Decomposition dec; - // Space for space position - grid_dist_id<1,space,Decomposition,Memory> pos; + // Particle position vector for each subdomain the last one is the unassigned particles vector + Vcluster_object_array<openfpm::vector<space>> v_pos; - // Space for properties - grid_dist_id<1,prop,Decomposition,Memory> prp; + // Particle properties vector for each subdomain the last one is the unassigned particles vector + Vcluster_object_array<openfpm::vector<prop>> v_prp; // Virtual cluster Vcluster & v_cl; @@ -43,14 +45,18 @@ public: * \param number of elements * */ - vector_dist(size_t np) + vector_dist(size_t np, Box box) :dec(Decomposition(*global_v_cluster)),v_cl(*global_v_cluster) { + // Allocate unassigned particles vectors + v_pos = v_cl.template allocate<openfpm::vector<space>>(1); + v_prp = v_cl.template allocate<openfpm::vector<prop>>(1); + // resize the position vector - pos.resize(np); + v_pos.get(0).resize(np); // resize the properties vector - prp.resize(np); + v_prp.get(0).resize(np); // Create a valid decomposition of the space // Get the number of processor and calculate the number of sub-domain @@ -60,12 +66,12 @@ public: // 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));} + size_t div[space::max_prop]; + for (int i = 0 ; i < space::max_prop ; i++) + {div[i] = round_big_2(pow(n_sub,1.0/space::max_prop));} // Create the sub-domains - dec.setParameters(div); + dec.setParameters(div,box); } /*! \brief Get position of an object @@ -73,9 +79,9 @@ public: * \param vec_key vector element * */ - template<unsigned int id> auto getPos(size_t vec_key) -> decltype(pos.template get<id>(vec_key)) + template<unsigned int id> inline auto getPos(vect_dist_key_dx vec_key) -> decltype(v_pos.get(vec_key.getSub()).template get<id>(vec_key.getKey())) { - return pos.template get<id>(vec_key); + return v_pos.get(vec_key.getSub()).template get<id>(vec_key.getKey()); } /*! \brief Get the property of the object @@ -83,9 +89,9 @@ public: * \param vec_key vector element * */ - template<unsigned int id> auto getProp(size_t vec_key) -> decltype(prp.template get<id>(vec_key)) + template<unsigned int id> inline auto getProp(vect_dist_key_dx vec_key) -> decltype(v_prp.get(vec_key.v_c).template get<id>(vec_key.key)) { - return prp.template get<id>(vec_key); + return v_prp.get(vec_key.v_c).template get<id>(vec_key.key); } /*! \brief It communicate the particle to the respective processor @@ -93,29 +99,26 @@ public: */ 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()]); + // Unassigned particle vector, is always the last one + size_t up_v = v_pos.size()-1; // 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()); + openfpm::vector<size_t> lbl_p(v_pos.size()); // It contain the list of the processors it should to communicate openfpm::vector<size_t> p_list; - auto it = pos.getIterator(); + auto it = v_pos.get(up_v).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)); + size_t p_id = dec.processorID(v_pos.get(up_v).get(key)); lbl_p.get(key) = p_id; @@ -126,6 +129,27 @@ public: } } + /*! \brief Get the iterator across the position of the particles + * + * \return an iterator + * + */ + vector_dist_iterator<openfpm::vector<space>> getIterator() + { + return vector_dist_iterator<openfpm::vector<space>>(v_pos); + } + + /*! \brief Get the iterator across the properties of the particles + * + * \return an iterator + * + */ + vector_dist_iterator<openfpm::vector<space>> getPropIterator() + { + return vector_dist_iterator<openfpm::vector<prop>>(v_prp); + } + + }; diff --git a/src/Vector/vector_dist_iterator.hpp b/src/Vector/vector_dist_iterator.hpp index 9ac4f9207bf4cb6c9f1aa2e0b3e1aca94318bfd6..10863afe9ddf12e5df43a52892e9571767b7b24f 100644 --- a/src/Vector/vector_dist_iterator.hpp +++ b/src/Vector/vector_dist_iterator.hpp @@ -8,9 +8,10 @@ #ifndef VECTOR_DIST_ITERATOR_HPP_ #define VECTOR_DIST_ITERATOR_HPP_ +#include "vector_dist_key.hpp" #include "VCluster.hpp" -template<unsigned int dim, typename device_v> +template<typename device_v> class vector_dist_iterator { //! vector list counter @@ -44,7 +45,7 @@ class vector_dist_iterator * assign * */ - vector_dist_iterator<dim,device_v> & operator=(const vector_dist_iterator<dim,device_v> & vdi) + vector_dist_iterator<device_v> & operator=(const vector_dist_iterator<device_v> & vdi) { v_c = vdi.v_c; vList = vdi.vList; @@ -59,13 +60,13 @@ class vector_dist_iterator * */ - vector_dist_iterator<dim,device_v> operator++() + vector_dist_iterator<device_v> operator++() { ++v_it; // check if a_it is at the end - if (v_it.isNext() == true) + if (v_it < vList.get(v_c).size()) return *this; else { @@ -76,7 +77,7 @@ class vector_dist_iterator // get the next grid iterator if (v_c < vList.size()) - v_it = vList[v_c].getDomainIterator(); + v_it = 0; } return *this; @@ -103,9 +104,9 @@ class vector_dist_iterator * \return the actual key * */ - size_t get() + vect_dist_key_dx get() { - return vect_dist_key_dx<dim>(v_c,v_it.get()); + return vect_dist_key_dx(v_c,v_it); } }; diff --git a/src/Vector/vector_dist_key.hpp b/src/Vector/vector_dist_key.hpp index e367f7c4cde3627e5d50c0c39c91da03667a0a21..a79bc680305a355857393efdfc29b13e29d03029 100644 --- a/src/Vector/vector_dist_key.hpp +++ b/src/Vector/vector_dist_key.hpp @@ -16,7 +16,6 @@ * */ -template<unsigned int dim> class vect_dist_key_dx { //! grid list counter diff --git a/src/Vector/vector_dist_unit_test.hpp b/src/Vector/vector_dist_unit_test.hpp index 896e6d312e8c143bb5807b8e0e6cfaef77029db5..784c58f75baf7c013e9be1a5bab9d0440bca9c52 100644 --- a/src/Vector/vector_dist_unit_test.hpp +++ b/src/Vector/vector_dist_unit_test.hpp @@ -8,22 +8,35 @@ #ifndef VECTOR_DIST_UNIT_TEST_HPP_ #define VECTOR_DIST_UNIT_TEST_HPP_ +#include <random> #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); + Box<2,float> box({0.0,0.0},{1.0,1.0}); + vector_dist<space<2,float>, Point_test<float>, Box<2,float>, CartDecomposition<2,float> > vd(4096,box); + + // randomized + size_t seed = global_v_cluster->getProcessUnitID(); + srand (time(NULL)+seed); auto it = vd.getIterator(); while (it.isNext()) { + auto key = it.get(); + vd.template getPos<space<2,float>::x>(key) = (rand()/(double)(RAND_MAX)); + vd.template getPos<space<2,float>::y>(key) = (rand()/(double)(RAND_MAX)); ++it; } + + + + // collect weight } BOOST_AUTO_TEST_SUITE_END()