Commit 8fd4e3d4 authored by Pietro Incardona's avatar Pietro Incardona
Browse files

Fixing vector with negative domain

parent daf36c05
......@@ -123,7 +123,7 @@ protected:
//! Structure that decompose your structure into cell without creating them
//! useful to convert positions to CellId or sub-domain id in this case
CellDecomposer_sm<dim, T> cd;
CellDecomposer_sm<dim, T, shift<dim,T>> cd;
//! rectangular domain to decompose
::Box<dim,T> domain;
......@@ -137,26 +137,21 @@ protected:
//! Create distribution
Distribution dist;
// Smallest subdivision on each direction
//! Smallest subdivision on each direction
::Box<dim,T> ss_box;
//! Processor bounding box
::Box<dim,T> bbox;
// reference counter of the object in case is shared between object
//! reference counter of the object in case is shared between object
long int ref_cnt;
// ghost info
//! ghost info
Ghost<dim,T> ghost;
// Boundary condition info
//! Boundary condition info
size_t bc[dim];
// Heap memory receiver
HeapMemory hp_recv;
// Receive counter
size_t recv_cnt = 0;
/*! \brief It convert the box from the domain decomposition into sub-domain
*
* The decomposition box from the domain-decomposition contain the box in integer
......
......@@ -169,13 +169,13 @@ protected:
switch (cmbs[j][k])
{
case 1:
shifts.get(cmbs[j].lin()).template get<0>()[k] = -domain.getHigh(k);
shifts.get(cmbs[j].lin()).template get<0>()[k] = -(domain.getHigh(k) - domain.getLow(k));
break;
case 0:
shifts.get(cmbs[j].lin()).template get<0>()[k] = 0;
break;
case -1:
shifts.get(cmbs[j].lin()).template get<0>()[k] = domain.getHigh(k);
shifts.get(cmbs[j].lin()).template get<0>()[k] = (domain.getHigh(k) - domain.getLow(k));
break;
}
}
......
......@@ -28,21 +28,21 @@ class nn_prcs
//! List of adjacent processors
openfpm::vector<size_t> nn_processors;
// for each near processor store the sub-domains of the near processors
//! for each near processor store the sub-domains of the near processors
std::unordered_map<size_t, N_box<dim,T>> nn_processor_subdomains;
// when we add new boxes, are added here
//! when we add new boxes, are added here
std::unordered_map<size_t, N_box<dim,T>> nn_processor_subdomains_tmp;
// contain the same information as the member boxes with the difference that
// instead of the Box itself, it contain the sub-domain id in the list of the
// local sub-domains
//! contain the same information as the member boxes with the difference that
//! instead of the Box itself, it contain the sub-domain id in the list of the
//! local sub-domains
openfpm::vector<openfpm::vector<size_t>> proc_adj_box;
//! contain the set of sub-domains sent to the other processors
openfpm::vector< openfpm::vector< ::SpaceBox<dim,T>> > boxes;
// Receive counter
//! Receive counter
size_t recv_cnt;
//! applyBC function is suppose to be called only one time
......
......@@ -10,151 +10,192 @@
#include "VCluster.hpp"
BOOST_AUTO_TEST_SUITE( nn_processor_test )
BOOST_AUTO_TEST_CASE( nn_processor_np_test)
void create_decomposition2x2(openfpm::vector<openfpm::vector<long unsigned int>> & box_nn_processor, openfpm::vector<SpaceBox<2,float>> & sub_domains)
{
constexpr unsigned int dim = 2;
typedef float T;
// Adjacent processor for each sub-domain
openfpm::vector<openfpm::vector<long unsigned int> > box_nn_processor;
Vcluster & v_cl = create_vcluster();
// Vcluster
Vcluster & v_cl = *global_v_cluster;
box_nn_processor.add();
const size_t bc[dim] = {NON_PERIODIC,NON_PERIODIC};
if (v_cl.getProcessUnitID() == 0)
{
box_nn_processor.get(0).add(1);
box_nn_processor.get(0).add(2);
box_nn_processor.get(0).add(3);
SpaceBox<dim,float> domain({0.0,0.0},{1.0,1.0});
sub_domains.add(Box<2,float>({0.0,0.0},{0.5,0.5}));
}
else if (v_cl.getProcessUnitID() == 1)
{
box_nn_processor.get(0).add(0);
box_nn_processor.get(0).add(2);
box_nn_processor.get(0).add(3);
size_t sz[dim] = {8,8};
//! Structure that store the cartesian grid information
grid_sm<dim,void> gr(sz);
sub_domains.add(Box<2,float>({0.5,0.0},{1.0,0.5}));
}
else if (v_cl.getProcessUnitID() == 2)
{
box_nn_processor.get(0).add(1);
box_nn_processor.get(0).add(0);
box_nn_processor.get(0).add(3);
CellDecomposer_sm<dim,T> cd;
cd.setDimensions(domain,sz,0);
sub_domains.add(Box<2,float>({0.0,0.5},{0.5,1.0}));
}
else if (v_cl.getProcessUnitID() == 3)
{
box_nn_processor.get(0).add(1);
box_nn_processor.get(0).add(2);
box_nn_processor.get(0).add(0);
//! Box Spacing
T spacing[dim];
sub_domains.add(Box<2,float>({0.5,0.5},{1.0,1.0}));
}
}
// Calculate the total number of box and and the spacing
// on each direction
// Get the box containing the domain
SpaceBox<2,T> bs = domain.getBox();
BOOST_AUTO_TEST_SUITE( nn_processor_test )
//! the set of all local sub-domain as vector
openfpm::vector<SpaceBox<dim,T>> sub_domains;
BOOST_AUTO_TEST_CASE( nn_processor_np_test)
{
Vcluster & v_cl = create_vcluster();
/*!
*
* We test this situation
*
* \verbatim
+-------+-------+
| | |
| 0 | 1 |
| | |
| | |
+---------------+
| | |
| 2 | 3 |
| | |
| | |
+-------+-------+
* \endverbatim
*
*
*/
if (v_cl.getProcessingUnits() != 4)
return;
openfpm::vector<openfpm::vector<long unsigned int>> box_nn_processor;
openfpm::vector<SpaceBox<2,float>> sub_domains;
create_decomposition2x2(box_nn_processor,sub_domains);
nn_prcs<2,float> nnp(v_cl);
nnp.create(box_nn_processor, sub_domains);
/////////// From Cart decomposition ///////////
BOOST_REQUIRE_EQUAL(nnp.getNNProcessors(),3);
for (unsigned int i = 0; i < dim ; i++)
if (v_cl.getProcessUnitID() == 0)
{
// Calculate the spacing
spacing[i] = (bs.getHigh(i) - bs.getLow(i)) / gr.size(i);
}
// Here we use METIS
// Create a cartesian grid graph
CartesianGraphFactory<dim,Graph_CSR<nm_part_v,nm_part_e>> g_factory_part;
// the graph has only non perdiodic boundary conditions
size_t bc_o[dim];
for (size_t i = 0 ; i < dim ; i++)
bc_o[i] = NON_PERIODIC;
BOOST_REQUIRE_EQUAL(nnp.getNRealSubdomains(1),1);
BOOST_REQUIRE_EQUAL(nnp.getNRealSubdomains(2),1);
BOOST_REQUIRE_EQUAL(nnp.getNRealSubdomains(3),1);
// sub-sub-domain graph
Graph_CSR<nm_part_v,nm_part_e> gp = g_factory_part.template construct<NO_EDGE,T,2-1>(gr.getSize(),domain,bc_o);
const openfpm::vector< ::Box<2,float> > & nsubs1 = nnp.getNearSubdomains(1);
const openfpm::vector< ::Box<2,float> > & nsubs2 = nnp.getNearSubdomains(2);
const openfpm::vector< ::Box<2,float> > & nsubs3 = nnp.getNearSubdomains(3);
// Get the number of processing units
size_t Np = v_cl.getProcessingUnits();
SpaceBox<2,float> b1_a = nsubs1.get(0);
SpaceBox<2,float> b2_a = nsubs2.get(0);
SpaceBox<2,float> b3_a = nsubs3.get(0);
// Get the processor id
long int p_id = v_cl.getProcessUnitID();
// Convert the graph to metis
Metis<Graph_CSR<nm_part_v,nm_part_e>> met(gp,Np);
SpaceBox<2,float> b1_b = Box<2,float>({0.5,0.0},{1.0,0.5});
SpaceBox<2,float> b2_b = Box<2,float>({0.0,0.5},{0.5,1.0});
SpaceBox<2,float> b3_b = Box<2,float>({0.5,0.5},{1.0,1.0});
// decompose
met.decompose<nm_part_v::id>();
bool ret1 = b1_a == b1_b;
bool ret2 = b2_a == b2_b;
bool ret3 = b3_a == b3_b;
// Optimize the decomposition creating bigger spaces
// And reducing Ghost over-stress
dec_optimizer<2,Graph_CSR<nm_part_v,nm_part_e>> d_o(gp,gr.getSize());
BOOST_REQUIRE_EQUAL(ret1,true);
BOOST_REQUIRE_EQUAL(ret2,true);
BOOST_REQUIRE_EQUAL(ret3,true);
}
else if (v_cl.getProcessUnitID() == 1)
{
BOOST_REQUIRE_EQUAL(nnp.getNRealSubdomains(0),1);
BOOST_REQUIRE_EQUAL(nnp.getNRealSubdomains(2),1);
BOOST_REQUIRE_EQUAL(nnp.getNRealSubdomains(3),1);
// set of Boxes produced by the decomposition optimizer
openfpm::vector<::Box<2,size_t>> loc_box;
const openfpm::vector< ::Box<2,float> > & nsubs1 = nnp.getNearSubdomains(0);
const openfpm::vector< ::Box<2,float> > & nsubs2 = nnp.getNearSubdomains(2);
const openfpm::vector< ::Box<2,float> > & nsubs3 = nnp.getNearSubdomains(3);
// optimize the decomposition
d_o.template optimize<nm_part_v::sub_id,nm_part_v::id>(gp,p_id,loc_box,box_nn_processor,bc);
SpaceBox<2,float> b1_a = nsubs1.get(0);
SpaceBox<2,float> b2_a = nsubs2.get(0);
SpaceBox<2,float> b3_a = nsubs3.get(0);
// Initialize ss_box and bbox
if (loc_box.size() >= 0)
{
SpaceBox<dim,size_t> sub_dc = loc_box.get(0);
SpaceBox<dim,T> sub_d(sub_dc);
sub_d.mul(spacing);
sub_d.expand(spacing);
// Fixing sub-domains to cover all the domain
SpaceBox<2,float> b1_b = Box<2,float>({0.0,0.0},{0.5,0.5});
SpaceBox<2,float> b2_b = Box<2,float>({0.0,0.5},{0.5,1.0});
SpaceBox<2,float> b3_b = Box<2,float>({0.5,0.5},{1.0,1.0});
// Fixing sub_d
// if (loc_box) is a the boundary we have to ensure that the box span the full
// domain (avoiding rounding off error)
for (size_t i = 0 ; i < dim ; i++)
{
if (sub_dc.getHigh(i) == cd.getGrid().size(i) - 1)
{
sub_d.setHigh(i,domain.getHigh(i));
}
}
bool ret1 = b1_a == b1_b;
bool ret2 = b2_a == b2_b;
bool ret3 = b3_a == b3_b;
// add the sub-domain
sub_domains.add(sub_d);
BOOST_REQUIRE_EQUAL(ret1,true);
BOOST_REQUIRE_EQUAL(ret2,true);
BOOST_REQUIRE_EQUAL(ret3,true);
}
// convert into sub-domain
for (size_t s = 1 ; s < loc_box.size() ; s++)
else if (v_cl.getProcessUnitID() == 2)
{
SpaceBox<dim,size_t> sub_dc = loc_box.get(s);
SpaceBox<dim,T> sub_d(sub_dc);
BOOST_REQUIRE_EQUAL(nnp.getNRealSubdomains(1),1);
BOOST_REQUIRE_EQUAL(nnp.getNRealSubdomains(0),1);
BOOST_REQUIRE_EQUAL(nnp.getNRealSubdomains(3),1);
// re-scale and add spacing (the end is the starting point of the next domain + spacing)
sub_d.mul(spacing);
sub_d.expand(spacing);
const openfpm::vector< ::Box<2,float> > & nsubs1 = nnp.getNearSubdomains(1);
const openfpm::vector< ::Box<2,float> > & nsubs2 = nnp.getNearSubdomains(0);
const openfpm::vector< ::Box<2,float> > & nsubs3 = nnp.getNearSubdomains(3);
// Fixing sub-domains to cover all the domain
SpaceBox<2,float> b1_a = nsubs1.get(0);
SpaceBox<2,float> b2_a = nsubs2.get(0);
SpaceBox<2,float> b3_a = nsubs3.get(0);
// Fixing sub_d
// if (loc_box) is a the boundary we have to ensure that the box span the full
// domain (avoiding rounding off error)
for (size_t i = 0 ; i < 2 ; i++)
{
if (sub_dc.getHigh(i) == cd.getGrid().size(i) - 1)
{
sub_d.setHigh(i,domain.getHigh(i));
}
}
SpaceBox<2,float> b1_b = Box<2,float>({0.5,0.0},{1.0,0.5});
SpaceBox<2,float> b2_b = Box<2,float>({0.0,0.0},{0.5,0.5});
SpaceBox<2,float> b3_b = Box<2,float>({0.5,0.5},{1.0,1.0});
// add the sub-domain
sub_domains.add(sub_d);
bool ret1 = b1_a == b1_b;
bool ret2 = b2_a == b2_b;
bool ret3 = b3_a == b3_b;
BOOST_REQUIRE_EQUAL(ret1,true);
BOOST_REQUIRE_EQUAL(ret2,true);
BOOST_REQUIRE_EQUAL(ret3,true);
}
else if (v_cl.getProcessUnitID() == 3)
{
BOOST_REQUIRE_EQUAL(nnp.getNRealSubdomains(0),1);
BOOST_REQUIRE_EQUAL(nnp.getNRealSubdomains(1),1);
BOOST_REQUIRE_EQUAL(nnp.getNRealSubdomains(2),1);
nn_prcs<dim,T> nnp(v_cl);
nnp.create(box_nn_processor, sub_domains);
const openfpm::vector< ::Box<2,float> > & nsubs1 = nnp.getNearSubdomains(0);
const openfpm::vector< ::Box<2,float> > & nsubs2 = nnp.getNearSubdomains(1);
const openfpm::vector< ::Box<2,float> > & nsubs3 = nnp.getNearSubdomains(2);
if (v_cl.getProcessingUnits() == 1)
{
BOOST_REQUIRE(nnp.getNNProcessors() == 0);
}
else if (v_cl.getProcessingUnits() == 2)
{
BOOST_REQUIRE(nnp.getNNProcessors() == 1);
}
else
{
BOOST_REQUIRE(nnp.getNNProcessors() >= 1);
SpaceBox<2,float> b1_a = nsubs1.get(0);
SpaceBox<2,float> b2_a = nsubs2.get(0);
SpaceBox<2,float> b3_a = nsubs3.get(0);
SpaceBox<2,float> b1_b = Box<2,float>({0.0,0.0},{0.5,0.5});
SpaceBox<2,float> b2_b = Box<2,float>({0.5,0.0},{1.0,0.5});
SpaceBox<2,float> b3_b = Box<2,float>({0.0,0.5},{0.5,1.0});
bool ret1 = b1_a == b1_b;
bool ret2 = b2_a == b2_b;
bool ret3 = b3_a == b3_b;
BOOST_REQUIRE_EQUAL(ret1,true);
BOOST_REQUIRE_EQUAL(ret2,true);
BOOST_REQUIRE_EQUAL(ret3,true);
}
}
......@@ -169,7 +210,7 @@ BOOST_AUTO_TEST_CASE( nn_processor_box_periodic_test)
const size_t bc[dim] = {PERIODIC,PERIODIC,PERIODIC};
// Vcluster
Vcluster & v_cl = *global_v_cluster;
Vcluster & v_cl = create_vcluster();
Ghost<dim,T> ghost(0.01);
......@@ -177,7 +218,7 @@ BOOST_AUTO_TEST_CASE( nn_processor_box_periodic_test)
nn_prcs<dim,T> nnp(v_cl);
std::unordered_map<size_t, N_box<dim,T>> & nnp_sub = nnp.get_nn_processor_subdomains();
/* std::unordered_map<size_t, N_box<dim,T>> & nnp_sub = nnp.get_nn_processor_subdomains();
openfpm::vector<size_t> & nnp_np = nnp.get_nn_processors();
// we add the boxes
......@@ -208,19 +249,19 @@ BOOST_AUTO_TEST_CASE( nn_processor_box_periodic_test)
for (size_t i = 0; i < dim; i++)
{
nnp_np.add(i+1);
}
}*/
// check that nn_processor contain the correct boxes
// nnp.write("nnp_output_before");
nnp.applyBC(domain,ghost,bc);
// nnp.write("nnp_output_after");
if (v_cl.getProcessUnitID() == 0)
{
BOOST_REQUIRE_EQUAL(nnp.getNearSubdomains(nnp.IDtoProc(2)).size(),12ul);
BOOST_REQUIRE_EQUAL(nnp.getNearSubdomains(nnp.IDtoProc(0)).size(),8ul*8ul);
BOOST_REQUIRE_EQUAL(nnp.getNearSubdomains(nnp.IDtoProc(1)).size(),12ul*4ul);
}
// BOOST_REQUIRE_EQUAL(nnp.getNearSubdomains(nnp.IDtoProc(2)).size(),12ul);
// BOOST_REQUIRE_EQUAL(nnp.getNearSubdomains(nnp.IDtoProc(0)).size(),8ul*8ul);
// BOOST_REQUIRE_EQUAL(nnp.getNearSubdomains(nnp.IDtoProc(1)).size(),12ul*4ul);
}
BOOST_AUTO_TEST_SUITE_END()
......
......@@ -97,7 +97,7 @@ void print_test(std::string test, size_t sz)
std::cout << test << " " << sz << "\n";
}
BOOST_AUTO_TEST_CASE( vector_dist_ghost )
void Test2D_ghost(Box<2,float> & box)
{
// Communication object
Vcluster & v_cl = create_vcluster();
......@@ -111,7 +111,6 @@ BOOST_AUTO_TEST_CASE( vector_dist_ghost )
//! [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
......@@ -134,7 +133,7 @@ BOOST_AUTO_TEST_CASE( vector_dist_ghost )
grid_sm<2,void> g_info(g_div);
// Calculate the grid spacing
Point<2,float> spacing = box.getP2();
Point<2,float> spacing = box.getP2() - box.getP1();
spacing = spacing / g_div;
// middle spacing
......@@ -162,8 +161,8 @@ BOOST_AUTO_TEST_CASE( vector_dist_ghost )
// set the particle position
vd.getPos(key_v)[0] = key.get(0) * spacing[0] + m_spacing[0];
vd.getPos(key_v)[1] = key.get(1) * spacing[1] + m_spacing[1];
vd.getPos(key_v)[0] = key.get(0) * spacing[0] + m_spacing[0] + box.getLow(0);
vd.getPos(key_v)[1] = key.get(1) * spacing[1] + m_spacing[1] + box.getLow(1);
cobj++;
......@@ -253,21 +252,26 @@ BOOST_AUTO_TEST_CASE( vector_dist_ghost )
BOOST_REQUIRE(n_part != 0);
}
CellDecomposer_sm<2,float> cd(SpaceBox<2,float>(box),g_div,0);
CellDecomposer_sm<2,float,shift<2,float>> cd(SpaceBox<2,float>(box),g_div,0);
for (size_t i = 0 ; i < vb.size() ; i++)
{
// Calculate how many particle should be in the box
size_t n_point = cd.getGridPoints(dec.getEGhostBox(i)).getVolumeKey();
if (n_point != vb.get(i))
{
std::cout << n_point << " " << dec.getEGhostBoxProcessor(i) << " " << v_cl.getProcessUnitID() << dec.getEGhostBox(i).toString() << "\n";
}
//BOOST_REQUIRE_EQUAL(n_point,vb.get(i));
BOOST_REQUIRE_EQUAL(n_point,vb.get(i));
}
}
BOOST_AUTO_TEST_CASE( vector_dist_ghost )
{
Box<2,float> box({0.0,0.0},{1.0,1.0});
Test2D_ghost(box);
Box<2,float> box2({-1.0,-1.0},{2.5,2.5});
Test2D_ghost(box2);
}
void print_test_v(std::string test, size_t sz)
{
if (create_vcluster().getProcessUnitID() == 0)
......@@ -952,7 +956,7 @@ BOOST_AUTO_TEST_CASE( vector_dist_out_of_bound_policy )
BOOST_REQUIRE_EQUAL(cnt_l,100-v_cl.getProcessingUnits());
}
BOOST_AUTO_TEST_CASE( vector_dist_periodic_test_interacting_particles )
void Test_interacting(Box<3,float> & box)
{
Vcluster & v_cl = create_vcluster();
......@@ -963,7 +967,7 @@ BOOST_AUTO_TEST_CASE( vector_dist_periodic_test_interacting_particles )
// create the random generator engine
std::srand(v_cl.getProcessUnitID());
std::default_random_engine eg;
std::uniform_real_distribution<float> ud(0.0f, 1.0f);
std::uniform_real_distribution<float> ud(-0.5f, 0.5f);
size_t nsz[] = {0,32,4};
nsz[0] = 65536 * v_cl.getProcessingUnits();
......@@ -977,8 +981,6 @@ BOOST_AUTO_TEST_CASE( vector_dist_periodic_test_interacting_particles )
BOOST_TEST_CHECKPOINT( "Testing 3D random walk interacting particles vector k=" << k );
Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0});
// Boundary conditions
size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
......@@ -1030,8 +1032,13 @@ BOOST_AUTO_TEST_CASE( vector_dist_periodic_test_interacting_particles )
vd.map();
vd.write("Without_ghost");
vd.ghost_get<0>();
vd.write("With_ghost");
vd.getDecomposition().write("With_dec_ghost");
// get the cell list with a cutoff radius
bool error = false;
......@@ -1080,12 +1087,19 @@ BOOST_AUTO_TEST_CASE( vector_dist_periodic_test_interacting_particles )
size_t cnt = total_n_part_lc(vd,bc);
BOOST_REQUIRE_EQUAL((size_t)k,cnt);
}
}
}
BOOST_AUTO_TEST_CASE( vector_dist_periodic_test_interacting_particles )
{
Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0});
Test_interacting(box);
Box<3,float> box2({-0.5,-0.5,-0.5},{0.5,0.5,0.5});
Test_interacting(box2);
}
BOOST_AUTO_TEST_CASE( vector_dist_grid_iterator )
{
long int k = 64*64*64*create_vcluster().getProcessingUnits();
......
......@@ -46,6 +46,6 @@ int main(int argc, char* argv[])
//#include "DLB/DLB_unit_test.hpp"
#include "Graph/dist_map_graph_unit_test.hpp"
#include "Graph/DistGraphFactory.hpp"
//#include "Decomposition/nn_processor_unit_test.hpp"
#include "Decomposition/nn_processor_unit_test.hpp"
#include "Grid/staggered_grid_dist_unit_test.hpp"
//#include "antoniol_test_isolation.hpp"
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