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

Fixing documentation of distributed vector

parent 15f2ca1e
No related branches found
No related tags found
No related merge requests found
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();
......
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