Commit 6bcf7186 authored by incardon's avatar incardon

Complex properties with serialization completed

parent 664bf178
......@@ -5,17 +5,21 @@ CC=mpic++
LDIR =
OBJ = main.o
OBJ_SER = main_ser.o
%.o: %.cpp
$(CC) -O3 -c --std=c++11 -o $@ $< $(INCLUDE_PATH)
vect: $(OBJ)
vect_cp: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS_PATH) $(LIBS)
all: vect
vect_ser: $(OBJ_SER)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS_PATH) $(LIBS)
all: vect_cp vect_ser
run: all
source $$HOME/openfpm_vars; mpirun -np 2 ./vect
source $$HOME/openfpm_vars && mpirun -np 2 ./vect_cp && mpirun -np 2 ./vect_ser
.PHONY: clean all run
......
/*! \page Vector_4_cp Vector 4 complex properties and serialization
*
* \subpage Vector_4_complex_prop
* \subpage Vector_4_complex_prop_ser
*
*/
/*!
*
* \page Vector_4_complex_prop Vector 4 complex property
* \page Vector_4_complex_prop Vector 4 complex properties
*
*
* [TOC]
*
*
* # Vector 4 complex property # {#vector_example_cp}
* # Vector 4 complex properties # {#vector_example_cp}
*
*
* This example show how we can use complex properties in a vector
......@@ -19,7 +26,7 @@ int main(int argc, char* argv[])
{
/*!
*
* \page Vector_4_complex_prop Vector 4 complex property
* \page Vector_4_complex_prop Vector 4 complex properties
*
*
* ## Initialization and vector creation ##
......@@ -29,13 +36,36 @@ int main(int argc, char* argv[])
*
* \snippet Vector/4_complex_prop/main.cpp vect create
*
* In This this particular case every particle carry a scalar,
* In this this particular case every particle carry a scalar,
* a vector in form of float[3], a Point, a list
* in form of vector of float and a list of custom structures
* in form of vector of float and a list of custom structures, and a vector of vector.
* In general particles can have properties of arbitrary complexity.
*
* \warning For arbitrary complexity mean that we can use any openfpm data structure with and arbitrary nested complexity.
* For example a openfpm::vector<aggregate<grid_cpu<openfpm::vector<aggregate<double,double[3]>>>,openfpm::vector<float>> is valid
* \verbatim
particle
*
vector
/ \
/ \
grid vector<float>
/\
/ \
double double[3]
* \endverbatim
*
* Our custom data-structure A is defined below. Note that this data-structure
* does not have pointers
*
* \snippet Vector/4_complex_prop/main.cpp struct A
*
*
* \warning custom data structure are allowed only if they does not have pointer.
* In case they have pointer we have to define how to serialize our data-structure
*
*/
// initialize the library
......@@ -82,20 +112,24 @@ int main(int argc, char* argv[])
// A listA
constexpr int listA = 4;
// A list of list
constexpr int listlist = 5;
//! \cond [vect create] \endcond
vector_dist<2,float, aggregate<float,
float[3],
Point<3,double>,
openfpm::vector<float>,
openfpm::vector<A>>>
openfpm::vector<A>,
openfpm::vector<openfpm::vector<float>>> >
vd(4096,domain,bc,g);
//! \cond [vect create] \endcond
/*!
*
* \page Vector_4_complex_prop Vector 4 complex property
* \page Vector_4_complex_prop Vector 4 complex properties
*
*
* ## Assign values to properties ##
......@@ -135,7 +169,7 @@ int main(int argc, char* argv[])
vd.getProp<point>(p).get(1) = 1.0;
vd.getProp<point>(p).get(2) = 1.0;
size_t n_cp = (float)10 * rand()/RAND_MAX;
size_t n_cp = (float)10.0 * rand()/RAND_MAX;
vd.getProp<listA>(p).resize(n_cp);
......@@ -146,10 +180,17 @@ int main(int argc, char* argv[])
vd.getProp<list>(p).add(i + 30);
vd.getProp<listA>(p).get(i) = A(i+10.0,i+20.0);
vd.getProp<listA>(p).get(i) = A(i+30.0,i+40.0);
vd.getProp<listA>(p).get(i) = A(i+50.0,i+60.0);
}
vd.getProp<listlist>(p).resize(2);
vd.getProp<listlist>(p).get(0).resize(2);
vd.getProp<listlist>(p).get(1).resize(2);
vd.getProp<listlist>(p).get(0).get(0) = 1.0;
vd.getProp<listlist>(p).get(0).get(1) = 2.0;
vd.getProp<listlist>(p).get(1).get(0) = 3.0;
vd.getProp<listlist>(p).get(1).get(1) = 4.0;
// next particle
++it;
}
......@@ -158,19 +199,15 @@ int main(int argc, char* argv[])
/*!
*
* \page Vector_4_complex_prop Vector 4 complex property
* \page Vector_4_complex_prop Vector 4 complex properties
*
*
* ## Mapping and ghost_get ##
*
* Particles are redistributed across processors but only the scalar,vector and the point
* are communicated (properties 0,1,2). A lot of time complex properties can be recomputed and
* communicate them is not a good idea. The same concept also apply for ghost_get
*
* \note OpenFPM <= 0.5.0 cannot communicate complex properties like a vector or other structure
* that are not POD object
*
* \note OpenFPM > 0.5.0 Does not have such limitation
* Particles are redistributed across processors all properties are communicated but instead of
* using map we use map_list that we can use to select properties.
* A lot of time complex properties can be recomputed and communicate them is not a good idea.
* The same concept also apply for ghost_get. In general we choose which properties to communicate
*
*
* \snippet Vector/4_complex_prop/main.cpp vect map ghost
......@@ -181,16 +218,16 @@ int main(int argc, char* argv[])
// Particles are redistribued across the processors but only the scalar,vector, and point properties
// are transfert
vd.map_list<scalar,vector,point>();
vd.map_list<scalar,vector,point,list,listA,listlist>();
// Synchronize the ghost
vd.ghost_get<scalar,vector,point>();
vd.ghost_get<scalar,vector,point,listA,listlist>();
//! \cond [vect map ghost] \endcond
/*!
*
* \page Vector_4_complex_prop Vector 4 complex property
* \page Vector_4_complex_prop Vector 4 complex properties
*
*
* ## Output and VTK visualization ##
......@@ -209,7 +246,44 @@ int main(int argc, char* argv[])
//! \cond [vtk] \endcond
/*!
* \page Vector_4_complex_prop Vector 4 complex property
*
* \page Vector_4_complex_prop Vector 4 complex properties
*
* ## Print 4 particles in the ghost area ##
*
* Here we print that the first 4 particles to show that the list of A and the list of list are filled
* and the ghosts contain the correct information
*
* \snippet Vector/4_complex_prop/main.cpp print ghost info
*
*/
//! \cond [print ghost info] \endcond
size_t fg = vd.size_local();
Vcluster & v_cl = create_vcluster();
if (v_cl.getProcessUnitID() == 0)
{
for ( ; fg < vd.size_local()+4 ; fg++)
{
std::cout << "List of A" << std::endl;
for (size_t i = 0 ; i < vd.getProp<listA>(fg).size() ; i++)
std::cout << "Element: " << i << " p1=" << vd.getProp<listA>(fg).get(i).p1 << " p2=" << vd.getProp<listA>(fg).get(i).p2 << std::endl;
std::cout << "List of list" << std::endl;
for (size_t i = 0 ; i < vd.getProp<listlist>(fg).size() ; i++)
{
for (size_t j = 0 ; j < vd.getProp<listlist>(fg).get(i).size() ; j++)
std::cout << "Element: " << i << " " << j << " " << vd.getProp<listlist>(fg).get(i).get(j) << std::endl;
}
}
}
//! \cond [print ghost info] \endcond
/*!
* \page Vector_4_complex_prop Vector 4 complex properties
*
* ## Finalize ## {#finalize}
*
......@@ -226,7 +300,7 @@ int main(int argc, char* argv[])
//! \cond [finalize] \endcond
/*!
* \page Vector_4_complex_prop Vector 4 complex property
* \page Vector_4_complex_prop Vector 4 complex properties
*
* # Full code # {#code}
*
......
openfpm_data @ f378ee11
Subproject commit dbfc39c70904fa40ac52d71e784cd6f54283f578
Subproject commit f378ee11c3aa2be8d0fde9fe5308d86d1d705aa7
......@@ -38,7 +38,7 @@ PROJECT_NAME = "OpenFPM_pdata"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 0.5.0
PROJECT_NUMBER = 0.5.1
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
......
......@@ -84,6 +84,67 @@ class vector_dist_comm
//! replicated ghost particles that are local
size_t lg_m;
//! process the particle with properties
struct proc_without_prp
{
template<typename T1, typename T2> inline static void proc(size_t lbl, size_t cnt, size_t id, T1 & v_prp, T2 & m_prp)
{
m_prp.get(lbl).set(cnt, v_prp.get(id));
}
};
template<typename prp_object, int ... prp>
struct proc_with_prp
{
template<typename T1, typename T2> inline static void proc(size_t lbl, size_t cnt, size_t id, T1 & v_prp, T2 & m_prp)
{
// source object type
typedef encapc<1, prop, typename openfpm::vector<prop>::layout_type> encap_src;
// destination object type
typedef encapc<1, prp_object, typename openfpm::vector<prp_object>::layout_type> encap_dst;
// Copy only the selected properties
object_si_d<encap_src, encap_dst, OBJ_ENCAP, prp...>(v_prp.get(id), m_prp.get(lbl).get(cnt));
}
};
//! It process one particle
template<typename proc_class, typename T1, typename T2, typename T3, typename T4> inline void process_map_particle(size_t i, long int & end, long int & id_end, T1 & m_pos, T2 & m_prp, T3 & v_pos, T4 & v_prp, openfpm::vector<size_t> & cnt)
{
long int prc_id = m_opart.template get<2>(i);
size_t id = m_opart.template get<0>(i);
if (prc_id >= 0)
{
size_t lbl = p_map_req.get(prc_id);
m_pos.get(lbl).set(cnt.get(lbl), v_pos.get(id));
proc_class::proc(lbl,cnt.get(lbl),id,v_prp,m_prp);
cnt.get(lbl)++;
// swap the particle
long int id_valid = get_end_valid(end,id_end);
if (id_valid > 0 && (long int)id < id_valid)
{
v_pos.set(id,v_pos.get(id_valid));
v_prp.set(id,v_prp.get(id_valid));
}
}
else
{
// swap the particle
long int id_valid = get_end_valid(end,id_end);
if (id_valid > 0 && (long int)id < id_valid)
{
v_pos.set(id,v_pos.get(id_valid));
v_prp.set(id,v_prp.get(id_valid));
}
}
}
/*! \brief Return a valid particle starting from end and tracing back
*
* \param end actual opart particle pointer
......@@ -492,21 +553,7 @@ class vector_dist_comm
// Run through all the particles and fill the sending buffer
for (size_t i = 0; i < m_opart.size(); i++)
{
size_t lbl = p_map_req.get(m_opart.template get<2>(i));
size_t id = m_opart.template get<0>(i);
m_pos.get(lbl).set(cnt.get(lbl), v_pos.get(id));
m_prp.get(lbl).set(cnt.get(lbl), v_prp.get(id));
cnt.get(lbl)++;
// swap the particle
long int id_valid = get_end_valid(end,id_end);
if (id_valid > 0 && (long int)id < id_valid)
{
v_pos.set(id,v_pos.get(id_valid));
v_prp.set(id,v_prp.get(id_valid));
}
process_map_particle<proc_without_prp>(i,end,id_end,m_pos,m_prp,v_pos,v_prp,cnt);
}
v_pos.resize(v_pos.size() - m_opart.size());
......@@ -523,17 +570,18 @@ class vector_dist_comm
* \param pb send buffer
*
*/
template<typename prp_object,int ... prp> void fill_send_map_buf_list(openfpm::vector<Point<dim, St>> & v_pos, openfpm::vector<prop> & v_prp, openfpm::vector<size_t> & prc_r, openfpm::vector<size_t> & prc_sz_r, openfpm::vector<openfpm::vector<Point<dim,St>>> & m_pos, openfpm::vector<openfpm::vector<prp_object>> & m_prp)
template<typename prp_object,int ... prp> void fill_send_map_buf_list(openfpm::vector<Point<dim, St>> & v_pos, openfpm::vector<prop> & v_prp, openfpm::vector<size_t> & prc_sz_r, openfpm::vector<openfpm::vector<Point<dim,St>>> & m_pos, openfpm::vector<openfpm::vector<prp_object>> & m_prp)
{
m_prp.resize(v_cl.getProcessingUnits());
m_pos.resize(v_cl.getProcessingUnits());
openfpm::vector<size_t> cnt(v_cl.getProcessingUnits());
m_prp.resize(prc_sz_r.size());
m_pos.resize(prc_sz_r.size());
openfpm::vector<size_t> cnt(prc_sz_r.size());
for (size_t i = 0; i < prc_r.size(); i++)
for (size_t i = 0; i < prc_sz_r.size(); i++)
{
// set the size and allocate, using mem warant that pos and prp is contiguous
m_pos.get(i).resize(prc_sz_r.get(i));
m_prp.get(i).resize(prc_sz_r.get(i));
cnt.get(i) = 0;
}
// end vector point
......@@ -545,31 +593,11 @@ class vector_dist_comm
// Run through all the particles and fill the sending buffer
for (size_t i = 0; i < m_opart.size(); i++)
{
size_t lbl = m_opart.template get<2>(i);
size_t id = m_opart.template get<0>(i);
m_pos.get(lbl).set(cnt.get(lbl), v_pos.get(id));
// source object type
typedef encapc<1, prop, typename openfpm::vector<prop>::layout_type> encap_src;
// destination object type
typedef encapc<1, prp_object, typename openfpm::vector<prp_object>::layout_type> encap_dst;
// Copy only the selected properties
object_si_d<encap_src, encap_dst, OBJ_ENCAP, prp...>(v_prp.get(id), m_prp.get(lbl).get(cnt.get(lbl)));
cnt.get(lbl)++;
// swap the particle
long int id_valid = get_end_valid(end,id_end);
if (id_valid > 0 && (long int)id < id_valid)
{
v_pos.set(id,v_pos.get(id_valid));
v_prp.set(id,v_prp.get(id_valid));
}
process_map_particle<proc_with_prp<prp_object,prp...>>(i,end,id_end,m_pos,m_prp,v_pos,v_prp,cnt);
}
v_pos.resize(v_pos.size() - m_opart.size());
v_prp.resize(v_prp.size() - m_opart.size());
}
/*! \brief Label particles for mappings
......@@ -616,6 +644,12 @@ class vector_dist_comm
lbl_p.last().template get<0>() = key;
lbl_p.last().template get<2>() = p_id;
}
else
{
lbl_p.add();
lbl_p.last().template get<0>() = key;
lbl_p.last().template get<2>() = p_id;
}
}
// Add processors and add size
......@@ -930,7 +964,7 @@ public:
//! properties vector
openfpm::vector<openfpm::vector<prp_object>> m_prp;
fill_send_map_buf_list<prp_object,prp...>(v_pos,v_prp,prc_r, prc_sz_r, m_pos, m_prp);
fill_send_map_buf_list<prp_object,prp...>(v_pos,v_prp,prc_sz_r, m_pos, m_prp);
v_cl.SSendRecv(m_pos,v_pos,prc_r,prc_recv_map,recv_sz_map);
v_cl.SSendRecvP<openfpm::vector<prp_object>,decltype(v_prp),prp...>(m_prp,v_prp,prc_r,prc_recv_map,recv_sz_map);
......
......@@ -1773,6 +1773,7 @@ BOOST_AUTO_TEST_CASE( vector_dist_ghost_put )
#include "vector_dist_cell_list_tests.hpp"
#include "vector_dist_NN_tests.hpp"
#include "vector_dist_complex_prp_unit_test.hpp"
BOOST_AUTO_TEST_SUITE_END()
......
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