From 9a77a582e90ecd192472129737431a37cdc91b48 Mon Sep 17 00:00:00 2001 From: Pietro Incardona <incardon@mpi-cbg.de> Date: Tue, 20 Oct 2015 00:33:42 +0200 Subject: [PATCH] Copy decomposition for grid --- src/Decomposition/CartDecomposition.hpp | 20 +++++++- src/Grid/grid_dist_id.hpp | 32 ++++++------ src/Grid/grid_dist_id_unit_test.hpp | 65 +++++++++++++++++++++++++ src/Grid/grid_dist_key.hpp | 18 +++++++ 4 files changed, 119 insertions(+), 16 deletions(-) diff --git a/src/Decomposition/CartDecomposition.hpp b/src/Decomposition/CartDecomposition.hpp index ad48a26e..216c15e7 100644 --- a/src/Decomposition/CartDecomposition.hpp +++ b/src/Decomposition/CartDecomposition.hpp @@ -334,15 +334,33 @@ private: // Receive counter size_t recv_cnt; + // reference counter of the object in case is shared between object + + long int ref_cnt; + public: + //! Increment the reference counter + void incRef() + {ref_cnt++;} + + //! Decrement the reference counter + void decRef() + {ref_cnt--;} + + //! Return the reference counter + long int ref() + { + return ref_cnt; + } + /*! \brief Cartesian decomposition constructor * * \param v_cl Virtual cluster, used internally to handle or pipeline communication * */ CartDecomposition(Vcluster & v_cl) - :nn_prcs<dim,T>(v_cl),v_cl(v_cl) + :nn_prcs<dim,T>(v_cl),v_cl(v_cl),ref_cnt(0) { // Reset the box to zero bbox.zero(); diff --git a/src/Grid/grid_dist_id.hpp b/src/Grid/grid_dist_id.hpp index 5854c665..8bc10131 100644 --- a/src/Grid/grid_dist_id.hpp +++ b/src/Grid/grid_dist_id.hpp @@ -54,7 +54,7 @@ class grid_dist_id Vcluster_object_array<device_grid> loc_grid; //! Space Decomposition - Decomposition dec; + Decomposition & dec; //! Extension of each grid: Domain and ghost + domain openfpm::vector<GBoxes<device_grid::dims>> gdb_ext; @@ -350,9 +350,12 @@ class grid_dist_id public: //! constructor - grid_dist_id(Vcluster v_cl, Decomposition & dec, const size_t (& g_sz)[dim], const Box<dim,St> & domain, const Ghost<dim,T> & ghost) - :domain(domain),ghost(ghost),loc_grid(NULL),v_cl(v_cl),dec(dec) + grid_dist_id(Decomposition & dec, const size_t (& g_sz)[dim], const Box<dim,St> & domain, const Ghost<dim,St> & ghost) + :domain(domain),ghost(ghost),dec(dec),v_cl(*global_v_cluster) { + // Increment the reference counter of the decomposition + dec.incRef(); + check_size(g_sz); // For a 5x5 grid you have 4x4 Cell @@ -363,27 +366,18 @@ public: cd_sm.setDimensions(domain,c_g,0); // fill the global size of the grid - for (int i = 0 ; i < dim ; i++) {this->g_sz[i] = g_sz[i];} + for (size_t i = 0 ; i < dim ; i++) {this->g_sz[i] = g_sz[i];} // Get the number of processor and calculate the number of sub-domain // for decomposition size_t n_proc = v_cl.getProcessingUnits(); size_t n_sub = n_proc * SUB_UNIT_FACTOR; - // Calculate the maximum number (before merging) of sub-domain on - // each dimension - size_t div[dim]; - for (int i = 0 ; i < dim ; i++) - {div[i] = openfpm::math::round_big_2(pow(n_sub,1.0/dim));} - - // Create the sub-domains - dec.setParameters(div); - // Create local grid Create(); // Calculate ghost boxes - dec.calculateGhostBoxes(ghost); + dec.calculateGhostBoxes(); } /*! \brief Constrcuctor @@ -394,8 +388,11 @@ public: * */ grid_dist_id(const size_t (& g_sz)[dim],const Box<dim,St> & domain, const Ghost<dim,St> & g) - :domain(domain),ghost(g),dec(Decomposition(*global_v_cluster)),v_cl(*global_v_cluster) + :domain(domain),ghost(g),dec(*new Decomposition(*global_v_cluster)),v_cl(*global_v_cluster) { + // Increment the reference counter of the decomposition + dec.incRef(); + // check that the grid has valid size check_size(g_sz); @@ -541,6 +538,11 @@ public: //! Destructor ~grid_dist_id() { + dec.decRef(); + + // if we reach the 0, destroy the object + if (dec.ref() == 0) + delete &dec; } /*! \brief Get the Virtual Cluster machine diff --git a/src/Grid/grid_dist_id_unit_test.hpp b/src/Grid/grid_dist_id_unit_test.hpp index fc4cbf3d..d5fe3841 100644 --- a/src/Grid/grid_dist_id_unit_test.hpp +++ b/src/Grid/grid_dist_id_unit_test.hpp @@ -612,6 +612,70 @@ void Test3D_complex(const Box<3,float> & domain, long int k) } } +// Test duplicated topology + +void Test3D_dup(const Box<3,float> & domain, long int k) +{ + typedef Point_test<float> p; + + long int big_step = k / 30; + big_step = (big_step == 0)?1:big_step; + long int small_step = 1; + + Vcluster & v_cl = *global_v_cluster; + + if ( v_cl.getProcessingUnits() > 32 ) + return; + + print_test( "Testing 3D duplicate topology complex k<=",k); + + // 3D test + for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step ) + { + BOOST_TEST_CHECKPOINT( "Testing 3D copy decomposition grid k=" << k ); + + // grid size + size_t sz[3]; + sz[0] = k; + sz[1] = k; + sz[2] = k; + + // factor + float factor = pow(global_v_cluster->getProcessingUnits()/2.0f,1.0f/3.0f); + + // Ghost + Ghost<3,float> g(0.01 / factor); + + //! [Construct two grid with the same topology] + + // Distributed grid with id decomposition + grid_dist_id<3, float, Point_test<float>, CartDecomposition<3,float>> g_dist1(sz,domain,g); + + // another grid with the same decomposition + grid_dist_id<3, float, Point_test<float>, CartDecomposition<3,float>> g_dist2(g_dist1.getDecomposition(),sz,domain,g); + + //! [Construct two grid with the same topology] + + auto dom_g1 = g_dist1.getDomainIterator(); + auto dom_g2 = g_dist2.getDomainIterator(); + + bool check = true; + + while (dom_g1.isNext()) + { + auto key1 = dom_g1.get(); + auto key2 = dom_g2.get(); + + check &= (key1 == key2)?true:false; + + ++dom_g1; + ++dom_g2; + } + + BOOST_REQUIRE_EQUAL(check,true); + } +} + BOOST_AUTO_TEST_CASE( grid_dist_id_iterator_test_use) { // Domain @@ -632,6 +696,7 @@ BOOST_AUTO_TEST_CASE( grid_dist_id_iterator_test_use) k = std::pow(k, 1/3.); Test3D(domain3,k); Test3D_complex(domain3,k); + Test3D_dup(domain3,k); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/Grid/grid_dist_key.hpp b/src/Grid/grid_dist_key.hpp index 9550a694..e62d3b0f 100644 --- a/src/Grid/grid_dist_key.hpp +++ b/src/Grid/grid_dist_key.hpp @@ -40,6 +40,24 @@ public: return key; } + /* \brief Check if two key are the same + * + * \param key_t key to check + * + * \return true if the two key are equal + * + */ + + inline bool operator==(const grid_dist_key_dx<dim> & key_t) + { + if (g_c != key_t.g_c) + return false; + + // Check the two key index by index + + return getKey() == key_t.getKey(); + } + /*! \brief Create a new key moving the old one * * \param i dimension id -- GitLab