Commit 03378f4d authored by incardon's avatar incardon

Verlet-list with smaller memory

parent 9069c103
......@@ -6,6 +6,9 @@ All notable changes to this project will be documented in this file.
### Added
- Interface for Multi-vector dynamic load balancing
- Added Verlet List with balanced Memory and wise memory form
- Increaded performance for grid ghost get
- Introduced forms to increase the performance of the grid iterator in case of stencil code (see example 5_GrayScott)
### Fixed
......@@ -13,6 +16,10 @@ All notable changes to this project will be documented in this file.
- 2D Fixing IO in binary for vector
- 1D Fixing grid writer in ASCII mode
### Changed
- VerletList<3, double, FAST, shift<3, double> > is now VerletList<3, double, Mem_fast<>, shift<3, double> >
## [1.0.0] 13 September 2017
### Added
......
openfpm_data @ fe9c2ec1
Subproject commit c0ea161438f849f70cab9c8763012b515613ac83
Subproject commit fe9c2ec101e72556238a6749c8e677be2d3d901a
openfpm_numerics @ 9910a6ed
Subproject commit 7b9aff6deec78f5db1be1035a7c253927ea477bf
Subproject commit 9910a6ed26129214a85cab8b74d40caf900827e9
......@@ -123,13 +123,27 @@ struct gcl<dim,St,CellL,Vector,GCL_SYMMETRIC>
};
#define CELL_MEMFAST(dim,St) CellList_gen<dim, St, Process_keys_lin, Mem_fast<>, shift<dim, St> >
#define CELL_MEMBAL(dim,St) CellList_gen<dim, St, Process_keys_lin, Mem_bal, shift<dim, St> >
#define CELL_MEMMW(dim,St) CellList_gen<dim, St, Process_keys_lin, Mem_mw, shift<dim, St> >
#define CELL_MEMBAL(dim,St) CellList_gen<dim, St, Process_keys_lin, Mem_bal<>, shift<dim, St> >
#define CELL_MEMMW(dim,St) CellList_gen<dim, St, Process_keys_lin, Mem_mw<>, shift<dim, St> >
#define CELL_MEMFAST_HILB(dim,St) CellList_gen<dim, St, Process_keys_hilb, Mem_fast<>, shift<dim, St> >
#define CELL_MEMBAL_HILB(dim,St) CellList_gen<dim, St, Process_keys_hilb, Mem_bal, shift<dim, St> >
#define CELL_MEMMW_HILB(dim,St) CellList_gen<dim, St, Process_keys_hilb, Mem_mw, shift<dim, St> >
#define CELL_MEMBAL_HILB(dim,St) CellList_gen<dim, St, Process_keys_hilb, Mem_bal<>, shift<dim, St> >
#define CELL_MEMMW_HILB(dim,St) CellList_gen<dim, St, Process_keys_hilb, Mem_mw<>, shift<dim, St> >
#define VERLET_MEMFAST(dim,St) VerletList<dim,St,Mem_fast<>,shift<dim,St> >
#define VERLET_MEMBAL(dim,St) VerletList<dim,St,Mem_bal<>,shift<dim,St> >
#define VERLET_MEMMW(dim,St) VerletList<dim,St,Mem_mw<>,shift<dim,St> >
#define VERLET_MEMFAST_INT(dim,St) VerletList<dim,St,Mem_fast<unsigned int>,shift<dim,St> >
#define VERLET_MEMBAL_INT(dim,St) VerletList<dim,St,Mem_bal<unsigned int>,shift<dim,St> >
#define VERLET_MEMMW_INT(dim,St) VerletList<dim,St,Mem_mw<unsigned int>,shift<dim,St> >
enum reorder_opt
{
NO_REORDER = 0,
HILBERT = 1,
LINEAR = 2
};
/*! \brief Distributed vector
*
......@@ -260,6 +274,51 @@ private:
}
}
/*! \brief Reorder based on hilbert space filling curve
*
* \param v_pos_dest reordered vector of position
* \param v_prp_dest reordered vector of properties
* \param m order of the space filling curve
* \param cell_list cell-list
*
*/
template<typename CellL, typename sfc_it>
void reorder_sfc(openfpm::vector<Point<dim,St>> & v_pos_dest,
openfpm::vector<prop> & v_prp_dest,
sfc_it & h_it,
CellL & cell_list)
{
v_pos_dest.resize(v_pos.size());
v_prp_dest.resize(v_prp.size());
//Index for v_pos_dest
size_t count = 0;
grid_key_dx<dim> ksum;
for (size_t i = 0; i < dim ; i++)
{ksum.set_d(i,cell_list.getPadding(i));}
while (h_it.isNext())
{
auto key = h_it.get();
key += ksum;
size_t lin = cell_list.getGrid().LinId(key);
// for each particle in the Cell "lin"
for (size_t i = 0; i < cell_list.getNelements(lin); i++)
{
//reorder
auto v = cell_list.get(lin,i);
v_pos_dest.get(count) = v_pos.get(v);
v_prp_dest.get(count) = v_prp.get(v);
count++;
}
++h_it;
}
}
public:
......@@ -1159,13 +1218,14 @@ public:
* \return the verlet list
*
*/
VerletList<dim,St,Mem_fast<>,shift<dim,St> > getVerletSym(St r_cut)
template <typename VerletL = VerletList<dim,St,Mem_fast<>,shift<dim,St> >>
VerletL getVerletSym(St r_cut)
{
#ifdef SE_CLASS3
se3.getNN();
#endif
VerletList<dim,St,Mem_fast<>,shift<dim,St>> ver;
VerletL ver;
// Processor bounding box
Box<dim, St> pbox = getDecomposition().getProcessorBounds();
......@@ -1184,7 +1244,8 @@ public:
* \return the verlet list
*
*/
VerletList<dim,St,Mem_fast<>,shift<dim,St> > getVerletCrs(St r_cut)
template <typename VerletL = VerletList<dim,St,Mem_fast<>,shift<dim,St> >>
VerletL getVerletCrs(St r_cut)
{
#ifdef SE_CLASS1
if (!(opt & BIND_DEC_TO_GHOST))
......@@ -1198,7 +1259,7 @@ public:
se3.getNN();
#endif
VerletList<dim,St,Mem_fast<>,shift<dim,St>> ver;
VerletL ver;
// Processor bounding box
Box<dim, St> pbox = getDecomposition().getProcessorBounds();
......@@ -1236,13 +1297,14 @@ public:
* \return a VerletList object
*
*/
VerletList<dim,St,Mem_fast<>,shift<dim,St> > getVerlet(St r_cut)
template <typename VerletL = VerletList<dim,St,Mem_fast<>,shift<dim,St> >>
VerletL getVerlet(St r_cut)
{
#ifdef SE_CLASS3
se3.getNN();
#endif
VerletList<dim,St,Mem_fast<>,shift<dim,St>> ver;
VerletL ver;
// get the processor bounding box
Box<dim, St> bt = getDecomposition().getProcessorBounds();
......@@ -1269,7 +1331,7 @@ public:
* \param opt option like VL_SYMMETRIC and VL_NON_SYMMETRIC or VL_CRS_SYMMETRIC
*
*/
void updateVerlet(VerletList<dim,St,Mem_fast<>,shift<dim,St> > & ver, St r_cut, size_t opt = VL_NON_SYMMETRIC)
template<typename Mem_type> void updateVerlet(VerletList<dim,St,Mem_type,shift<dim,St> > & ver, St r_cut, size_t opt = VL_NON_SYMMETRIC)
{
#ifdef SE_CLASS3
se3.getNN();
......@@ -1287,9 +1349,9 @@ public:
ver.update(getDecomposition().getDomain(),r_cut,v_pos,g_m, opt);
else
{
VerletList<dim,St,Mem_fast<>,shift<dim,St> > ver_tmp;
VerletList<dim,St,Mem_type,shift<dim,St> > ver_tmp;
ver_tmp = getVerlet(r_cut);
ver_tmp = getVerlet<VerletList<dim,St,Mem_type,shift<dim,St> >>(r_cut);
ver.swap(ver);
}
}
......@@ -1328,9 +1390,9 @@ public:
}
else
{
VerletList<dim,St,Mem_fast<>,shift<dim,St> > ver_tmp;
VerletList<dim,St,Mem_type,shift<dim,St> > ver_tmp;
ver_tmp = getVerletCrs(r_cut);
ver_tmp = getVerletCrs<VerletList<dim,St,Mem_type,shift<dim,St> >>(r_cut);
ver.swap(ver_tmp);
}
}
......@@ -1346,9 +1408,9 @@ public:
ver.update(getDecomposition().getDomain(),r_cut,v_pos,g_m, opt);
else
{
VerletList<dim,St,Mem_fast<>,shift<dim,St> > ver_tmp;
VerletList<dim,St,Mem_type,shift<dim,St> > ver_tmp;
ver_tmp = getVerlet(r_cut);
ver_tmp = getVerlet<VerletList<dim,St,Mem_type,shift<dim,St> >>(r_cut);
ver.swap(ver_tmp);
}
}
......@@ -1362,9 +1424,10 @@ public:
* \param m an order of a hilbert curve
*
*/
template<typename CellL=CellList_gen<dim,St,Process_keys_lin,Mem_fast<>,shift<dim,St> > > void reorder (int32_t m)
template<typename CellL=CellList_gen<dim,St,Process_keys_lin,Mem_bal<>,shift<dim,St> > >
void reorder (int32_t m, reorder_opt opt = reorder_opt::HILBERT)
{
reorder(m,getDecomposition().getGhost());
reorder<CellL>(m,getDecomposition().getGhost(),opt);
}
......@@ -1380,7 +1443,8 @@ public:
* \param enlarge In case of padding particles the cell list must be enlarged, like a ghost this parameter say how much must be enlarged
*
*/
template<typename CellL=CellList_gen<dim,St,Process_keys_lin,Mem_fast<>,shift<dim,St> > > void reorder(int32_t m, const Ghost<dim,St> & enlarge)
template<typename CellL=CellList_gen<dim,St,Process_keys_lin,Mem_bal<>,shift<dim,St> > >
void reorder(int32_t m, const Ghost<dim,St> & enlarge, reorder_opt opt = reorder_opt::HILBERT)
{
// reset the ghost part
v_pos.resize(g_m);
......@@ -1428,38 +1492,24 @@ public:
openfpm::vector<Point<dim,St>> v_pos_dest;
openfpm::vector<prop> v_prp_dest;
v_pos_dest.resize(v_pos.size());
v_prp_dest.resize(v_prp.size());
//hilberts curve iterator
grid_key_dx_iterator_hilbert<dim> h_it(m);
//Index for v_pos_dest
size_t count = 0;
grid_key_dx<dim> ksum;
for (size_t i = 0; i < dim ; i++)
ksum.set_d(i,cell_list.getPadding(i));
while (h_it.isNext())
if (opt == reorder_opt::HILBERT)
{
auto key = h_it.get();
key += ksum;
grid_key_dx_iterator_hilbert<dim> h_it(m);
size_t lin = cell_list.getGrid().LinId(key);
// for each particle in the Cell "lin"
for (size_t i = 0; i < cell_list.getNelements(lin); i++)
{
//reorder
auto v = cell_list.get(lin,i);
v_pos_dest.get(count) = v_pos.get(v);
v_prp_dest.get(count) = v_prp.get(v);
reorder_sfc<CellL,grid_key_dx_iterator_hilbert<dim>>(v_pos_dest,v_prp_dest,h_it,cell_list);
}
else if (reorder_opt::LINEAR)
{
grid_sm<dim,void> gs(div);
grid_key_dx_iterator<dim> h_it(gs);
count++;
}
++h_it;
reorder_sfc<CellL,grid_key_dx_iterator<dim>>(v_pos_dest,v_prp_dest,h_it,cell_list);
}
else
{
// We do nothing, we second swap nullify the first
v_pos.swap(v_pos_dest);
v_prp.swap(v_prp_dest);
}
v_pos.swap(v_pos_dest);
......@@ -2166,7 +2216,7 @@ public:
* \return Particle iterator
*
*/
template<typename vrl> openfpm::vector_key_iterator_seq<typename vrl::local_index_t> getParticleIteratorCRS(vrl & NN)
template<typename vrl> openfpm::vector_key_iterator_seq<typename vrl::Mem_type_type::loc_index> getParticleIteratorCRS(vrl & NN)
{
#ifdef SE_CLASS1
if (!(opt & BIND_DEC_TO_GHOST))
......@@ -2177,7 +2227,7 @@ public:
#endif
// First we check that
return openfpm::vector_key_iterator_seq<typename vrl::local_index_t>(NN.getParticleSeq());
return openfpm::vector_key_iterator_seq<typename vrl::Mem_type_type::loc_index>(NN.getParticleSeq());
}
/*! \brief Return from which cell we have to start in case of CRS interation
......
......@@ -8,8 +8,8 @@
#ifndef SRC_VECTOR_VECTOR_DIST_NN_TESTS_HPP_
#define SRC_VECTOR_VECTOR_DIST_NN_TESTS_HPP_
BOOST_AUTO_TEST_CASE( vector_dist_full_NN )
template<typename VerletList>
void test_full_nn(long int k)
{
Vcluster & v_cl = create_vcluster();
......@@ -22,12 +22,6 @@ BOOST_AUTO_TEST_CASE( vector_dist_full_NN )
std::default_random_engine eg;
std::uniform_real_distribution<float> ud(0.0f, 1.0f);
#ifdef TEST_COVERAGE_MODE
long int k = 50 * v_cl.getProcessingUnits();
#else
long int k = 750 * v_cl.getProcessingUnits();
#endif
long int big_step = k / 4;
big_step = (big_step == 0)?1:big_step;
......@@ -134,14 +128,14 @@ BOOST_AUTO_TEST_CASE( vector_dist_full_NN )
///////////////////////////////////
auto NNv = vd.getVerlet(r_cut*1.0001);
auto NNv = vd.template getVerlet<VerletList>(r_cut*1.0001);
it = vd.getDomainIterator();
while (it.isNext())
{
Point<3,float> xp = vd.getPos(it.get());
auto Np = NNv.getNNIterator<NO_CHECK>(it.get().getKey());
auto Np = NNv.template getNNIterator<NO_CHECK>(it.get().getKey());
list_idx2.get(it.get().getKey()).clear();
......@@ -185,7 +179,7 @@ BOOST_AUTO_TEST_CASE( vector_dist_full_NN )
while (it.isNext())
{
Point<3,float> xp = vd.getPos(it.get());
auto Np = NNv.getNNIterator<NO_CHECK>(it.get().getKey());
auto Np = NNv.template getNNIterator<NO_CHECK>(it.get().getKey());
list_idx2.get(it.get().getKey()).clear();
......@@ -221,6 +215,24 @@ BOOST_AUTO_TEST_CASE( vector_dist_full_NN )
}
}
BOOST_AUTO_TEST_CASE( vector_dist_full_NN )
{
auto & v_cl = create_vcluster();
#ifdef TEST_COVERAGE_MODE
long int k = 50 * v_cl.getProcessingUnits();
#else
long int k = 750 * v_cl.getProcessingUnits();
#endif
test_full_nn<VERLET_MEMFAST(3,float)>(k);
k /= 2;
test_full_nn<VERLET_MEMBAL(3,float)>(k);
k /= 2;
test_full_nn<VERLET_MEMMW(3,float)>(k);
}
BOOST_AUTO_TEST_CASE( vector_dist_particle_iteration )
{
Vcluster & v_cl = create_vcluster();
......
This diff is collapsed.
......@@ -1231,7 +1231,11 @@ public:
* \param opt options
*
*/
template<template<typename,typename> class op, int ... prp> void ghost_put_(openfpm::vector<Point<dim, St>> & v_pos, openfpm::vector<prop> & v_prp, size_t & g_m, size_t opt)
template<template<typename,typename> class op, int ... prp>
void ghost_put_(openfpm::vector<Point<dim, St>> & v_pos,
openfpm::vector<prop> & v_prp,
size_t & g_m,
size_t opt)
{
// Sending property object
typedef object<typename object_creator<typename prop::type, prp...>::type> prp_object;
......
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