Commit 3f1ee245 authored by incardon's avatar incardon

Fixing documentation of distributed vector

parent 15f2ca1e
openfpm_numerics @ 8940976d
Subproject commit 0c51112a6a0808e7209329de9d4639c1e440a815
Subproject commit 8940976df9020348e7c40b0c622bd1b0b9a23827
#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
......@@ -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 \
......
......@@ -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
......
......@@ -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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment