diff --git a/build_pdata.sh b/build_pdata.sh new file mode 100644 index 0000000000000000000000000000000000000000..77b1fd6345766961a77619ead167fcea385576fb --- /dev/null +++ b/build_pdata.sh @@ -0,0 +1,118 @@ +#! /bin/bash + +# Make a directory in /tmp/OpenFPM_data + +echo "Directory: $1" +echo "Machine: $2" + +mkdir /tmp/openfpm_pdata +mv * .[^.]* /tmp/openfpm_pdata +mv /tmp/openfpm_pdata OpenFPM_pdata + +mkdir OpenFPM_pdata/src/config + +git clone ssh://git@ppmcoremirror.dynu.com:2222/incardon/openfpm_vcluster.git OpenFPM_vcluster +git clone ssh://git@ppmcoremirror.dynu.com:2222/incardon/openfpm_devices.git OpenFPM_devices +git clone ssh://git@ppmcoremirror.dynu.com:2222/incardon/openfpm_data.git OpenFPM_data +cd OpenFPM_pdata +git checkout develop +cd .. + +cd "$1/OpenFPM_pdata" + +if [ "$2" == "gin" ] +then + echo "Compiling on gin\n" + module load gcc/4.9.2 + module load openmpi/1.8.1 +elif [ "$2" == "wetcluster" ] +then + echo "Compiling on wetcluster" + +## produce the module path + + export MODULEPATH="/sw/apps/modules/modulefiles:$MODULEPATH" + + script="module load gcc/4.9.2\n +module load openmpi/1.8.1\n +module load boost/1.54.0\n +compile_options='--with-boost=/sw/apps/boost/1.54.0/'\n +\n +sh ./autogen.sh\n +sh ./configure \"\$compile_options\" CXX=mpic++\n +make\n +if [ \"\$?\" = "0" ]; then exit 1 ; fi\n +exit(0)\n" + + echo $script | sed -r 's/\\n/\n/g' > compile_script + + bsub -o output_compile.%J -K -n 1 -J compile sh ./compile_script + +## Run on the cluster + bsub -o output_run2.%J -K -n 2 -R "span[hosts=1]" "module load openmpi/1.8.1 ; module load gcc/4.9.2; mpirun -np 2 ./src/pdata" + if [ $? -ne 0 ]; then exit 1 ; fi + bsub -o output_run3.%J -K -n 3 -R "span[hosts=1]" "module load openmpi/1.8.1 ; module load gcc/4.9.2; mpirun -np 3 ./src/pdata" + if [ $? -ne 0 ]; then exit 1 ; fi + bsub -o output_run4.%J -K -n 4 -R "span[hosts=1]" "module load openmpi/1.8.1 ; module load gcc/4.9.2; mpirun -np 4 ./src/pdata" + if [ $? -ne 0 ]; then exit 1 ; fi + bsub -o output_run5.%J -K -n 5 -R "span[hosts=1]" "module load openmpi/1.8.1 ; module load gcc/4.9.2; mpirun -np 5 ./src/pdata" + if [ $? -ne 0 ]; then exit 1 ; fi + bsub -o output_run6.%J -K -n 6 -R "span[hosts=1]" "module load openmpi/1.8.1 ; module load gcc/4.9.2; mpirun -np 6 ./src/pdata" + if [ $? -ne 0 ]; then exit 1 ; fi + bsub -o output_run6.%J -K -n 7 -R "span[hosts=1]" "module load openmpi/1.8.1 ; module load gcc/4.9.2; mpirun -np 7 ./src/pdata" + if [ $? -ne 0 ]; then exit 1 ; fi + bsub -o output_run6.%J -K -n 8 -R "span[hosts=1]" "module load openmpi/1.8.1 ; module load gcc/4.9.2; mpirun -np 8 ./src/pdata" + if [ $? -ne 0 ]; then exit 1 ; fi + bsub -o output_run6.%J -K -n 9 -R "span[hosts=1]" "module load openmpi/1.8.1 ; module load gcc/4.9.2; mpirun -np 9 ./src/pdata" + if [ $? -ne 0 ]; then exit 1 ; fi + bsub -o output_run6.%J -K -n 10 -R "span[hosts=1]" "module load openmpi/1.8.1 ; module load gcc/4.9.2; mpirun -np 10 ./src/pdata" + if [ $? -ne 0 ]; then exit 1 ; fi + bsub -o output_run6.%J -K -n 11 -R "span[hosts=1]" "module load openmpi/1.8.1 ; module load gcc/4.9.2; mpirun -np 11 ./src/pdata" + if [ $? -ne 0 ]; then exit 1 ; fi + bsub -o output_run12.%J -K -n 12 -R "span[hosts=1]" "module load openmpi/1.8.1 ; module load gcc/4.9.2; mpirun -np 12 ./src/vcluster" + if [ $? -ne 0 ]; then exit 1 ; fi +# bsub -o output_run32.%J -K -n 32 "module load openmpi/1.8.1 ; module load gcc/4.9.2; mpirun -np 32 ./src/vcluster" +# if [ $? -ne 0 ]; then exit 1 ; fi +# bsub -o output_run32.%J -K -n 64 "module load openmpi/1.8.1 ; module load gcc/4.9.2; mpirun -np 64 ./src/vcluster" +# if [ $? -ne 0 ]; then exit 1 ; fi +# bsub -o output_run32.%J -K -n 128 "module load openmpi/1.8.1 ; module load gcc/4.9.2; mpirun -np 128 ./src/vcluster" +# if [ $? -ne 0 ]; then exit 1 ; fi +elif [ "$2" == "taurus" ] +then + echo "Compiling on taurus" + + echo "$PATH" + module load gcc/4.8.2 + module load boost/1.55.0-gnu4.8 + module load openmpi/1.8.7 + module unload bullxmpi + + sh ./autogen.sh + sh ./configure --enable-verbose CXX=mpic++ + make + if [ $? -ne 0 ]; then exit 1 ; fi + +# salloc --nodes=1 --ntasks-per-node=16 --time=00:05:00 --mem-per-cpu=1900 --partition=haswell bash -c "ulimit -s unlimited && mpirun -np 16 src/vcluster" +# if [ $? -ne 0 ]; then exit 1 ; fi +# salloc --nodes=2 --ntasks-per-node=16 --time=00:05:00 --mem-per-cpu=1900 --partition=haswell bash -c "ulimit -s unlimited && mpirun -np 32 src/vcluster" +# if [ $? -ne 0 ]; then exit 1 ; fi +# salloc --nodes=4 --ntasks-per-node=16 --time=00:05:00 --mem-per-cpu=1900 --partition=haswell bash -c "ulimit -s unlimited && mpirun -np 64 src/vcluster" +# if [ $? -ne 0 ]; then exit 1 ; fi +# salloc --nodes=8 --ntasks-per-node=16 --time=00:05:00 --mem-per-cpu=1900 --partition=haswell bash -c "ulimit -s unlimited && mpirun -np 128 src/vcluster" +# if [ $? -ne 0 ]; then exit 1 ; fi +# salloc --nodes=16 --ntasks-per-node=16 --time=00:5:00 --mem-per-cpu=1900 --partition=haswell bash -c "ulimit -s unlimited && mpirun -np 256 src/vcluster" +# if [ $? -ne 0 ]; then exit 1 ; fi + +else + echo "Compiling general" + sh ./autogen.sh + sh ./configure CXX=mpic++ + make + + mpirun -np 2 ./src/pdata + mpirun -np 3 ./src/pdata + mpirun -np 4 ./src/pdata +fi + + + diff --git a/src/Decomposition/CartDecomposition.hpp b/src/Decomposition/CartDecomposition.hpp index 7483463baa4cd3929cfd74d2c421e84ee6911b33..78a60eac6345b6d8bd3444d24dc61c431f5f0487 100644 --- a/src/Decomposition/CartDecomposition.hpp +++ b/src/Decomposition/CartDecomposition.hpp @@ -90,12 +90,40 @@ class CartDecomposition size_t proc; }; - //! It contain a box definition and from witch sub-domain it come from + /*! It contain a box definition and from witch sub-domain it come from (in the local processor) + * and an unique across adjacent processors (for communication) + * + * If the box come from the intersection of an expanded sub-domain and a sub-domain + * + * Assuming we are considering the adjacent processor i (0 to getNNProcessors()) + * + * ### external ghost box + * + * id = id_exp + N_non_exp + id_non_exp + * + * id_exp = the id in the vector proc_adj_box.get(i) of the expanded sub-domain + * + * id_non_exp = the id in the vector nn_processor_subdomains[i] of the sub-domain + * + * ### internal ghost box + * + * id = id_exp + N_non_exp + id_non_exp + * + * id_exp = the id in the vector nn_processor_subdomains[i] of the expanded sub-domain + * + * id_non_exp = the id in the vector proc_adj_box.get(i) of the sub-domain + * + */ + /* + */ struct Box_sub : public Box<dim,T> { // Domain id size_t sub; + // Id + size_t id; + Box_sub operator=(const Box<dim,T> & box) { ::Box<dim,T>::operator=(box); @@ -106,7 +134,7 @@ class CartDecomposition }; - //! Particular case for internal ghost boxes, in contain the internal local ghost box + //! Particular case for local internal ghost boxes struct Box_sub_k : public Box<dim,T> { // Domain id @@ -190,6 +218,9 @@ private: // for each near-processor store the sub-domain of the near processor std::unordered_map<size_t, N_box> nn_processor_subdomains; + // for each processor store the set of the sub-domains sent to the adjacent processors + openfpm::vector<openfpm::vector<size_t>> proc_adj_box; + //! it contain the internal ghosts of the local processor openfpm::vector<lBox_dom> loc_ghost_box; @@ -579,6 +610,19 @@ private: proc_int_box_g.ebx.add(); proc_int_box_g.ebx.last() = bi; proc_int_box_g.ebx.last().sub = i; + + // Search for the correct id + size_t k = 0; + size_t p_idp = ProctoID(p_id); + for (k = 0 ; k < proc_adj_box.get(p_idp).size() ; k++) + { + if (proc_adj_box.get(p_idp).get(k) == i) + break; + } + if (k == proc_adj_box.get(p_idp).size()) + std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " sub-domain not found\n"; + + proc_int_box_g.ebx.last().id = (k * nn_processor_subdomains_g.size() + b) * v_cl.getProcessingUnits() + p_id; } } } @@ -665,6 +709,19 @@ private: sb = b_int.box; sb.sub = i; + // Search for the correct id + size_t s = 0; + size_t p_idp = ProctoID(p_id); + for (s = 0 ; s < proc_adj_box.get(p_idp).size() ; s++) + { + if (proc_adj_box.get(p_idp).get(s) == i) + break; + } + if (s == proc_adj_box.get(p_idp).size()) + std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " sub-domain not found\n"; + + sb.id = (k * proc_adj_box.get(p_idp).size() + s) * v_cl.getProcessingUnits() + v_cl.getProcessUnitID(); + pr_box_int.ibx.add(sb); // update the geo_cell list @@ -1048,6 +1105,7 @@ p1[0]<-----+ +----> p2[0] // of the sub-domains contiguous to the processor A are sent to the processor A and // the information of the contiguous sub-domains in the near processors are received // + proc_adj_box.resize(getNNProcessors()); openfpm::vector< openfpm::vector< ::SpaceBox<dim,T>> > boxes(nn_processors.size()); for (size_t b = 0 ; b < box_nn_processor.size() ; b++) @@ -1061,6 +1119,7 @@ p1[0]<-----+ +----> p2[0] size_t id = nn_processor_subdomains[prc].id; boxes.get(id).add(sub_domains.get(b)); + proc_adj_box.get(id).add(b); } } @@ -1362,7 +1421,7 @@ p1[0]<-----+ +----> p2[0] return proc_int_box.get(id).ibx.get(j); } - /*! \brief Get the j External ghost box for one processor + /*! \brief Get the j External ghost box * * \param id near processor list id (the id go from 0 to getNNProcessor()) * \param j box (each near processor can produce more than one external ghost box) @@ -1374,6 +1433,30 @@ p1[0]<-----+ +----> p2[0] return proc_int_box.get(id).ebx.get(j); } + /*! \brief Get the j Internal ghost box id + * + * \param id near processor list id (the id go from 0 to getNNProcessor()) + * \param j box (each near processor can produce more than one internal ghost box) + * \return the box + * + */ + inline size_t getProcessorIGhostId(size_t id, size_t j) const + { + return proc_int_box.get(id).ibx.get(j).id; + } + + /*! \brief Get the j External ghost box id + * + * \param id near processor list id (the id go from 0 to getNNProcessor()) + * \param j box (each near processor can produce more than one external ghost box) + * \return the box + * + */ + inline size_t getProcessorEGhostId(size_t id, size_t j) const + { + return proc_int_box.get(id).ebx.get(j).id; + } + /*! \brief For the sub-domain i intersected with the sub-domain j enlarged, the associated * external ghost box is located in getLocalIGhostBox(j,k) with * getLocalIGhostSub(j,k) == i, this function return k @@ -1676,6 +1759,32 @@ p1[0]<-----+ +----> p2[0] return true; } + + void debugPrint() + { +// if (v_cl.getProcessUnitID() == 3) +// { + std::cout << "External ghost box\n"; + + for (size_t p = 0 ; p < getNNProcessors() ; p++) + { + for (size_t i = 0 ; i < getProcessorNEGhost(p) ; i++) + { + std::cout << getProcessorEGhostBox(p,i).toString() << " prc=" << IDtoProc(p) << " id=" << getProcessorEGhostId(p,i) << "\n"; + } + } + + std::cout << "Internal ghost box\n"; + + for (size_t p = 0 ; p < getNNProcessors() ; p++) + { + for (size_t i = 0 ; i < getProcessorNIGhost(p) ; i++) + { + std::cout << getProcessorIGhostBox(p,i).toString() << " prc=" << IDtoProc(p) << " id=" << getProcessorIGhostId(p,i) << "\n"; + } + } + } +// } }; diff --git a/src/Grid/grid_dist_id.hpp b/src/Grid/grid_dist_id.hpp index 14fed24a6277cf83176fa9407fdd36b996e56128..a9aa4805e4b902063e43590669012ad914b0075c 100644 --- a/src/Grid/grid_dist_id.hpp +++ b/src/Grid/grid_dist_id.hpp @@ -179,7 +179,7 @@ class grid_dist_id i_box_id bid_t; bid_t.box = cvt; - bid_t.g_id = g.LinId(bid_t.box.middle().asArray()); + bid_t.g_id = dec.getProcessorIGhostId(i,j); bid_t.sub = dec.getProcessorIGhostSub(i,j); pib.bid.add(bid_t); } @@ -234,7 +234,7 @@ class grid_dist_id pib.bid.add(bid_t); // Add the map between the global ghost box id and id of the external box in the vector - size_t g_id = g.LinId(ib.middle().asArray()); + size_t g_id = dec.getProcessorEGhostId(i,j); g_id_to_external_ghost_box[g_id] = pib.bid.size()-1; } } diff --git a/src/Grid/grid_dist_id_iterator.hpp b/src/Grid/grid_dist_id_iterator.hpp index 63a45ab2c4f6d55ff49b189a26b5067e8e4492b9..be28396e9ac3bba8061f5705e758839ede8219d6 100644 --- a/src/Grid/grid_dist_id_iterator.hpp +++ b/src/Grid/grid_dist_id_iterator.hpp @@ -207,6 +207,21 @@ class grid_dist_iterator<dim,device_grid,FIXED> //! Actual iterator grid_key_dx_iterator<dim> a_it; + /*! \brief from g_c increment g_c until you find a valid grid + * + */ + void selectValidGrid() + { + // When the grid has size 0 potentially all the other informations are garbage + while (g_c < gList.size() && (gList[g_c].size() == 0 || gdb_ext.get(g_c).Dbox.isValid() == false ) ) g_c++; + + // get the next grid iterator + if (g_c < gList.size()) + { + a_it.reinitialize(gList[g_c].getIterator(gdb_ext.get(g_c).Dbox.getKP1(),gdb_ext.get(g_c).Dbox.getKP2())); + } + } + public: /*! \brief Constructor of the distributed grid @@ -219,7 +234,7 @@ class grid_dist_iterator<dim,device_grid,FIXED> { // Initialize the current iterator // with the first grid - a_it.reinitialize(gList[0].getIterator()); + selectValidGrid(); } // Destructor @@ -245,15 +260,7 @@ class grid_dist_iterator<dim,device_grid,FIXED> { // switch to the new grid g_c++; - - // When the grid has size 0 potentially all the other informations are garbage - while (g_c < gList.size() && gdb_ext.get(g_c).Dbox.getVolumeKey() == 0 ) g_c++; - - // get the next grid iterator - if (g_c < gList.size()) - { - a_it.reinitialize(gList[g_c].getIterator(gdb_ext.get(g_c).Dbox.getKP1(),gdb_ext.get(g_c).Dbox.getKP2())); - } + selectValidGrid(); } return *this; diff --git a/src/Grid/grid_dist_id_unit_test.hpp b/src/Grid/grid_dist_id_unit_test.hpp index 6c1c9f84dd489988b25358e393fbbe572bdf5dca..21d9fca51c7b3477c16ddf1b1343dd3f51c6e42d 100644 --- a/src/Grid/grid_dist_id_unit_test.hpp +++ b/src/Grid/grid_dist_id_unit_test.hpp @@ -94,7 +94,7 @@ BOOST_AUTO_TEST_CASE( grid_dist_id_iterator_test_use) // Initialize the global VCluster init_global_v_cluster(&boost::unit_test::framework::master_test_suite().argc,&boost::unit_test::framework::master_test_suite().argv); - for (long int k = 8 ; k >= 2 ; k-= (k >= 66)?33:1 ) + for (long int k = 1024 ; k >= 2 ; k-= (k >= 66)?33:1 ) { std::cout << "Testing: " << k << "\n"; @@ -109,6 +109,8 @@ BOOST_AUTO_TEST_CASE( grid_dist_id_iterator_test_use) // Distributed grid with id decomposition grid_dist_id<2, float, scalar<float>, CartDecomposition<2,float>> g_dist(sz,domain,g); +// g_dist.getDecomposition().debugPrint(); + // Write the decomposition g_dist.getDecomposition().write("output/");