From 3f1ee245d1a5ee943aaea2413594f72d03546d3b Mon Sep 17 00:00:00 2001 From: Pietro Incardona <incardon@mpi-cbg.de> Date: Fri, 9 Oct 2015 00:36:27 +0200 Subject: [PATCH] Fixing documentation of distributed vector --- openfpm_numerics | 2 +- src/Decomposition/DistModel.hpp | 30 ------ src/Makefile.am | 2 +- src/Vector/vector_dist.hpp | 138 +++++++++++++-------------- src/Vector/vector_dist_unit_test.hpp | 31 +++--- 5 files changed, 90 insertions(+), 113 deletions(-) delete mode 100644 src/Decomposition/DistModel.hpp diff --git a/openfpm_numerics b/openfpm_numerics index 0c51112a..8940976d 160000 --- a/openfpm_numerics +++ b/openfpm_numerics @@ -1 +1 @@ -Subproject commit 0c51112a6a0808e7209329de9d4639c1e440a815 +Subproject commit 8940976df9020348e7c40b0c622bd1b0b9a23827 diff --git a/src/Decomposition/DistModel.hpp b/src/Decomposition/DistModel.hpp deleted file mode 100644 index 5980dc8a..00000000 --- a/src/Decomposition/DistModel.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#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 diff --git a/src/Makefile.am b/src/Makefile.am index d96f3e68..f36310c8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,7 +6,7 @@ pdata_CXXFLAGS = $(CUDA_CFLAGS) $(INCLUDES_PATH) $(METIS_INCLUDE) $(BOOST_CPPFLA pdata_CFLAGS = $(CUDA_CFLAGS) pdata_LDADD = $(LINKLIBS) -lmetis nobase_include_HEADERS = Decomposition/CartDecomposition.hpp Decomposition/common.hpp Decomposition/Decomposition.hpp Decomposition/ie_ghost.hpp \ - Decomposition/nn_processor.hpp Decomposition/DistModel.hpp Decomposition/ie_loc_ghost.hpp Decomposition/ORB.hpp \ + Decomposition/nn_processor.hpp Decomposition/ie_loc_ghost.hpp Decomposition/ORB.hpp \ Graph/CartesianGraphFactory.hpp \ Grid/grid_dist_id.hpp Grid/grid_dist_id_iterator.hpp Grid/grid_dist_key.hpp \ Vector/vector_dist.hpp Vector/vector_dist_iterator.hpp Vector/vector_dist_key.hpp \ diff --git a/src/Vector/vector_dist.hpp b/src/Vector/vector_dist.hpp index 68111862..40c2fe41 100644 --- a/src/Vector/vector_dist.hpp +++ b/src/Vector/vector_dist.hpp @@ -42,46 +42,58 @@ /*! \brief Distributed vector * - * \tparam dim Dimensionality of the space where the object live - * \tparam St type of space - * \tparam prop properties the object store + * This class reppresent a distributed vector, the distribution of the structure + * is based on the positional information of the elements the vector store + * + * ## Create a vector of random elements on each processor 2D + * \snippet vector_dist_unit_test.hpp Create a vector of random elements on each processor 2D + * + * ## Create a vector of random elements on each processor 3D + * \snippet vector_dist_unit_test.hpp Create a vector of random elements on each processor 3D + * + * ## Create a vector of elements distributed on a grid like way + * \snippet vector_dist_unit_test.hpp Create a vector of elements distributed on a grid like way + * + * ## Redistribute the particles and sync the ghost properties + * \snippet vector_dist_unit_test.hpp Redistribute the particles and sync the ghost properties + * + * \tparam dim Dimensionality of the space where the elements lives + * \tparam St type of space float, double ... + * \tparam prop properties the vector element store in OpenFPM data structure format + * \tparam Decomposition Decomposition strategy to use CartDecomposition ... + * \tparam Memory Memory pool where store the information HeapMemory ... * */ -template<unsigned int dim, typename St, typename prop, typename Decomposition , typename Memory=HeapMemory, bool with_id=false> +template<unsigned int dim, typename St, typename prop, typename Decomposition , typename Memory=HeapMemory> class vector_dist { private: - // Ghost marker, all the particle with id > g_m are ghost all with g_m < are real particle + //! Ghost marker, all the particle with id > g_m are ghost all with g_m < are real particle size_t g_m = 0; - // indicate from where the ghost particle start in the vector - size_t ghost_pointer; - //! Space Decomposition Decomposition dec; - // Particle position vector for each sub-domain the last one is the unassigned particles vector + //! Particle position vector, (It has 2 elements) the first has real particles assigned to a processor + //! the second element contain unassigned particles Vcluster_object_array<openfpm::vector<Point<dim,St>>> v_pos; - // Particle properties vector for each sub-domain the last one is the unassigned particles vector + //! Particle properties vector, (It has 2 elements) the first has real particles assigned to a processor + //! the second element contain unassigned particles Vcluster_object_array<openfpm::vector<prop>> v_prp; - // Virtual cluster + //! Virtual cluster Vcluster & v_cl; - // Geometrical cell list - CellList<dim,St,FAST> geo_cell; - - // Label particles - - public: /*! \brief Constructor * - * \param Global number of elements + * \param np number of elements + * \param box domain where the vector of elements live + * \param g Ghost margins * */ vector_dist(size_t np, Box<dim,St> box, Ghost<dim,St> g = Ghost<dim,St>()) @@ -122,22 +134,8 @@ public: // Create the sub-domains dec.setParameters(div,box,g); - // Get the bounding box containing the processor domain - const ::Box<dim,St> & bbound = dec.getProcessorBounds(); - - const ::Box<dim,St> & smallest_unit = dec.getSmallestSubdivision(); - - // convert spacing divisions - size_t n_g[dim]; - - for (size_t i = 0 ; i < dim ; i++) - n_g[i] = (bbound.getHigh(i) - bbound.getLow(i)) / smallest_unit.getHigh(i); - Point<dim,St> p; p.zero(); - - // Initialize the geo cell list - geo_cell.Initialize(box,n_g,p,8); } /*! \brief Get the number of minimum sub-domain @@ -160,9 +158,13 @@ public: return v_pos.get(0).size(); } - /*! \brief Get position of an object + /*! \brief Get the position of an element * - * \param vec_key vector element + * see the vector_dist iterator usage to get an element key + * + * \param vec_key element + * + * \return the position of the element in space * */ 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())) @@ -170,10 +172,15 @@ public: return v_pos.get(vec_key.getSub()).template get<id>(vec_key.getKey()); } - /*! \brief Get the property of the object + /*! \brief Get the property of an element * + * see the vector_dist iterator usage to get an element key + * + * \tparam id property id * \param vec_key vector element * + * \return return the selected property of the vector element + * */ template<unsigned int id> inline auto getProp(vect_dist_key_dx vec_key) -> decltype(v_prp.get(vec_key.getSub()).template get<id>(vec_key.getKey())) { @@ -192,20 +199,14 @@ public: openfpm::vector<prop,PreAllocHeapMemory<2>,openfpm::grow_policy_identity> prp; }; - /*! \brief set the ghost - * - * \param g ghost - * - */ - void setGhost() - { - dec.calculateGhostBoxes(); - } - //! It map the processor id with the communication request into map procedure openfpm::vector<size_t> p_map_req; - /*! \brief It communicate the particle to the respective processor + /*! \brief It move all the particles that does not belong to the local processor to the respective processor + * + * In general this function is called after moving the particles to move the + * elements out the local processor. Or just after initialization if each processor + * contain non local particle * */ void map() @@ -399,25 +400,22 @@ public: v_prp.get(0).remove(opart,o_p_id); } - // outgoing particles-id + //! For each adjacent processor outgoing particles-ids openfpm::vector<openfpm::vector<size_t>> opart; - // Each entry contain the size of the ghost sending buffer + //! For each adjacent processor the size of the ghost sending buffer openfpm::vector<size_t> ghost_prc_sz; - // ghost particle labels - openfpm::vector<size_t> ghost_lbl_p; - - // Memory for the ghost sending buffer + //! Sending buffer for the ghost particles properties Memory g_prp_mem; - // Memory for the ghost position sending buffer + //! Sending buffer for the ghost particles position Memory g_pos_mem; - /*! \brief It synchronize getting the ghost particles + /*! \brief It synchronize the properties and position of the ghost particles * - * \prp Properties to get - * \opt options WITH_POSITION, it send also the positional information of the particles + * \tparam prp list of properties to get synchronize + * \param opt options WITH_POSITION, it send also the positional information of the particles * */ template<int... prp> void ghost_get(size_t opt = WITH_POSITION) @@ -613,13 +611,13 @@ public: } } - // Receiving size + //! For each adjacent processor it store the size of the receiving message in byte openfpm::vector<size_t> recv_sz; - // Receiving buffer for particles ghost get + //! For each adjacent processot it store the received message openfpm::vector<HeapMemory> recv_mem_gg; - /*! \brief Call-back to allocate buffer to receive incoming objects (particles) + /*! \brief Call-back to allocate buffer to receive incoming elements (particles) * * \param msg_i message size required to receive from i * \param total_msg message size to receive from all the processors @@ -632,7 +630,7 @@ public: */ static void * msg_alloc_ghost_get(size_t msg_i ,size_t total_msg, size_t total_p, size_t i, size_t ri, void * ptr) { - vector_dist<dim,St,prop,Decomposition,Memory,with_id> * v = static_cast<vector_dist<dim,St,prop,Decomposition,Memory,with_id> *>(ptr); + vector_dist<dim,St,prop,Decomposition,Memory> * v = static_cast<vector_dist<dim,St,prop,Decomposition,Memory> *>(ptr); v->recv_sz.resize(v->dec.getNNProcessors()); v->recv_mem_gg.resize(v->dec.getNNProcessors()); @@ -647,32 +645,32 @@ public: return v->recv_mem_gg.get(lc_id).getPointer(); } - // Heap memory receiver + //! Receive buffer for global communication HeapMemory hp_recv; - // vector v_proc + //! For each message contain the processor from which processor come from openfpm::vector<size_t> v_proc; - // Receive counter + //! Total size of the received buffer size_t recv_cnt; - /*! \brief Message allocation + /*! \brief Call-back to allocate buffer to receive incoming elements (particles) * - * \param message size required to receive from i - * \param total message size to receive from all the processors - * \param the total number of processor want to communicate with you + * \param msg_i size required to receive the message from i + * \param total_msg total size to receive from all the processors + * \param total_p the total number of processor that want to communicate with you * \param i processor id * \param ri request id (it is an id that goes from 0 to total_p, and is unique * every time message_alloc is called) * \param ptr a pointer to the vector_dist structure * - * \return the pointer where to store the message + * \return the pointer where to store the message for the processor i * */ static void * message_alloc_map(size_t msg_i ,size_t total_msg, size_t total_p, size_t i, size_t ri, void * ptr) { // cast the pointer - vector_dist<dim,St,prop,Decomposition,Memory,with_id> * vd = static_cast<vector_dist<dim,St,prop,Decomposition,Memory,with_id> *>(ptr); + vector_dist<dim,St,prop,Decomposition,Memory> * vd = static_cast<vector_dist<dim,St,prop,Decomposition,Memory> *>(ptr); // Resize the receive buffer, and the size of each message buffer vd->hp_recv.resize(total_msg); @@ -743,7 +741,7 @@ public: /*! \brief Output particle position and properties * - * \param File output + * \param out output * \param opt NO_GHOST or WITH_GHOST * * \return if the file has been written correctly diff --git a/src/Vector/vector_dist_unit_test.hpp b/src/Vector/vector_dist_unit_test.hpp index 2f1b974e..b3e45434 100644 --- a/src/Vector/vector_dist_unit_test.hpp +++ b/src/Vector/vector_dist_unit_test.hpp @@ -26,13 +26,15 @@ BOOST_AUTO_TEST_CASE( vector_dist_ghost ) // Convert the request of having a minimum n_sub number of sub-sub domain into grid decompsition of the space size_t sz = CartDecomposition<2,float>::getDefaultGrid(n_sub); + //! [Create a vector of elements distributed on a grid like way] + Box<2,float> box({0.0,0.0},{1.0,1.0}); size_t g_div[]= {sz,sz}; // number of particles size_t np = sz * sz; - // Calculate the number of objects this processor is going to obtain + // Calculate the number of elements this processor is going to obtain size_t p_np = np / v_cl.getProcessingUnits(); // Get non divisible part @@ -41,7 +43,7 @@ BOOST_AUTO_TEST_CASE( vector_dist_ghost ) // Get the offset size_t offset = v_cl.getProcessUnitID() * p_np + std::min(v_cl.getProcessUnitID(),r); - // Distribute the remain objects + // Distribute the remain elements if (v_cl.getProcessUnitID() < r) p_np++; @@ -83,18 +85,19 @@ BOOST_AUTO_TEST_CASE( vector_dist_ghost ) ++it; } - // Both iterators must signal the end, and the number of object in the vector, must the equal to the + //! [Create a vector of elements distributed on a grid like way] + + // Both iterators must signal the end, and the number of elements in the vector, must the equal to the // predicted one BOOST_REQUIRE_EQUAL(v_it.isNext(),false); BOOST_REQUIRE_EQUAL(it.isNext(),false); BOOST_REQUIRE_EQUAL(cobj,p_np); + //! [Redistribute the particles and sync the ghost properties] + // redistribute the particles according to the decomposition vd.map(); - // Fill the scalar with the particle position - const auto & ct = vd.getDecomposition(); - v_it = vd.getIterator(); while (v_it.isNext()) @@ -110,14 +113,10 @@ BOOST_AUTO_TEST_CASE( vector_dist_ghost ) ++v_it; } - //! Output the decomposition - ct.write("."); - // do a ghost get vd.template ghost_get<p::s,p::v>(); - // Debug write the particles with GHOST - vd.write("Particles_with_ghost.csv",WITH_GHOST); + //! [Redistribute the particles and sync the ghost properties] // Get the decomposition const auto & dec = vd.getDecomposition(); @@ -214,6 +213,9 @@ BOOST_AUTO_TEST_CASE( vector_dist_iterator_test_use_2d ) for ( ; k >= 2 ; k-= decrement(k,big_step) ) { BOOST_TEST_CHECKPOINT( "Testing 2D vector k=" << k ); + + //! [Create a vector of random elements on each processor 2D] + Box<2,float> box({0.0,0.0},{1.0,1.0}); vector_dist<2,float, Point_test<float>, CartDecomposition<2,float> > vd(k,box); @@ -231,6 +233,8 @@ BOOST_AUTO_TEST_CASE( vector_dist_iterator_test_use_2d ) vd.map(); + //! [Create a vector of random elements on each processor 2D] + // Check if we have all the local particles size_t cnt = 0; const CartDecomposition<2,float> & ct = vd.getDecomposition(); @@ -278,6 +282,9 @@ BOOST_AUTO_TEST_CASE( vector_dist_iterator_test_use_3d ) for ( ; k >= 2 ; k-= decrement(k,big_step) ) { BOOST_TEST_CHECKPOINT( "Testing 3D vector k=" << k ); + + //! [Create a vector of random elements on each processor 3D] + Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); vector_dist<3,float, Point_test<float>, CartDecomposition<3,float> > vd(k,box); @@ -296,6 +303,8 @@ BOOST_AUTO_TEST_CASE( vector_dist_iterator_test_use_3d ) vd.map(); + //! [Create a vector of random elements on each processor 3D] + // Check if we have all the local particles size_t cnt = 0; const CartDecomposition<3,float> & ct = vd.getDecomposition(); -- GitLab