diff --git a/src/Decomposition/CartDecomposition.hpp b/src/Decomposition/CartDecomposition.hpp index 8a1c01ed54c08eeea1dd635bc5fe7ae4700e809e..20712b510a8997be6a52bc73569f066223293e5f 100644 --- a/src/Decomposition/CartDecomposition.hpp +++ b/src/Decomposition/CartDecomposition.hpp @@ -27,8 +27,7 @@ /** * \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 + * This class decompose a space into regular hyper-cube subspaces * * \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 ... @@ -38,13 +37,13 @@ * \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 - * - * \note sub-sub-domain portion of space at finer level than the sub-domain (before optimization) - * (or before sub-sub-domain merging) - * \note sub-domain portion of space (after optimization) - * \note near processor sub-domain a sub-domain that live in the a near (or contiguous) processor + * \note sub-sub-domain are the sub-unit produced by the decomposition + * \note sub-domain are the result of merging one or more sub-sub-domain (optimization) + * \note Near processors are the processors adjacent to this processor + * \note near processor sub-domain is a sub-domain that live in the a near (or contiguous) processor + * \note external ghost box are the ghost space of the processors + * \note internal ghost box are the part of ghost of the near processor that intersect the space of the + * processor * */ @@ -63,11 +62,11 @@ class CartDecomposition struct Box_proc { // Intersection between the local sub-domain enlarged by the ghost and the contiguous processor - // sub-domains + // sub-domains (External ghost) openfpm::vector<::Box<dim,T>> bx; // Intersection between the contiguous processor sub-domain enlarged by the ghost with the - // local sub-domain + // local sub-domain (Internal ghost) openfpm::vector<::Box<dim,T>> nbx; @@ -127,28 +126,13 @@ private: //! rectangular domain to decompose Domain<dim,T> domain; - //! Ghost boxes of the processor - //! for each Sub-domain it store the ghost boxes, or - //! the set of boxes that enclose the the ghost space - //! Box cannot overlap, they contain one id that is the - //! processor the information should come from - openfpm::vector< openfpm::vector<Domain<dim,T>> > gh_dom; - - //! Internal boxes of the processor - //! for each Sub-domain it store the boxes enclosing the - //! space that must be communicated when another processor - //! require the ghost - //! Box can overlap, they contain one id that is the - //! processor the information should be communicated to - openfpm::vector< openfpm::vector< Domain<dim,T>> > int_box; - //! Box Spacing T spacing[dim]; //! Runtime virtual cluster machine Vcluster & v_cl; - //! Structure that store the geometrical information about intersection between the local sub-domain + //! Cell-list that store the geometrical information about the intersection between the local sub-domain //! and the near processor sub-domains CellList<dim,T,FAST> geo_cell; @@ -434,13 +418,14 @@ public: openfpm::vector<size_t> ids; /*! \brief Given a position it return if the position belong to any neighborhood processor ghost + * (Internal ghost) * * \param p Particle position * * \param return the processor ids * */ - const openfpm::vector<size_t> ghost_processorID(Point<dim,T> & p) + inline const openfpm::vector<size_t> ghost_processorID(Point<dim,T> & p) { ids.clear(); @@ -464,6 +449,7 @@ public: } /*! \brief Given a position it return if the position belong to any neighborhood processor ghost + * (Internal ghost) * * \param p Particle position * @@ -497,7 +483,7 @@ public: // below as a linear vector openfpm::vector<::Box<dim,T>> vb_int; - /*! It calculate the ghost boxes and internal boxes + /*! It calculate the internal ghost boxes * * Example: Processor 10 calculate * B8_0 B9_0 B9_1 and B5_0 @@ -529,7 +515,7 @@ public: +-----------------------------------+ and also - G8_0 G9_0 G9_1 G5_0 + G8_0 G9_0 G9_1 G5_0 (External ghost boxes) +----------------------------------------------------+ | | @@ -628,7 +614,7 @@ p1[0]<-----+ +----> p2[0] // Intersect all the local sub-domains with the sub-domains of the contiguous processors // Get the sub-domains of the near processors - v_cl.sendrecvMultipleMessages(nn_processors,boxes,CartDecomposition<dim,T,device_l,Memory,Domain,data_s>::message_alloc, this ,NEED_ALL_SIZE); + v_cl.sendrecvMultipleMessagesNBX(nn_processors,boxes,CartDecomposition<dim,T,device_l,Memory,Domain,data_s>::message_alloc, this ,NEED_ALL_SIZE); // ++++++++++++++++++++++++++++++++++++++++++ Check received boxes @@ -843,65 +829,6 @@ p1[0]<-----+ +----> p2[0] 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 @@ -1087,10 +1014,10 @@ p1[0]<-----+ +----> p2[0] * \return number of processors * */ - inline size_t labelPointNp(Point<dim,T> & p) +/* inline size_t labelPointNp(Point<dim,T> & p) { return geo_cell.getNelements(geo_cell.getCell(p)); - } + }*/ /*! \brief It return the label point cell * @@ -1100,34 +1027,30 @@ p1[0]<-----+ +----> p2[0] * \return cell-id * */ - inline size_t labelPointCell(Point<dim,T> & p) +/* inline size_t labelPointCell(Point<dim,T> & p) { return geo_cell.getCell(p); - } + }*/ - /*! \brief Fill the ghost buffer + /*! \brief get the number of near processors * - * \tparam one or more properties to get + * \return the number of near processors * */ -/* template<unsigned int ...i> void ghost_get() + inline size_t getNNProcessors() { - // first check if a local particle must be sent to another processor - for (size_t i = 0 ; i < ; i++) - { - - } - }*/ + return nn_processors.size(); + } - /*! \brief Fill the ghost buffer + /*! \brief Give the internal ghost box id, it return at which processor it belong * - * \tparam one or more properties to get + * \return the number of near processors * */ -/* template<unsigned int ...i> void ghost_put() + inline size_t getGhostBoxProcessor(size_t b_id) { - - }*/ + return vb_int.get(b_id).proc; + } }; diff --git a/src/Graph/CartesianGraphFactory.hpp b/src/Graph/CartesianGraphFactory.hpp index 5d2a72b631348d1fbd9c05d987be332276b54ef2..e8c2218d3095a6a881f85ba643bb951ddcd90b0d 100644 --- a/src/Graph/CartesianGraphFactory.hpp +++ b/src/Graph/CartesianGraphFactory.hpp @@ -129,7 +129,7 @@ public: auto obj = gp.vertex(g.LinId(key)); // vertex spatial properties functor - fill_prop<dim,T,decltype(gp.vertex(g.LinId(key))), typename to_boost_mpl<pos...>::type, sizeof...(pos) == 0 > flp(obj,szd,key); + fill_prop<dim,T,decltype(gp.vertex(g.LinId(key))), typename to_boost_vmpl<pos...>::type, sizeof...(pos) == 0 > flp(obj,szd,key); // fill properties @@ -239,7 +239,7 @@ public: auto obj = gp.vertex(g.LinId(key)); // vertex spatial properties functor - fill_prop<dim,T,decltype(gp.vertex(g.LinId(key))), typename to_boost_mpl<pos...>::type, sizeof...(pos) == 0 > flp(obj,szd,key); + fill_prop<dim,T,decltype(gp.vertex(g.LinId(key))), typename to_boost_vmpl<pos...>::type, sizeof...(pos) == 0 > flp(obj,szd,key); // fill properties diff --git a/src/Vector/vector_dist.hpp b/src/Vector/vector_dist.hpp index d990938a08da8239ddeff4b9bb17f78452c32743..e59992373166c35f0a3af518759c03d0190678d8 100644 --- a/src/Vector/vector_dist.hpp +++ b/src/Vector/vector_dist.hpp @@ -17,7 +17,7 @@ #include "memory/PtrMemory.hpp" #include "NN/CellList/CellList.hpp" #include "common.hpp" -#include "util/vector_creator.hpp" +#include "util/object_util.hpp" #include "memory/ExtPreAlloc.hpp" #define NO_ID false @@ -29,22 +29,6 @@ #define INTERNAL 0 #define NO_POSITION 1 -/*! \brief This is a container for the sending buffers - * - * It is used in ghost_get to create a particular object with the properties selected - * - * \tparam Is a boost::fusion::vector with the properties selected - * - * - */ -template<typename v> -class buff_com -{ - typedef v type; - - const int max_prop = boost::fusion::result_of::size<v>::value; -}; - /*! \brief Distributed vector * */ @@ -313,7 +297,7 @@ public: // Send and receive the particles recv_cnt = 0; - v_cl.sendrecvMultipleMessages(prc_sz_r.size(),&p_map.get(0), &prc_sz_r.get(0), &prc_r.get(0) , &ptr.get(0) , vector_dist::message_alloc, this ,NEED_ALL_SIZE); + v_cl.sendrecvMultipleMessagesPCX(prc_sz_r.size(),&p_map.get(0), &prc_sz_r.get(0), &prc_r.get(0) , &ptr.get(0) , vector_dist::message_alloc, this ,NEED_ALL_SIZE); // overwrite the outcoming particle with the incoming particle and resize the vectors @@ -378,6 +362,8 @@ public: // Memory for the ghost Memory g_pos_mem; + + /*! \brief It synchronize getting the ghost particles * * \prp Properties to get @@ -387,10 +373,9 @@ public: */ template<int... prp> void ghost_get(size_t opt = NONE) { - // Create the ghost buffer + // Buffer that containe the number of elements for each processor ghost_prc_sz.clear(); - ghost_lbl_p.clear(); - ghost_lbl_p.resize(v_pos.get(INTERNAL).size()); + ghost_prc_sz.resize(dec.getNNProcessors()); // Label the internal (assigned) particles auto it = v_pos.get(INTERNAL).getIterator(); @@ -400,20 +385,20 @@ public: { auto key = it.get(); - size_t p_id = dec.ghost_processorID(v_pos.get(INTERNAL).get(key)); - - ghost_lbl_p.get(key) = p_id; + const openfpm::vector<size_t> & vp_id = dec.ghost_processorID(v_pos.get(INTERNAL).get(key)); - // It has to communicate - if (p_id != v_cl.getProcessUnitID()) + for (size_t i = 0 ; i < vp_id.size() ; i++) { - size_t id = dec.ProcToID(p_id); + // Box id + size_t b_id = vp_id.get(i); + // processor id + size_t p_id = dec.getGhostBoxProcessor(b_id); // add particle to communicate - ghost_prc_sz.get(id)++; + ghost_prc_sz.get(p_id)++; - opart.get(id).add(key); + opart.get(p_id).add(key); } ++it; @@ -423,17 +408,17 @@ public: size_t n_ele = 0; // sequence of pre-allocation pattern - openfpm::vector<size_t> pap; + std::vector<size_t> pap; // Calculate the total size required for the sending buffer for ( size_t i = 0 ; i < ghost_prc_sz.size() ; i++ ) { - pap.add(ghost_prc_sz.get(i)*sizeof(vector_creator<Point_test<float>::type,prp...>::type)); + pap.push_back(ghost_prc_sz.get(i)*sizeof(typename object_creator<Point_test<float>::type,prp...>::type)); n_ele += ghost_prc_sz.get(i); } // resize the property buffer memory - g_prp_mem.resize(n_ele * sizeof(typename vector_creator<Point_test<float>::type,prp...>::type)); + g_prp_mem.resize(n_ele * sizeof(typename object_creator<Point_test<float>::type,prp...>::type)); // resize the position buffer memory if (opt != NO_POSITION) g_pos_mem.resize(n_ele * sizeof(point)); @@ -441,10 +426,10 @@ public: ExtPreAlloc<Memory> prAlloc(pap,g_prp_mem); // definition of a property object based on the property selected - typedef typename vector_creator<Point_test<float>::type,prp...>::type property_object; + typedef typename object_creator<Point_test<float>::type,prp...>::type property_object; // definition of the send vector for each processor - typedef openfpm::vector<property_object,openfpm::device_cpu<prop>,ExtPreAlloc<Memory>> send_vector; + typedef openfpm::vector<::object<property_object>,openfpm::device_cpu<object<property_object>>,ExtPreAlloc<Memory>> send_vector; // create a vector of send vector (ExtPreAlloc warrant that all the created vector are contiguous) openfpm::vector<send_vector> g_send; @@ -465,30 +450,55 @@ public: { for (size_t j = 0 ; j < opart.get(i).size() ; j++) { - g_send.get(i).get(j) = v_prp.get(INTERNAL).get(opart.get(i).get(j)); + // source object type + typedef encapc<1,prop,typename openfpm::vector<prop>::memory_t> encap_src; + // destination object type + typedef encapc<1,::object<property_object>,typename openfpm::vector<::object<property_object>>::memory_t> encap_dst; + + // Copy only the selected properties + object_copy<encap_src,encap_dst,ENCAP,prp...>(v_prp.get(INTERNAL).get(opart.get(i).get(j)),g_send.get(i).get(j)); } } // Create the buffer for particle position - // definition of the send vector for each processor - typedef openfpm::vector<property_object,openfpm::device_cpu<point>,ExtPreAlloc<Memory>> send_pos_vector; + // definition of the send vector for position for each processor + typedef openfpm::vector<point,openfpm::device_cpu<point>,ExtPreAlloc<Memory>> send_pos_vector; - openfpm::vector<point> g_pos_send; + openfpm::vector<send_pos_vector> g_pos_send; if (opt != NO_POSITION) { + // create a number of send buffer equal to the near processors + g_pos_send.resize(ghost_prc_sz.size()); + for (size_t i = 0 ; i < g_pos_send.size() ; i++) + { + // set the preallocated memory to ensure contiguity + g_pos_send.get(i).setMemory(prAlloc); + + // resize the sending vector (No allocation is produced) + g_pos_send.get(i).resize(ghost_prc_sz.get(i)); + } + // Fill the send buffer for ( size_t i = 0 ; i < opart.size() ; i++ ) { for (size_t j = 0 ; j < opart.get(i).size() ; j++) { - g_send.get(i).get(j) = v_pos.get(INTERNAL).get(opart.get(i).get(j)); + g_pos_send.get(i).set(j,v_pos.get(INTERNAL).get(opart.get(i).get(j))); } } } - // Send receive the particles information + // Create processor buffer pattern + + openfpm::vector<size_t> prc; + for (size_t i = 0 ; i < opart.size() ; i++) + { + prc.add(dec.IDtoProc(i)); + } + // Send receive the particles information +// v_cl.sendRecvMultipleMessageNBX(); // add the received particles to the vector