From dd99a004d044d53e8b33231eb7503b29e14505ea Mon Sep 17 00:00:00 2001
From: Yaroslav <beorn.90@gmail.com>
Date: Wed, 20 Apr 2016 16:14:28 +0200
Subject: [PATCH] Benchmark with mooving particles

---
 openfpm_data                         |   2 +-
 openfpm_io                           |   2 +-
 openfpm_vcluster                     |   2 +-
 src/Makefile.am                      |   4 +-
 src/Vector/vector_dist.hpp           | 132 +++++++++++++++++++++++++++
 src/Vector/vector_dist_iterator.hpp  |   9 ++
 src/Vector/vector_dist_unit_test.hpp |  80 +++++++++++++++-
 src/main.cpp                         |   3 +
 8 files changed, 228 insertions(+), 6 deletions(-)

diff --git a/openfpm_data b/openfpm_data
index 8168a90cc..21d50e7f0 160000
--- a/openfpm_data
+++ b/openfpm_data
@@ -1 +1 @@
-Subproject commit 8168a90ccd39ef504ba8699d6d0ed9aed46a3f31
+Subproject commit 21d50e7f0f796ceb5699dcf6939183572aba2ba0
diff --git a/openfpm_io b/openfpm_io
index 523332938..d07c3c784 160000
--- a/openfpm_io
+++ b/openfpm_io
@@ -1 +1 @@
-Subproject commit 523332938de0a47a1ca1d652a8e171cf9b8a6f5b
+Subproject commit d07c3c7848e446437526d0bbda0843c18ab6a925
diff --git a/openfpm_vcluster b/openfpm_vcluster
index be8c849c9..02c935545 160000
--- a/openfpm_vcluster
+++ b/openfpm_vcluster
@@ -1 +1 @@
-Subproject commit be8c849c9189fe90e1533125f2544258671d0916
+Subproject commit 02c935545524000d318f0b84578af704896eeee4
diff --git a/src/Makefile.am b/src/Makefile.am
index a79faae31..f3fd81586 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2,9 +2,9 @@ LINKLIBS = $(METIS_LIB) $(PTHREAD_LIBS) $(OPT_LIBS) $(BOOST_LDFLAGS) $(BOOST_IOS
 
 noinst_PROGRAMS = pdata
 pdata_SOURCES = main.cpp lib/pdata.cpp test_multiple_o.cpp ../openfpm_devices/src/memory/HeapMemory.cpp ../openfpm_devices/src/memory/PtrMemory.cpp ../openfpm_vcluster/src/VCluster.cpp ../openfpm_devices/src/Memleak_check.cpp
-pdata_CXXFLAGS = $(CUDA_CFLAGS) $(INCLUDES_PATH) $(METIS_INCLUDE) $(BOOST_CPPFLAGS) -Wno-unused-local-typedefs
+pdata_CXXFLAGS = $(CUDA_CFLAGS) $(INCLUDES_PATH) $(METIS_INCLUDE) $(BOOST_CPPFLAGS) -I/usr/local/libhilbert/include -Wno-unused-local-typedefs
 pdata_CFLAGS = $(CUDA_CFLAGS)
-pdata_LDADD = $(LINKLIBS) -lmetis
+pdata_LDADD = $(LINKLIBS) -lmetis -L/usr/local/libhilbert/lib -lhilbert
 nobase_include_HEADERS = Decomposition/CartDecomposition.hpp Decomposition/common.hpp Decomposition/Decomposition.hpp  Decomposition/ie_ghost.hpp \
          Decomposition/nn_processor.hpp Decomposition/ie_loc_ghost.hpp Decomposition/ORB.hpp \
          Graph/CartesianGraphFactory.hpp \
diff --git a/src/Vector/vector_dist.hpp b/src/Vector/vector_dist.hpp
index d06a21d5a..775c7b44e 100644
--- a/src/Vector/vector_dist.hpp
+++ b/src/Vector/vector_dist.hpp
@@ -22,6 +22,7 @@
 #include "CSVWriter/CSVWriter.hpp"
 #include "Decomposition/common.hpp"
 #include "Grid/grid_dist_id_iterator_dec.hpp"
+#include "Grid/grid_key_dx_iterator_hilbert.hpp"
 #include "Vector/vector_dist_ofb.hpp"
 
 #define V_SUB_UNIT_FACTOR 64
@@ -133,6 +134,21 @@ private:
 		openfpm::vector<prop,PreAllocHeapMemory<2>,openfpm::grow_policy_identity> prp;
 	};
 
+	/*! \brief Operator= is not permitted
+	 *
+	 *
+	 */
+/*	vector_dist<dim,St,prop,Decomposition,Memory> & operator=(const vector_dist<dim,St,prop,Decomposition,Memory> &)
+	{
+		return *this;
+	}*/
+
+	/*! Copy constructor not permitted
+	 *
+	 *
+	 */
+//	vector_dist(const vector_dist<dim,St,prop,Decomposition,Memory> &) {}
+
 	/*! \brief Label particles for mappings
 	 *
 	 * \param lbl_p Particle labeled
@@ -1126,6 +1142,122 @@ public:
 	    }
 	}
 
+	/*! \brief Construct a cell list starting from the stored particles and reorder a vector according to the Hilberts curve
+	 *
+	 * \tparam CellL CellList type to construct
+	 *
+	 * \param m an order of a hilbert curve
+	 *
+	 *
+	 *
+	 */
+	template<typename CellL=CellList<dim,St,FAST,shift<dim,St> > > void reorder (int32_t m)
+	{
+		reorder(m,dec.getGhost());
+	}
+
+
+	/*! \brief Construct a cell list starting from the stored particles and reorder a vector according to the Hilberts curve
+	 *
+	 *
+	 *It differs from the reorder(m) for an additional parameter, in case the
+	 * domain + ghost is not big enough to contain additional padding particles, a Cell list
+	 * with bigger space can be created
+	 * (padding particles in general are particles added by the user out of the domains)
+	 *
+	 * \param m order of a curve
+	 * \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<dim,St,FAST,shift<dim,St> > > void reorder(int32_t m, const Ghost<dim,St> & enlarge)
+	{
+		// reset the ghost part
+		v_pos.resize(g_m);
+		v_prp.resize(g_m);
+
+
+		CellL cell_list;
+
+		// calculate the parameters of the cell list
+
+		// get the processor bounding box
+		Box<dim,St> pbox = dec.getProcessorBounds();
+		// extend by the ghost
+		pbox.enlarge(enlarge);
+
+		Box<dim,St> cell_box;
+
+		size_t div[dim];
+
+		// Calculate the division array and the cell box
+		for (size_t i = 0 ; i < dim ; i++)
+		{
+			div[i] = 1 << m;
+
+			cell_box.setLow(i,0.0);
+			cell_box.setHigh(i,pbox.getP2().get(i) - pbox.getP1().get(i));
+		}
+
+		cell_list.Initialize(cell_box,div,pbox.getP1());
+
+		// for each particle add the particle to the cell list
+
+		auto it = getIterator();
+
+		while (it.isNext())
+		{
+			auto key = it.get();
+
+			cell_list.add(this->template getPos<0>(key),key.getKey());
+
+			++it;
+		}
+
+		// Use cell_list to reorder v_pos
+
+		//destination vector
+		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())
+		{
+		  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;
+		}
+
+		v_pos.swap(v_pos_dest);
+		v_prp.swap(v_prp_dest);
+
+	}
+
 	/*! \brief It return the number of particles contained by the previous processors
 	 *
 	 * \Warning It only work with the initial decomposition
diff --git a/src/Vector/vector_dist_iterator.hpp b/src/Vector/vector_dist_iterator.hpp
index 795e4290b..4b8ee861f 100644
--- a/src/Vector/vector_dist_iterator.hpp
+++ b/src/Vector/vector_dist_iterator.hpp
@@ -74,6 +74,15 @@ class vector_dist_iterator
 	{
 		return vect_dist_key_dx(v_it);
 	}
+
+	/*! \brief Reset the iterator
+	 *
+	 *
+	 */
+	void reset()
+	{
+		v_it = 0;
+	}
 };
 
 
diff --git a/src/Vector/vector_dist_unit_test.hpp b/src/Vector/vector_dist_unit_test.hpp
index 8a5c813cb..93faeb798 100644
--- a/src/Vector/vector_dist_unit_test.hpp
+++ b/src/Vector/vector_dist_unit_test.hpp
@@ -10,6 +10,7 @@
 
 #include <random>
 #include "Vector/vector_dist.hpp"
+#include "data_type/aggregate.hpp"
 
 /*! \brief Count the total number of particles
  *
@@ -270,7 +271,7 @@ BOOST_AUTO_TEST_CASE( vector_dist_ghost )
 void print_test_v(std::string test, size_t sz)
 {
 	if (global_v_cluster->getProcessUnitID() == 0)
-		std::cout << test << " " << sz << "\n";
+		std::cout << "\n" << test << " " << sz << "\n";
 }
 
 long int decrement(long int k, long int step)
@@ -1031,6 +1032,8 @@ 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);
+
+
 		}
 	}
 }
@@ -1155,6 +1158,81 @@ BOOST_AUTO_TEST_CASE( vector_dist_cell_verlet_test )
 	}
 }
 
+BOOST_AUTO_TEST_CASE( vector_dist_hilbert_timer_test )
+{
+	typedef Point<2,float> s;
+
+	Vcluster & v_cl = *global_v_cluster;
+
+    // set the seed
+	// 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);
+
+    long int k = 524288 * v_cl.getProcessingUnits();
+
+	long int big_step = k / 4;
+	big_step = (big_step == 0)?1:big_step;
+
+	print_test_v( "Testing 2D vector with hilbert curve reordering k<=",k);
+
+	// 2D test
+	for ( ; k >= 2 ; k-= decrement(k,big_step) )
+	{
+		BOOST_TEST_CHECKPOINT( "Testing 2D vector with hilbert curve reordering k=" << k );
+
+		//! [Create a vector of random elements on each processor 2D]
+
+		Box<2,float> box({0.0,0.0},{1.0,1.0});
+
+		// Boundary conditions
+		size_t bc[2]={NON_PERIODIC,NON_PERIODIC};
+
+		vector_dist<2,float, Point_test<float>, CartDecomposition<2,float> > vd(k,box,bc,Ghost<2,float>(0.0));
+
+		auto it = vd.getIterator();
+
+		while (it.isNext())
+		{
+			auto key = it.get();
+
+			vd.template getPos<s::x>(key)[0] = ud(eg);
+			vd.template getPos<s::x>(key)[1] = ud(eg);
+
+			++it;
+		}
+
+		vd.map();
+
+		timer t;
+		t.start();
+
+		//! [Create a vector of random elements on each processor 2D]
+
+		auto NN1 = vd.getCellList(0.01);
+
+		//An order of a curve
+		int32_t m = 6;
+
+		//Reorder a vector
+		vd.reorder(m);
+
+		auto NN2 = vd.getCellList(0.01);
+
+		for (size_t i = 0 ; i < NN1.getGrid().size() ; i++)
+		{
+			size_t n1 = NN1.getNelements(i);
+			size_t n2 = NN2.getNelements(i);
+
+			BOOST_REQUIRE_EQUAL(n1,n2);
+		}
+
+		t.stop();
+		std::cout << "  t: " << t.getwct() << "\n";
+	}
+}
+
 BOOST_AUTO_TEST_SUITE_END()
 
 #endif /* VECTOR_DIST_UNIT_TEST_HPP_ */
diff --git a/src/main.cpp b/src/main.cpp
index 0d2c73fe0..f884796da 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -26,5 +26,8 @@
 #include "dec_optimizer_unit_test.hpp"
 #include "Grid/grid_dist_id_unit_test.hpp"
 #include "Vector/vector_dist_unit_test.hpp"
+//#ifdef PERFORMANCE_TEST
+#include "pdata_performance.hpp"
+//#endif
 //#include "Decomposition/nn_processor_unit_test.hpp"
 
-- 
GitLab