From ae3ab296de3d1e616a7539ab4badc1bf38854136 Mon Sep 17 00:00:00 2001
From: Pietro Incardona <incardon@mpi-cbg.de>
Date: Tue, 23 Jul 2019 11:08:10 +0200
Subject: [PATCH] Refactor performance test

---
 CMakeLists.txt                                |   4 +-
 openfpm_data                                  |   2 +-
 openfpm_io                                    |   2 +-
 src/CMakeLists.txt                            |   5 +
 src/Grid/grid_dist_id.hpp                     |  18 +-
 src/Grid/grid_dist_key.hpp                    |   2 +-
 .../performance/grid_dist_performance.hpp     | 287 ++++++------------
 .../performance/cell_list_comp_reorder.hpp    | 102 ++++++-
 .../vector_dist_performance_util.cpp          |  14 +-
 .../vector_dist_performance_util.hpp          |  85 +-----
 .../performance/verlet_performance_tests.hpp  |   2 +
 src/pdata_performance.cpp                     |   8 +-
 12 files changed, 215 insertions(+), 316 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index c04fdabf8..551c410b5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -30,6 +30,8 @@ set(SuiteSparse_ROOT ${SUITESPARSE_ROOT})
 
 set (CMAKE_CXX_STANDARD 11)
 set (CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CXX_FLAGS_RELEASE "-O3")
+set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -O3")
 
 if (OPENBLAS_ROOT)
 	set(ENV{LD_LIBRARY_PATH} "$ENV{LD_LIBRARY_PATH}:${OPENBLAS_ROOT}/lib")
@@ -57,7 +59,7 @@ if(ENABLE_GPU)
 endif()
 
 
-find_package(Boost 1.68.0 COMPONENTS unit_test_framework iostreams program_options)
+find_package(Boost 1.68.0 COMPONENTS unit_test_framework iostreams program_options system filesystem)
 find_package(MPI)
 find_package(PETSc)
 find_package(HDF5)
diff --git a/openfpm_data b/openfpm_data
index c7d16222b..cbef620db 160000
--- a/openfpm_data
+++ b/openfpm_data
@@ -1 +1 @@
-Subproject commit c7d16222ba51287808f611c280860fcd76281936
+Subproject commit cbef620db71cbd6beb13eb11f139f1cdbfce8ae3
diff --git a/openfpm_io b/openfpm_io
index eafa24bd9..d7c48264a 160000
--- a/openfpm_io
+++ b/openfpm_io
@@ -1 +1 @@
-Subproject commit eafa24bd983173dfd9c4e9c49e88b160096066ff
+Subproject commit d7c48264a25f8f7aded163258fb3c182a7397542
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e6b1e2f75..858cbe10a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -89,6 +89,11 @@ target_link_libraries(pdata -L${HDF5_ROOT}/lib hdf5 hdf5_hl)
 target_link_libraries(pdata -L${LIBHILBERT_LIBRARY_DIRS} ${LIBHILBERT_LIBRARIES})
 target_link_libraries(pdata ${PETSC_LIBRARIES})
 
+if (TEST_PERFORMANCE)
+	target_link_libraries(pdata  ${Boost_FILESYSTEM_LIBRARY})
+        target_link_libraries(pdata ${Boost_SYSTEM_LIBRARY})
+endif()
+
 if (TEST_COVERAGE)
     target_link_libraries(pdata -lgcov --coverage)
 endif()
diff --git a/src/Grid/grid_dist_id.hpp b/src/Grid/grid_dist_id.hpp
index 8364a0889..518fcd311 100644
--- a/src/Grid/grid_dist_id.hpp
+++ b/src/Grid/grid_dist_id.hpp
@@ -2059,7 +2059,8 @@ public:
 	 * \return the selected element
 	 *
 	 */
-	template <unsigned int p = 0>inline auto get(grid_dist_g_dx<device_grid> & v1) const -> typename std::add_lvalue_reference<decltype(v1.getSub()->template get<p>(v1.getKey()))>::type
+	template <unsigned int p = 0>
+	inline auto get(const grid_dist_g_dx<device_grid> & v1) const -> typename std::add_lvalue_reference<decltype(v1.getSub()->template get<p>(v1.getKey()))>::type
 	{
 #ifdef SE_CLASS2
 		check_valid(this,8);
@@ -2075,7 +2076,8 @@ public:
 	 * \return the selected element
 	 *
 	 */
-	template <unsigned int p = 0>inline auto get(grid_dist_g_dx<device_grid> & v1) -> typename std::add_lvalue_reference<decltype(v1.getSub()->template get<p>(v1.getKey()))>::type
+	template <unsigned int p = 0>
+	inline auto get(const grid_dist_g_dx<device_grid> & v1) -> typename std::add_lvalue_reference<decltype(v1.getSub()->template get<p>(v1.getKey()))>::type
 	{
 #ifdef SE_CLASS2
 		check_valid(this,8);
@@ -2091,7 +2093,8 @@ public:
 	 * \return the selected element
 	 *
 	 */
-	template <unsigned int p = 0>inline auto get(const grid_dist_lin_dx & v1) const -> typename std::add_lvalue_reference<decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))>::type
+	template <unsigned int p = 0>
+	inline auto get(const grid_dist_lin_dx & v1) const -> typename std::add_lvalue_reference<decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))>::type
 	{
 #ifdef SE_CLASS2
 		check_valid(this,8);
@@ -2107,7 +2110,8 @@ public:
 	 * \return the selected element
 	 *
 	 */
-	template <unsigned int p = 0>inline auto get(const grid_dist_lin_dx & v1) -> typename std::add_lvalue_reference<decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))>::type
+	template <unsigned int p = 0>
+	inline auto get(const grid_dist_lin_dx & v1) -> typename std::add_lvalue_reference<decltype(loc_grid.get(v1.getSub()).template get<p>(v1.getKey()))>::type
 	{
 #ifdef SE_CLASS2
 		check_valid(this,8);
@@ -2123,7 +2127,8 @@ public:
 	 * \return the selected element
 	 *
 	 */
-	template <unsigned int p = 0>inline auto getProp(const grid_dist_key_dx<dim> & v1) const -> decltype(this->template get<p>(v1))
+	template <unsigned int p = 0>
+	inline auto getProp(const grid_dist_key_dx<dim> & v1) const -> decltype(this->template get<p>(v1))
 	{
 		return this->template get<p>(v1);
 	}
@@ -2136,7 +2141,8 @@ public:
 	 * \return the selected element
 	 *
 	 */
-	template <unsigned int p = 0>inline auto getProp(const grid_dist_key_dx<dim> & v1) -> decltype(this->template get<p>(v1))
+	template <unsigned int p = 0>
+	inline auto getProp(const grid_dist_key_dx<dim> & v1) -> decltype(this->template get<p>(v1))
 	{
 		return this->template get<p>(v1);
 	}
diff --git a/src/Grid/grid_dist_key.hpp b/src/Grid/grid_dist_key.hpp
index ecf67a423..96224dc12 100644
--- a/src/Grid/grid_dist_key.hpp
+++ b/src/Grid/grid_dist_key.hpp
@@ -308,7 +308,7 @@ public:
 	 *
 	 *
 	 */
-	inline device_grid * getSub()
+	inline device_grid * getSub() const
 	{
 		return dg;
 	}
diff --git a/src/Grid/performance/grid_dist_performance.hpp b/src/Grid/performance/grid_dist_performance.hpp
index a69fda648..e157842f3 100644
--- a/src/Grid/performance/grid_dist_performance.hpp
+++ b/src/Grid/performance/grid_dist_performance.hpp
@@ -8,26 +8,21 @@
 #ifndef SRC_GRID_GRID_DIST_PERFORMANCE_HPP_
 #define SRC_GRID_GRID_DIST_PERFORMANCE_HPP_
 
-#include "../../../openfpm_numerics/src/interpolation/interpolation.hpp"
-#include "Grid/grid_dist_id.hpp"
-#include "Plot/GoogleChart.hpp"
-#include "interpolation/mp4_kernel.hpp"
-
 #define GRID_ITERATOR_TESTS  30
 #define GRID_INTERPOLATION_TESTS  30
 
 // Vectors to store the data for 3D
-openfpm::vector<double> time_iterator_normal_mean;
-openfpm::vector<double> time_iterator_normal_dev;
-openfpm::vector<double> time_iterator_stencil_mean;
-openfpm::vector<double> time_iterator_stencil_dev;
-openfpm::vector<double> time_inte_p2m_mean;
-openfpm::vector<double> time_inte_m2p_mean;
-openfpm::vector<double> time_inte_p2m_dev;
-openfpm::vector<double> time_inte_m2p_dev;
 openfpm::vector<size_t> nk_grid_st;
 openfpm::vector<size_t> nk_grid_int;
 
+// Property tree
+struct report_grid_iterator_test
+{
+	boost::property_tree::ptree graphs;
+};
+
+report_grid_iterator_test report_grid_iterator;
+
 BOOST_AUTO_TEST_SUITE( grid_iterator_performance_test )
 
 constexpr int x = 0;
@@ -39,10 +34,7 @@ constexpr int z = 2;
  *
  */
 void grid_interpolation_benchmark(openfpm::vector<size_t> & nk_grid,
-		                            openfpm::vector<double> & time_interpolation_p2m_mean,
-									openfpm::vector<double> & time_interpolation_m2p_mean,
-									openfpm::vector<double> & time_interpolation_p2m_dev,
-									openfpm::vector<double> & time_interpolation_m2p_dev)
+									boost::property_tree::ptree & interpolation_graph)
 {
 	for (size_t k = 0 ; k < nk_grid.size() ; k++)
 	{
@@ -55,6 +47,23 @@ void grid_interpolation_benchmark(openfpm::vector<size_t> & nk_grid,
 
 		size_t tot_part = np*np*np;
 
+		std::string base_p2m = "performance.interpolation.p2m(" + std::to_string(k) + ")";
+		std::string base_m2p = "performance.interpolation.m2p(" + std::to_string(k) + ")";
+
+		interpolation_graph.put(base_p2m + ".grid.dim",3);
+		interpolation_graph.put(base_m2p + ".grid.dim",3);
+
+		interpolation_graph.put(base_p2m + ".grid.x",np);
+		interpolation_graph.put(base_p2m + ".grid.y",np);
+		interpolation_graph.put(base_p2m + ".grid.z",np);
+
+		interpolation_graph.put(base_m2p + ".grid.x",np);
+		interpolation_graph.put(base_m2p + ".grid.y",np);
+		interpolation_graph.put(base_m2p + ".grid.z",np);
+
+		interpolation_graph.put(base_p2m + ".particles",tot_part);
+		interpolation_graph.put(base_m2p + ".particles",tot_part);
+
 		grid_dist_id<3, float, aggregate<float>> gd(sz,domain,gg);
 		vector_dist<3,float,aggregate<float>> vd(gd.getDecomposition(),tot_part);
 
@@ -95,10 +104,11 @@ void grid_interpolation_benchmark(openfpm::vector<size_t> & nk_grid,
 			measures.add(tstl.getwct());
 		}
 		standard_deviation(measures,mean,dev);
-		time_interpolation_p2m_mean.add(mean);
-		time_interpolation_p2m_dev.add(dev);
 
-		std::cout << "Time particles to mesh " << time_interpolation_p2m_mean.last() << std::endl;
+		interpolation_graph.put(base_p2m + ".data.mean",mean);
+		interpolation_graph.put(base_p2m + ".data.dev",dev);
+
+		std::cout << "Time particles to mesh " << mean << std::endl;
 
 		measures.clear();
 		for (size_t j = 0 ; j < GRID_INTERPOLATION_TESTS ; j++)
@@ -115,10 +125,11 @@ void grid_interpolation_benchmark(openfpm::vector<size_t> & nk_grid,
 			measures.add(tstl.getwct());
 		}
 		standard_deviation(measures,mean,dev);
-		time_interpolation_m2p_mean.add(mean);
-		time_interpolation_m2p_dev.add(dev);
 
-		std::cout << "Time mesh to particles " << time_interpolation_m2p_mean.last() << std::endl;
+		interpolation_graph.put(base_m2p + ".data.mean",mean);
+		interpolation_graph.put(base_m2p + ".data.dev",dev);
+
+		std::cout << "Time mesh to particles " << mean << std::endl;
 	}
 }
 
@@ -190,10 +201,7 @@ double grid_iterator_benchmark_norm(grid_dist_id<3, float, aggregate<long int>,
  *
  */
 template<unsigned int dim> void grid_iterator_benchmark(openfpm::vector<size_t> & nk_grid,
-														   openfpm::vector<double> & time_iterator_normal_mean,
-														   openfpm::vector<double> & time_iterator_stencil_mean,
-														   openfpm::vector<double> & time_iterator_normal_dev,
-														   openfpm::vector<double> & time_iterator_stencil_dev)
+														   boost::property_tree::ptree & iterator_graph)
 {
 	std::string str("Testing " + std::to_string(dim) + "D grid iterator stencil and normal");
 	print_test_v(str,0);
@@ -207,8 +215,14 @@ template<unsigned int dim> void grid_iterator_benchmark(openfpm::vector<size_t>
 			//Number of particles
 			size_t k = nk_grid.get(i);
 
+			std::string base = "performance.grid.iterators(" + std::to_string(i) + ")";
+			iterator_graph.put(base + ".grid.dim",3);
+
+			iterator_graph.put(base + ".grid.x",k);
+			iterator_graph.put(base + ".grid.y",k);
+			iterator_graph.put(base + ".grid.z",k);
 
-			BOOST_TEST_CHECKPOINT( "Testing " << dim << "D vector grid iterator performance k=" << k );
+			BOOST_TEST_CHECKPOINT( "Testing " << dim << "D grid iterator performance k=" << k );
 
 			Box<dim,float> box;
 
@@ -245,11 +259,15 @@ template<unsigned int dim> void grid_iterator_benchmark(openfpm::vector<size_t>
 			double mean;
 			double dev;
 			openfpm::vector<double> measures;
+
 			for (size_t j = 0 ; j < GRID_ITERATOR_TESTS ; j++)
 			{measures.add(grid_iterator_benchmark_stencil(g_dist,total));}
 			standard_deviation(measures,mean,dev);
-			time_iterator_stencil_mean.add(mean);
-			time_iterator_stencil_dev.add(dev);
+
+			iterator_graph.put(base + ".stencil.data.mean",mean);
+			iterator_graph.put(base + ".stencil.data.dev",dev);
+
+			std::cout << "Size: " << nk_grid.get(i) <<  "   stencil: " << mean << std::endl;
 
 			//// NORMAL ////
 
@@ -257,155 +275,13 @@ template<unsigned int dim> void grid_iterator_benchmark(openfpm::vector<size_t>
 			for (size_t j = 0 ; j < GRID_ITERATOR_TESTS ;j++)
 			{measures.add(grid_iterator_benchmark_norm(g_dist,total));}
 			standard_deviation(measures,mean,dev);
-			time_iterator_normal_mean.add(mean);
-			time_iterator_normal_dev.add(dev);
 
-			std::cout << "Size: " << nk_grid.get(i) <<  "    " << total << std::endl;
-		}
-	}
-}
-
-
-/*! \brief Function for verlet performance report
- *
- */
-template<unsigned int dim>
-void grid_iterator_performance_write_report(GoogleChart & cg,
-											openfpm::vector<size_t> & nk_grid,
-											openfpm::vector<double> & time_iterator_stencil_mean,
-											openfpm::vector<double> & time_iterator_stencil_dev,
-											openfpm::vector<double> & time_iterator_normal_mean,
-											openfpm::vector<double> & time_iterator_normal_dev)
-{
-	std::string file_mean(test_dir);
-	std::string file_var(test_dir);
-	file_mean += std::string("/openfpm_pdata/grid_iterator_mean_" + std::to_string(dim) + std::string("_ref"));
-	file_var += std::string("/openfpm_pdata/grid_iterator_dev_" + std::to_string(dim) + std::string("_ref"));
-
-	std::string file_mean_save = std::string("grid_iterator_mean_" + std::to_string(dim) + std::to_string("_ref"));
-	std::string file_var_save = std::string("grid_iterator_dev_" + std::to_string(dim) + std::to_string("_ref"));
-
-	openfpm::vector<size_t> xp = nk_grid;
-
-	openfpm::vector<openfpm::vector<openfpm::vector<double>>> yp_mean;
-	openfpm::vector<openfpm::vector<openfpm::vector<double>>> yp_dev;
+			iterator_graph.put(base + ".normal.data.mean",mean);
+			iterator_graph.put(base + ".normal.data.dev",dev);
 
-	openfpm::vector<std::string> names;
-	openfpm::vector<std::string> gnames;
-
-/*	yp_mean.add();
-	yp_dev.add();
-	yp_mean.last().add(time_iterator_stencil_mean);
-	yp_mean.last().add(time_iterator_normal_mean);
-	yp_dev.last().add(time_iterator_stencil_dev);
-	yp_dev.last().add(time_iterator_normal_dev);*/
-
-	yp_mean.resize(1);
-	yp_dev.resize(1);
-	for (size_t i = 0 ; i < yp_mean.size() ; i++)
-	{
-		yp_mean.get(i).resize(time_iterator_stencil_mean.size());
-		yp_dev.get(i).resize(time_iterator_stencil_dev.size());
-
-		for (size_t j = 0 ; j < yp_mean.get(i).size() ; j++)
-		{
-			yp_mean.get(i).get(j).resize(2);
-			yp_dev.get(i).get(j).resize(2);
-
-			yp_mean.get(i).get(j).get(0) = time_iterator_stencil_mean.get(j);
-			yp_mean.get(i).get(j).get(1) = time_iterator_normal_mean.get(j);
-
-			yp_dev.get(i).get(j).get(0) = time_iterator_stencil_dev.get(j);
-			yp_dev.get(i).get(j).get(1) = time_iterator_normal_dev.get(j);
-		}
-	}
-
-	gnames.add("Grid iterators performance for stencil");
-	names.add("Stencil specialized iterator");
-	names.add("Normal iterator");
-
-	std::string y_string = std::string("Time seconds");
-	std::string x_string = std::string("Number of grid poins");
-
-
-	StandardPerformanceGraph(file_mean,
-			                 file_var,
-							 file_mean_save,
-							 file_var_save,
-							 cg,
-							 xp,
-							 yp_mean,
-							 yp_dev,
-							 names,
-							 gnames,
-							 x_string,
-							 y_string,
-							 true);
-}
-
-/*! \brief Function for verlet performance report
- *
- */
-template<unsigned int dim>
-void grid_m2p_performance_write_report(GoogleChart & cg,
-											openfpm::vector<size_t> & nk_grid,
-											openfpm::vector<double> & time_m2p_mean,
-											openfpm::vector<double> & time_m2p_dev)
-{
-	std::string file_mean(test_dir);
-	std::string file_var(test_dir);
-	file_mean += std::string("/openfpm_pdata/grid_m2p_mean_" + std::to_string(dim) + std::string("_ref"));
-	file_var += std::string("/openfpm_pdata/grid_m2p_dev_" + std::to_string(dim) + std::string("_ref"));
-
-	std::string file_mean_save = std::string("grid_m2p_mean_" + std::to_string(dim) + std::to_string("_ref"));
-	std::string file_var_save = std::string("grid_m2p_dev_" + std::to_string(dim) + std::to_string("_ref"));
-
-	openfpm::vector<size_t> xp = nk_grid;
-
-	openfpm::vector<openfpm::vector<openfpm::vector<double>>> yp_mean;
-	openfpm::vector<openfpm::vector<openfpm::vector<double>>> yp_dev;
-
-	openfpm::vector<std::string> names;
-	openfpm::vector<std::string> gnames;
-
-	yp_mean.resize(1);
-	yp_dev.resize(1);
-	for (size_t i = 0 ; i < yp_mean.size() ; i++)
-	{
-		yp_mean.get(i).resize(time_iterator_stencil_mean.size());
-		yp_dev.get(i).resize(time_iterator_stencil_dev.size());
-
-		for (size_t j = 0 ; j < yp_mean.get(i).size() ; j++)
-		{
-			yp_mean.get(i).get(j).resize(1);
-			yp_dev.get(i).get(j).resize(1);
-
-			yp_mean.get(i).get(j).get(0) = time_m2p_mean.get(j);
-			yp_dev.get(i).get(j).get(0) = time_m2p_dev.get(j);
+			std::cout << "Size: " << nk_grid.get(i) <<  "   normal: " << mean << std::endl;
 		}
 	}
-
-	gnames.add("Grid m2p performance");
-	names.add("Mesh to particle performance");
-
-	std::string y_string = std::string("Time seconds");
-	std::string x_string = std::string("Number of grid poins");
-
-
-	StandardPerformanceGraph(file_mean,
-			                 file_var,
-							 file_mean_save,
-							 file_var_save,
-							 cg,
-							 xp,
-							 yp_mean,
-							 yp_dev,
-							 names,
-							 gnames,
-							 x_string,
-							 y_string,
-							 true);
-
 }
 
 
@@ -418,10 +294,7 @@ BOOST_AUTO_TEST_CASE( grid_interpolation_benchmark_test )
 
 	//Benchmark test for 2D and 3D
 	grid_interpolation_benchmark(nk_grid_int,
-			                time_inte_p2m_mean,
-							time_inte_m2p_mean,
-							time_inte_p2m_dev,
-							time_inte_m2p_dev);
+							report_grid_iterator.graphs);
 }
 
 BOOST_AUTO_TEST_CASE( grid_iterator_benchmark_test )
@@ -432,36 +305,58 @@ BOOST_AUTO_TEST_CASE( grid_iterator_benchmark_test )
 
 	//Benchmark test for 2D and 3D
 	grid_iterator_benchmark<3>(nk_grid_st,
-			                time_iterator_normal_mean,
-							time_iterator_stencil_mean,
-							time_iterator_normal_dev,
-							time_iterator_stencil_dev);
+								report_grid_iterator.graphs);
 }
 
 
 BOOST_AUTO_TEST_CASE(grid_iterator_performance_write_report_final)
 {
-	GoogleChart cg;
+	report_grid_iterator.graphs.put("graphs.graph(0).type","line");
+	report_grid_iterator.graphs.add("graphs.graph(0).title","Grid iterators performance for stencil");
+	report_grid_iterator.graphs.add("graphs.graph(0).x.title","Number of grid points");
+	report_grid_iterator.graphs.add("graphs.graph(0).y.title","Time seconds");
+	report_grid_iterator.graphs.add("graphs.graph(0).y.data(0).source","performance.grid.iterators(#).normal.data.mean");
+	report_grid_iterator.graphs.add("graphs.graph(0).x.data(0).source","performance.grid.iterators(#).grid.x");
+	report_grid_iterator.graphs.add("graphs.graph(0).y.data(0).title","Normal iterator");
+	report_grid_iterator.graphs.add("graphs.graph(0).y.data(1).source","performance.grid.iterators(#).stencil.data.mean");
+	report_grid_iterator.graphs.add("graphs.graph(0).x.data(1).source","performance.grid.iterators(#).grid.x");
+	report_grid_iterator.graphs.add("graphs.graph(0).y.data(1).title","Stencil specialized iterator");
+	report_grid_iterator.graphs.add("graphs.graph(0).options.log_y","true");
+
+	report_grid_iterator.graphs.put("graphs.graph(1).type","line");
+	report_grid_iterator.graphs.add("graphs.graph(1).title","Grid p2m performance");
+	report_grid_iterator.graphs.add("graphs.graph(1).x.title","Number of grid points");
+	report_grid_iterator.graphs.add("graphs.graph(1).y.title","Time seconds");
+	report_grid_iterator.graphs.add("graphs.graph(1).y.data(0).source","performance.interpolation.p2m(#).data.mean");
+	report_grid_iterator.graphs.add("graphs.graph(1).y.data(0).title","Interpolation p2m");
+	report_grid_iterator.graphs.add("graphs.graph(1).x.data(0).source","performance.interpolation.p2m(#).grid.x");
+	report_grid_iterator.graphs.add("graphs.graph(1).options.log_y","true");
+
+	report_grid_iterator.graphs.put("graphs.graph(2).type","line");
+	report_grid_iterator.graphs.add("graphs.graph(2).title","Grid m2p performance");
+	report_grid_iterator.graphs.add("graphs.graph(2).x.title","Number of grid points");
+	report_grid_iterator.graphs.add("graphs.graph(2).y.title","Time seconds");
+	report_grid_iterator.graphs.add("graphs.graph(2).x","performance.interpolation.m2p(#).grid.x");
+	report_grid_iterator.graphs.add("graphs.graph(2).y.data(0).source","performance.interpolation.m2p(#).data.mean");
+	report_grid_iterator.graphs.add("graphs.graph(2).y.data(0).title","Interpolation m2p");
+	report_grid_iterator.graphs.add("graphs.graph(2).x.data(0).source","performance.interpolation.m2p(#).grid.x");
+	report_grid_iterator.graphs.add("graphs.graph(2).options.log_y","true");
+
+	boost::property_tree::xml_writer_settings<std::string> settings(' ', 4);
+	boost::property_tree::write_xml("grid_performance.xml", report_grid_iterator.graphs,std::locale(),settings);
 
-	//Write report for 2D and 3D
-	grid_iterator_performance_write_report<3>(cg,
-            								  nk_grid_st,
-											  time_iterator_stencil_mean,
-											  time_iterator_stencil_dev,
-											  time_iterator_normal_mean,
-											  time_iterator_normal_dev);
+	GoogleChart cg;
 
+	std::string file_xml_ref(test_dir);
+	file_xml_ref += std::string("/openfpm_pdata/grid_performance_ref.xml");
 
-	grid_m2p_performance_write_report<3>(cg,
-										nk_grid_int,
-										time_inte_m2p_mean,
-										time_inte_m2p_dev);
+	StandardXMLPerformanceGraph("grid_performance.xml",file_xml_ref,cg);
 
 	if (create_vcluster().getProcessUnitID() == 0)
 	{
 		addUpdtateTime(cg);
 
-		cg.write("grid_iterator_performance.html");
+		cg.write("grid_performance.html");
 	}
 }
 
diff --git a/src/Vector/performance/cell_list_comp_reorder.hpp b/src/Vector/performance/cell_list_comp_reorder.hpp
index 86ac5f598..0f3747423 100644
--- a/src/Vector/performance/cell_list_comp_reorder.hpp
+++ b/src/Vector/performance/cell_list_comp_reorder.hpp
@@ -14,7 +14,16 @@
 #include "vector_dist_performance_util.hpp"
 #include "cl_comp_performance_graph.hpp"
 
-BOOST_AUTO_TEST_SUITE( celllist_comp_reorder_performance_test )
+// Property tree
+struct report_cell_list_func_tests
+{
+	boost::property_tree::ptree graphs;
+};
+
+report_cell_list_func_tests report_cl_funcs;
+
+BOOST_AUTO_TEST_SUITE( celllist_getCellList_calc_forces_performance_test )
+
 
 ///////////////////// INPUT DATA //////////////////////
 
@@ -51,7 +60,7 @@ openfpm::vector<openfpm::vector<double>> time_create_hilb_2_dev;
 /*! \brief Function for random cell list test
  *
  */
-template<unsigned int dim> void cell_list_comp_reorder_random_benchmark(size_t cl_k_start,
+template<unsigned int dim> void cell_list_getCellList_calc_force_benchmark(size_t cl_k_start,
 		                                                                size_t cl_k_min,
 																		openfpm::vector<float> & cl_r_cutoff,
 																		openfpm::vector<size_t> & cl_n_particles,
@@ -60,6 +69,8 @@ template<unsigned int dim> void cell_list_comp_reorder_random_benchmark(size_t c
 																		openfpm::vector<openfpm::vector<double>> & cl_time_create_rand_mean,
 																		openfpm::vector<openfpm::vector<double>> & cl_time_create_rand_dev)
 {
+	report_cl_funcs.graphs.put("performance.celllist.dim",std::to_string(dim));
+
 	cl_time_rand_mean.resize(cl_r_cutoff.size());
 	cl_time_create_rand_mean.resize(cl_r_cutoff.size());
 	cl_time_rand_dev.resize(cl_r_cutoff.size());
@@ -83,11 +94,17 @@ template<unsigned int dim> void cell_list_comp_reorder_random_benchmark(size_t c
 			//Counter number for amounts of particles
 			size_t k_count = 1 + log2(k/cl_k_min);
 
+			report_cl_funcs.graphs.put("performance.celllist.getCellList" + std::to_string(dim) + "D(" + std::to_string(r) + ").rcut",r_cut);
+
+			int c = 0;
+
 			//For different number of particles
 			for (size_t k_int = k ; k_int >= cl_k_min ; k_int/=2 )
 			{
 				BOOST_TEST_CHECKPOINT( "Testing " << dim << "D vector with a random cell list k=" << k_int );
 
+				report_cl_funcs.graphs.put("performance.celllist.getCellList" + std::to_string(dim) + "D(" + std::to_string(r) + ").npart(" + std::to_string(c) + ").n",k_int);
+
 				if (cl_n_particles.size() < k_count)
 					cl_n_particles.add(k_int);
 
@@ -120,13 +137,18 @@ template<unsigned int dim> void cell_list_comp_reorder_random_benchmark(size_t c
 
 				openfpm::vector<double> measures;
 				for (size_t n = 0 ; n < N_STAT_TEST; n++)
+				{
 					measures.add(benchmark_get_celllist(NN,vd,r_cut));
+				}
 				standard_deviation(measures,sum_cl_mean,sum_cl_dev);
 				//Average total time
 
 				cl_time_create_rand_mean.get(r).add(sum_cl_mean);
 				cl_time_create_rand_dev.get(r).add(sum_cl_dev);
 
+				report_cl_funcs.graphs.put("performance.celllist.getCellList" + std::to_string(dim) + "D(" + std::to_string(r) + ").npart(" + std::to_string(c) + ").mean",sum_cl_mean);
+				report_cl_funcs.graphs.put("performance.celllist.getCellList" + std::to_string(dim) + "D(" + std::to_string(r) + ").npart(" + std::to_string(c) + ").dev",sum_cl_dev);
+
 				//Calculate forces
 
 				double sum_fr_mean = 0;
@@ -134,14 +156,19 @@ template<unsigned int dim> void cell_list_comp_reorder_random_benchmark(size_t c
 
 				measures.clear();
 				for (size_t l = 0 ; l < N_STAT_TEST; l++)
-					measures.add(benchmark_calc_forces<dim>(NN,vd,r_cut));
+				{measures.add(benchmark_calc_forces<dim>(NN,vd,r_cut));}
 				standard_deviation(measures,sum_fr_mean,sum_fr_dev);
 
 				cl_time_rand_mean.get(r).add(sum_fr_mean);
 				cl_time_rand_dev.get(r).add(sum_fr_dev);
 
+				report_cl_funcs.graphs.put("performance.celllist.calc_forces" + std::to_string(dim) + "D(" + std::to_string(r) + ").npart(" + std::to_string(c) + ").mean",sum_fr_mean);
+				report_cl_funcs.graphs.put("performance.celllist.calc_forces" + std::to_string(dim) + "D(" + std::to_string(r) + ").npart(" + std::to_string(c) + ").dev",sum_fr_dev);
+
 				if (v_cl.getProcessUnitID() == 0)
 					std::cout << "Cut-off = " << r_cut << ", Particles = " << k_int << ". Time to create a cell-list: " << sum_cl_mean << " dev: " << sum_cl_dev << "    time to calculate forces: " << sum_fr_mean << " dev: " << sum_fr_dev << std::endl;
+
+				c++;
 			}
 		}
 	}
@@ -150,7 +177,7 @@ template<unsigned int dim> void cell_list_comp_reorder_random_benchmark(size_t c
 /*! \brief Function for hilb cell list test
  *
  */
-template<unsigned int dim> void cell_list_comp_reorder_hilbert_benchmark(size_t cl_k_start,
+template<unsigned int dim> void cell_list_getCellList_hilb_calc_force_benchmark(size_t cl_k_start,
 		                                                                 size_t cl_k_min,
 																		 openfpm::vector<float> & cl_r_cutoff,
 																		 openfpm::vector<size_t> & cl_n_particles,
@@ -159,6 +186,8 @@ template<unsigned int dim> void cell_list_comp_reorder_hilbert_benchmark(size_t
 																		 openfpm::vector<openfpm::vector<double>> & cl_time_create_mean,
 																		 openfpm::vector<openfpm::vector<double>> & cl_time_create_dev)
 {
+	report_cl_funcs.graphs.put("performance.celllist.dim",std::to_string(dim));
+
 	cl_time_force_mean.resize(cl_r_cutoff.size());
 	cl_time_create_mean.resize(cl_r_cutoff.size());
 	cl_time_force_dev.resize(cl_r_cutoff.size());
@@ -176,17 +205,23 @@ template<unsigned int dim> void cell_list_comp_reorder_hilbert_benchmark(size_t
 			//Cut-off radius
 			float r_cut = cl_r_cutoff.get(r);
 
+			report_cl_funcs.graphs.put("performance.celllist.getCellList_hilb" + std::to_string(dim) + "D(" + std::to_string(r) + ").rcut",r_cut);
+
 			//Number of particles
 			size_t k = cl_k_start * v_cl.getProcessingUnits();
 
 			//Counter number for amounts of particles
 			size_t k_count = 1 + log2(k/cl_k_min);
 
+			int c = 0;
+
 			//For different number of particles
 			for (size_t k_int = k ; k_int >= cl_k_min ; k_int/=2 )
 			{
 				BOOST_TEST_CHECKPOINT( "Testing " << dim << "D vector with an Hilbert cell list k=" << k_int );
 
+				report_cl_funcs.graphs.put("performance.celllist.getCellList_hilb" + std::to_string(dim) + "D(" + std::to_string(r) + ").npart(" + std::to_string(c) + ").n",k_int);
+
 				if (cl_n_particles.size() < k_count)
 					cl_n_particles.add(k_int);
 
@@ -219,13 +254,16 @@ template<unsigned int dim> void cell_list_comp_reorder_hilbert_benchmark(size_t
 
 				double sum_cl_mean = 0;
 				double sum_cl_dev = 0;
-				for (size_t n = 0 ; n < N_VERLET_TEST; n++)
+				for (size_t n = 0 ; n < N_STAT_TEST; n++)
 				{measures.add(benchmark_get_celllist_hilb(NN,vd,r_cut));}
 				standard_deviation(measures,sum_cl_mean,sum_cl_dev);
 				//Average total time
 				cl_time_create_mean.get(r).add(sum_cl_mean);
 				cl_time_create_dev.get(r).add(sum_cl_dev);
 
+				report_cl_funcs.graphs.put("performance.celllist.getCellList_hilb" + std::to_string(dim) + "D(" + std::to_string(r) + ").npart(" + std::to_string(c) + ").mean",sum_cl_mean);
+				report_cl_funcs.graphs.put("performance.celllist.getCellList_hilb" + std::to_string(dim) + "D(" + std::to_string(r) + ").npart(" + std::to_string(c) + ").dev",sum_cl_dev);
+
 				//Calculate forces
 
 				double sum_fr_mean = 0;
@@ -235,15 +273,21 @@ template<unsigned int dim> void cell_list_comp_reorder_hilbert_benchmark(size_t
 				NN.init_SFC();
 
 				measures.clear();
-				for (size_t l = 0 ; l < N_VERLET_TEST; l++)
+				for (size_t l = 0 ; l < N_STAT_TEST; l++)
 				{measures.add(benchmark_calc_forces_hilb<dim>(NN,vd,r_cut));}
 				standard_deviation(measures,sum_fr_mean,sum_fr_dev);
 
 				cl_time_force_mean.get(r).add(sum_fr_mean);
 				cl_time_force_dev.get(r).add(sum_fr_dev);
 
+				report_cl_funcs.graphs.put("performance.celllist.calc_forces_hilb" + std::to_string(dim) + "D(" + std::to_string(r) + ").npart(" + std::to_string(c) + ").mean",sum_fr_mean);
+				report_cl_funcs.graphs.put("performance.celllist.calc_forces_hilb" + std::to_string(dim) + "D(" + std::to_string(r) + ").npart(" + std::to_string(c) + ").dev",sum_fr_dev);
+
+
 				if (v_cl.getProcessUnitID() == 0)
 				{std::cout << "Cut-off = " << r_cut << ", Particles = " << k_int << ". Time to create: " << sum_cl_mean << " dev: " << sum_cl_dev << " time to calculate force: " << sum_fr_mean << " dev: " << sum_fr_dev << std::endl;}
+
+				c++;
 			}
 		}
 	}
@@ -253,7 +297,7 @@ template<unsigned int dim> void cell_list_comp_reorder_hilbert_benchmark(size_t
 BOOST_AUTO_TEST_CASE( vector_dist_celllist_random_test )
 {
 	//Benchmark test for 2D and 3D
-	cell_list_comp_reorder_random_benchmark<3>(k_start,
+	cell_list_getCellList_calc_force_benchmark<3>(k_start,
 			                                   k_min,
 											   r_cutoff,
 											   n_particles,
@@ -263,7 +307,7 @@ BOOST_AUTO_TEST_CASE( vector_dist_celllist_random_test )
 											   time_create_rand_dev);
 
 
-	cell_list_comp_reorder_random_benchmark<2>(k_start,
+	cell_list_getCellList_calc_force_benchmark<2>(k_start,
 			                                   k_min,
 											   r_cutoff,
 											   n_particles,
@@ -276,7 +320,7 @@ BOOST_AUTO_TEST_CASE( vector_dist_celllist_random_test )
 BOOST_AUTO_TEST_CASE( vector_dist_celllist_hilbert_test )
 {
 	//Benchmark test for 2D and 3D
-	cell_list_comp_reorder_hilbert_benchmark<3>(k_start,
+	cell_list_getCellList_hilb_calc_force_benchmark<3>(k_start,
 			                                    k_min,
 												r_cutoff,
 												n_particles,
@@ -285,7 +329,7 @@ BOOST_AUTO_TEST_CASE( vector_dist_celllist_hilbert_test )
 												time_create_hilb_mean,
 												time_create_hilb_dev);
 
-	cell_list_comp_reorder_hilbert_benchmark<2>(k_start,
+	cell_list_getCellList_hilb_calc_force_benchmark<2>(k_start,
 			                                    k_min,
 												r_cutoff,
 												n_particles,
@@ -335,6 +379,39 @@ template<unsigned int dim> void cell_list_comp_reorder_report(GoogleChart & cg,
 
 BOOST_AUTO_TEST_CASE(vector_dist_cl_performance_write_report)
 {
+	// Create a graphs
+
+	//For different r_cut
+/*	for (size_t r = 0; r < r_cutoff.size(); r++ )
+	{
+		report_cl_funcs.graphs.put("graphs.graph(" + std::to_string(r) + ").type","line");
+		report_cl_funcs.graphs.add("graphs.graph(" + std::to_string(r) + ").title","getCellList performance r_cut=" + std::to_string(r_cutoff.get(r)));
+		report_cl_funcs.graphs.add("graphs.graph(" + std::to_string(r) + ").x.title","number of particles");
+		report_cl_funcs.graphs.add("graphs.graph(" + std::to_string(r) + ").y.title","Time seconds");
+		report_cl_funcs.graphs.add("graphs.graph(" + std::to_string(r) + ").y.data(0).source","performance.celllist.getCellList_hilb3D(" + std::to_string(r) + ").npart(#).mean");
+		report_cl_funcs.graphs.add("graphs.graph(" + std::to_string(r) + ").x.data(0).source","performance.celllist.getCellList_hilb3D(" + std::to_string(r) + ").npart(#).n");
+		report_cl_funcs.graphs.add("graphs.graph(" + std::to_string(r) + ").y.data(0).title","Cell-list hilbert");
+		report_cl_funcs.graphs.add("graphs.graph(" + std::to_string(r) + ").y.data(1).source","performance.celllist.getCellList3D(" + std::to_string(r) + ").npart(#).mean");
+		report_cl_funcs.graphs.add("graphs.graph(" + std::to_string(r) + ").x.data(1).source","performance.celllist.getCellList3D(" + std::to_string(r) + ").npart(#).n");
+		report_cl_funcs.graphs.add("graphs.graph(" + std::to_string(r) + ").y.data(1).title","Cell-list normal");
+		report_cl_funcs.graphs.add("graphs.graph(" + std::to_string(r) + ").options.log_y","true");
+	}
+
+	boost::property_tree::xml_writer_settings<std::string> settings(' ', 4);
+	boost::property_tree::write_xml("celllist_performance.xml", report_cl_funcs.graphs,std::locale(),settings);*/
+
+	GoogleChart cg;
+
+	std::string file_xml_ref(test_dir);
+	file_xml_ref += std::string("/openfpm_pdata/celllist_performance_ref.xml");
+
+	StandardXMLPerformanceGraph("celllist_performance.xml",file_xml_ref,cg);
+
+	addUpdtateTime(cg);
+
+	cg.write("celllist_performance.html");
+
+/*
 	GoogleChart cg;
 
 	double warning_level = 0;
@@ -373,11 +450,8 @@ BOOST_AUTO_TEST_CASE(vector_dist_cl_performance_write_report)
 
 	if (create_vcluster().getProcessUnitID() == 0)
 	{
-		// write the xml report
-		pt.put("celllist.comp.warning",warning_level);
-
 		cg.write("Celllist_comp_ord.html");
-	}
+	}*/
 }
 
 
diff --git a/src/Vector/performance/vector_dist_performance_util.cpp b/src/Vector/performance/vector_dist_performance_util.cpp
index 32bd68187..30262447b 100644
--- a/src/Vector/performance/vector_dist_performance_util.cpp
+++ b/src/Vector/performance/vector_dist_performance_util.cpp
@@ -9,18 +9,10 @@
 
 #include "vector_dist_performance_util.hpp"
 #include "Plot/GoogleChart.hpp"
+#include <boost/property_tree/xml_parser.hpp>
+#include <boost/foreach.hpp>
+#include "util/performance/performance_util.hpp"
 
-void addUpdtateTime(GoogleChart & cg)
-{
-    time_t t = time(0);   // get time now
-    struct tm * now = localtime( & t );
-
-    std::stringstream str;
-
-    str << "<h3>Updated: " << now->tm_mday << "/" << now->tm_mon + 1 << "/" << now->tm_year+1900 << "     " << now->tm_hour << ":" << now->tm_min << ":" << now->tm_sec << std::endl;
-
-	cg.addHTML(str.str());
-}
 
 /*! \brief Draw a standard performance graph
  *
diff --git a/src/Vector/performance/vector_dist_performance_util.hpp b/src/Vector/performance/vector_dist_performance_util.hpp
index df6eee591..b8a6153f3 100644
--- a/src/Vector/performance/vector_dist_performance_util.hpp
+++ b/src/Vector/performance/vector_dist_performance_util.hpp
@@ -8,6 +8,7 @@
 #ifndef SRC_VECTOR_VECTOR_DIST_PERFORMANCE_UTIL_HPP_
 #define SRC_VECTOR_VECTOR_DIST_PERFORMANCE_UTIL_HPP_
 
+#include <boost/property_tree/ptree.hpp>
 #include "Plot/GoogleChart.hpp"
 #include "vector_dist_performance_common.hpp"
 
@@ -15,86 +16,6 @@
 #define N_VERLET_TEST 3
 #define N_STAT_TEST 30
 
-static inline void warning_set(int & warning_level, double mean, double mean_ref, double sigma)
-{
-	int warning_level_candidate;
-
-	if (mean - mean_ref < -2.0*sigma )
-		warning_level_candidate = -1;
-	else if (mean - mean_ref < 2.0*sigma)
-		warning_level_candidate = 0;
-	else if (mean - mean_ref < 3.0*sigma)
-		warning_level_candidate = 1;
-	else
-		warning_level_candidate = 2;
-
-	if (warning_level_candidate > warning_level)
-		warning_level = warning_level_candidate;
-}
-
-static inline void addchartarea(std::string & chart_area, int lvl)
-{
-	std::string color;
-
-	if (lvl == -1)
-	{
-		chart_area = std::string(",chartArea: {\
-		    backgroundColor: {\
-		        stroke: '#00FF00',\
-		        strokeWidth: 6\
-		    }\
-		}");
-	}
-	else if (lvl == 0)
-	{
-		// NOTHING TO DO
-	}
-	else if (lvl == 1)
-	{
-		chart_area = std::string(",chartArea: {\
-		    backgroundColor: {\
-		        stroke: '#FFFF00',\
-		        strokeWidth: 6\
-		    }\
-		}");
-	}
-	else if (lvl == 2)
-	{
-		chart_area = std::string(",chartArea: {\
-		    backgroundColor: {\
-		        stroke: '#FF0000',\
-		        strokeWidth: 6\
-		    }\
-		}");
-	}
-
-}
-
-void addUpdtateTime(GoogleChart & cg);
-
-/*! \brief Standard deviation
- *
- * \param measures set of measures
- * \param mean the mean of the measures
- *
- * \return the standard deviation
- *
- */
-static inline void standard_deviation(openfpm::vector<double> measures, double & mean, double & dev)
-{
-	mean = 0;
-	for (size_t i = 0 ; i < measures.size() ; i++)
-		mean += measures.get(i);
-	mean /= measures.size();
-
-	dev = 0;
-	for (size_t i = 0 ; i < measures.size() ; i++)
-		dev += (measures.get(i) - mean)*(measures.get(i) - mean);
-
-	dev = sqrt(dev / (measures.size() - 1));
-}
-
-
 
 /*! \brief Benchmark particles' forces time
  *
@@ -146,7 +67,8 @@ template<typename V> double benchmark_reorder(V & vd, size_t m)
  *
  * \return real time
  */
-template<typename T, typename V> double benchmark_get_celllist(T & NN, V & vd, float r_cut)
+template<typename T, typename V>
+double benchmark_get_celllist(T & NN, V & vd, float r_cut)
 {
 	// Cell list timer
 	timer t;
@@ -290,5 +212,4 @@ extern void StandardPerformanceGraph(std::string file_mean,
 							  std::string y_string,
 							  bool use_log);
 
-
 #endif /* SRC_VECTOR_VECTOR_DIST_PERFORMANCE_UTIL_HPP_ */
diff --git a/src/Vector/performance/verlet_performance_tests.hpp b/src/Vector/performance/verlet_performance_tests.hpp
index da2ced65b..f955031c7 100644
--- a/src/Vector/performance/verlet_performance_tests.hpp
+++ b/src/Vector/performance/verlet_performance_tests.hpp
@@ -8,6 +8,8 @@
 #ifndef SRC_VECTOR_VECTOR_DIST_VERLET_PERFORMANCE_TESTS_HPP_
 #define SRC_VECTOR_VECTOR_DIST_VERLET_PERFORMANCE_TESTS_HPP_
 
+#include "util/stat/common_statistics.hpp"
+
 /*! \brief Print a string about the test
  *
  * \param test string to print
diff --git a/src/pdata_performance.cpp b/src/pdata_performance.cpp
index 92c6bce0a..ec7362ee9 100644
--- a/src/pdata_performance.cpp
+++ b/src/pdata_performance.cpp
@@ -26,16 +26,18 @@
 
 extern const char * test_dir;
 
-// XML report
-boost::property_tree::ptree pt;
 
 #ifdef PERFORMANCE_TEST
 
+#include "../../openfpm_numerics/src/interpolation/interpolation.hpp"
+#include "Grid/grid_dist_id.hpp"
+#include "Plot/GoogleChart.hpp"
+#include "interpolation/mp4_kernel.hpp"
 #include "Vector/performance/vector_dist_performance_util.hpp"
+#include "util/performance/performance_util.hpp"
 
 BOOST_AUTO_TEST_SUITE( performance )
 
-
 #include "Vector/performance/verlet_performance_tests.hpp"
 #include "Vector/performance/cell_list_part_reorder.hpp"
 #include "Vector/performance/cell_list_comp_reorder.hpp"
-- 
GitLab