Commit 2ab60a4b authored by incardon's avatar incardon

Release_0.8.0

parent 0c66b3b5
......@@ -5,10 +5,11 @@ All notable changes to this project will be documented in this file.
### Added
- Dynamic Load balancing
- Added SPH Dam break with Dynamic load balancing
- Added SPH Dam break with Dynamic load balancing (7_sph_dlb)(7_sph_dlb_opt)
- Added procedure for update ./install --update
(From 0.8.0 version will be supported for bug fixing, version 0.X.0 will be supported untill
0.X+2.0 will be out)
- Added for debugging the options PRINT_STACKTRACE, CHECKFOR_POSNAN, CHECKFOR_POSINF, CHECKFOR_PROPINF, CHECKFOR_PROPNAN, SE_CLASS3 for debugging. Additional example added (7_sph_dlb_safe)
### Changed
- BOOST updated to 1.63
......@@ -27,7 +28,7 @@ All notable changes to this project will be documented in this file.
0.7.0 or apply the patch to upgrade to 0.6.1
- Found and fixed a memory leak when using complex properties
### Changed
-### Changed
- The file VCluster has been mooved #include "VCluster.hpp" must be changed to #include "VCluster/VCluster.hpp"
BECAUSE OF THIS, PLEASE CLEAN THE OPENFPM FOLDER OTHERWISE YOU WILL END TO HAVE 2 VCLUSTER.HPP
......
......@@ -187,7 +187,7 @@ int main(int argc, char* argv[])
vect_dist_key_dx vt(0);
auto it = vd1->getPos(vt);
}
catch (size_t e)
catch (std::exception & e)
{
std::cerr << "Error notification of invalid usage of deleted object \n";
}
......
......@@ -12,6 +12,7 @@
* \subpage Vector_5_md_vl_sym_crs
* \subpage Vector_6_complex_usage
* \subpage Vector_7_sph_dlb
* \subpage Vector_7_sph_dlb_opt
*
*/
......@@ -51,6 +52,7 @@
*/
//! \cond [inclusion] \endcond
#include <stddef.h>
#include "Vector/vector_dist.hpp"
//! \cond [inclusion] \endcond
......
......@@ -13,6 +13,19 @@
* decomposition to keep all the processor load and reduce idle time.
*
* \htmlonly
* <a href="#" onclick="hide_show('vector-video-3')" >Video 1</a>
* <div style="display:none" id="vector-video-3">
* <video id="vid1" width="1200" height="576" controls> <source src="http://openfpm.mpi-cbg.de/web/images/examples/7_SPH_dlb/sph_speed.mp4" type="video/mp4"></video>
* <script>video_anim('vid1',100,230)</script>
* </div>
* <a href="#" onclick="hide_show('vector-video-4')" >Video 2</a>
* <div style="display:none" id="vector-video-4">
* <video id="vid2" width="1200" height="576" controls> <source src="http://openfpm.mpi-cbg.de/web/images/examples/7_SPH_dlb/sph_speed2.mp4" type="video/mp4"></video>
* <script>video_anim('vid2',21,1590)</script>
* </div>
* \endhtmlonly
*
* \htmlonly
* <img src="http://ppmcore.mpi-cbg.de/web/images/examples/7_SPH_dlb/dam_break_all.jpg"/>
* \endhtmlonly
*
......
......@@ -16,7 +16,7 @@ dom_box_CXXFLAGS = $(OPENMP_CFLAGS) $(AM_CXXFLAGS) $(PETSC_INCLUDE) $(METIS_INCL
dom_box_CFLAGS = $(OPENMP_CFLAGS) $(CUDA_CFLAGS)
dom_box_LDADD = $(LINKLIBS)
vector_dist_SOURCES = vector.cpp ../openfpm_devices/src/memory/HeapMemory.cpp ../openfpm_vcluster/src/VCluster/VCluster.cpp ../openfpm_devices/src/memory/PtrMemory.cpp
vector_dist_SOURCES = vector.cpp ../openfpm_devices/src/memory/HeapMemory.cpp ../openfpm_vcluster/src/VCluster/VCluster.cpp ../openfpm_devices/src/memory/PtrMemory.cpp ../openfpm_devices/src/Memleak_check.cpp
vector_dist_CXXFLAGS = $(OPENMP_CFLAGS) $(AM_CXXFLAGS) $(LIBHILBERT_INCLUDE) $(PETSC_INCLUDE) $(PARMETIS_INCLUDE) $(METIS_INCLUDE) $(CUDA_CFLAGS) $(INCLUDES_PATH) $(HDF5_CPPFLAGS) $(BOOST_CPPFLAGS) -I../src -Wno-unused-function -Wno-unused-local-typedefs
vector_dist_CFLAGS = $(OPENMP_CFLAGS) $(CUDA_CFLAGS)
vector_dist_LDADD = $(LINKLIBS) -lparmetis -lmetis
......
......@@ -6,14 +6,34 @@ template<typename T> class Particle
{
public:
#ifdef SE_CLASS3
typedef boost::fusion::vector<T,T[3],T[3][3],SE3_ADD_PROP(3)> type;
#else
typedef boost::fusion::vector<T,T[3],T[3][3]> type;
#endif
type data;
static const unsigned int s = 0;
static const unsigned int v = 1;
static const unsigned int t = 2;
#ifdef SE_CLASS3
static const unsigned int max_prop = SE3_MAX_PROP(3);
static const unsigned int max_prop_real = 3;
#else
static const unsigned int max_prop = 3;
static const unsigned int max_prop_real = 3;
#endif
};
int main(int argc, char* argv[])
......
openfpm_data @ 63bfcfa6
Subproject commit bcdc58554b1ff4b97c85479ac0869565bf76a0b6
Subproject commit 63bfcfa657c6d9cd66eae064a115a08e4eaeb400
openfpm_devices @ b96708b8
Subproject commit a0b02db5938003755b85c86fded64b107ac4e55d
Subproject commit b96708b8c2ca93ef4a8754e58a28bbad506df932
openfpm_io @ 5dfcba90
Subproject commit 4a5f8a2a4d13fe1e4e4537281c11979f3ac87e28
Subproject commit 5dfcba90e49c58fa569f02475635938e285142b1
openfpm_vcluster @ dcf398d0
Subproject commit 5b36046775ce3d7868f14450faade5effc256a14
Subproject commit dcf398d040347c33163f349ffd3ab3f081affb01
......@@ -11,10 +11,21 @@
//! Time structure for statistical purposes
typedef struct
{
//! starting time of the simulation (0)
size_t simulationStartTime = 0;
//! End iteration of the simulation
size_t simulationEndTime;
//! integration time
double timeStep = 0.1;
//! Interval between teo rebalance
//! Start time
size_t iterationStartTime;
//! End time
size_t iterationEndTime;
} Times;
......@@ -89,7 +100,7 @@ private:
/*! \brief Function that gather times informations and decides if a rebalance is needed it uses the SAR heuristic
*
* \param t
* \return true if re-balance is needed
*
*/
inline bool SAR()
......@@ -168,7 +179,12 @@ public:
heuristic = h;
}
/*! \brief Get the heuristic to use
/*! \brief Get the heuristic
*
* Indicate which heuristic model is used to calculate when a rebalance
* is needed
*
* \return the Heuristic used by DLB
*
*/
Heuristic getHeurisitc()
......@@ -176,7 +192,9 @@ public:
return heuristic;
}
/*! \brief check if a re-balance is needed using the SAR heuristic
/*! \brief check if a re-balance is needed using the selected heuristic
*
* \return true if the rebalance is needed
*
*/
bool rebalanceNeeded()
......@@ -193,7 +211,7 @@ public:
/*! \brief Set start time for the simulation
*
* \param simulationStartTime time when the whole simulation starts
* \param t time when the whole simulation starts
*/
void setSimulationStartTime(size_t t)
{
......@@ -201,6 +219,8 @@ public:
}
/*! \brief Get start time for the simulation
*
* \return the start point of the simulation
*
*/
size_t getSimulationStartTime()
......@@ -210,7 +230,7 @@ public:
/*! \brief Set end time for the simulation
*
* \param simulationEndTime time when the whole simulation ends
* \param t time when the whole simulation ends
*/
void setSimulationEndTime(size_t t)
{
......@@ -218,6 +238,8 @@ public:
}
/*! \brief Get end time for the simulation
*
* \return the end time of the simulation
*
*/
size_t getSimulationEndTime()
......@@ -235,7 +257,7 @@ public:
/*! \brief Set start time for the single iteration
*
* \param iterationStartTime time when the single iteration starts
* \param t time when the one iteration starts
*/
void startIteration(size_t t)
{
......@@ -243,6 +265,8 @@ public:
}
/*! \brief Set end time for the single iteration
*
* \param time when one iteration is completed
*
*/
void endIteration()
......@@ -250,18 +274,18 @@ public:
timeInfo.iterationEndTime = clock();
}
/*! \brief Set end time for the single iteration
/*! \brief Set the end time when the previous rebalance has been performed
*
* \param iterationEndTime time when the single iteration ends
* \param t time when one iteration ends
*/
void endIteration(size_t t)
{
timeInfo.iterationEndTime = t;
}
/*! \brief Set time step for the single iteration
/*! \brief Set delta time step for one iteration (Computation time)
*
* \param timestep value, can be also a 0.1 s
* \param t timestep
*/
void setTimeStep(double t)
{
......@@ -278,6 +302,8 @@ public:
}
/*! \brief Get how many time-steps have passed since the last re-balancing
*
* \return number of timesteos
*
*/
size_t getNTimeStepSinceDLB()
......@@ -287,16 +313,16 @@ public:
/*! \brief Set un-balance value
*
* \param computation value of the computation cost (default: 5)
* \param u unbalance
*/
void setUnbalance(float u)
{
unbalance = u;
}
/*! \brief Set un-balance value
/*! \brief threshold of umbalance to start a rebalance
*
* \param computation value of the computation cost (default: 5)
* \param t threshold level
*/
void setThresholdLevel(ThresholdLevel t)
{
......
......@@ -32,6 +32,11 @@ struct ModelLin
{
dec.setSubSubDomainComputationCost(v, dec.getSubSubDomainComputationCost(v));
}
double setDistributionTol(size_t i)
{
return 1.01;
}
};
/*! \brief Linear model
......@@ -52,6 +57,11 @@ struct ModelSquare
{
dec.setSubSubDomainComputationCost(v, dec.getSubSubDomainComputationCost(v) * dec.getSubSubDomainComputationCost(v));
}
double setDistributionTol(size_t i)
{
return 1.01;
}
};
......
......@@ -217,14 +217,6 @@ public:
*/
void createSubdomains(Vcluster & v_cl, const size_t (& bc)[dim], size_t opt = 0)
{
#ifdef SE_CLASS1
if (&v_cl == NULL)
{
std::cerr << __FILE__ << ":" << __LINE__ << " error VCluster instance is null, check that you ever initialized it \n";
ACTION_ON_ERROR()
}
#endif
int p_id = v_cl.getProcessUnitID();
// Calculate the total number of box and and the spacing
......@@ -1028,7 +1020,7 @@ public:
* \param ts number of time step from the previous load balancing
*
*/
void rebalance(size_t ts)
void refine(size_t ts)
{
reset();
......@@ -1044,13 +1036,34 @@ public:
domain_nn_calculator_cart<dim>::reset();
}
/*! \brief Refine the decomposition, available only for ParMetis distribution, for Metis it is a null call
*
* \param ts number of time step from the previous load balancing
*
*/
void redecompose(size_t ts)
{
reset();
if (commCostSet == false)
computeCommunicationAndMigrationCosts(ts);
dist.redecompose();
createSubdomains(v_cl,bc);
calculateGhostBoxes();
domain_nn_calculator_cart<dim>::reset();
}
/*! \brief Refine the decomposition, available only for ParMetis distribution, for Metis it is a null call
*
* \param dlb Dynamic load balancing object
*
* \return true if the re-balance has been executed, false otherwise
*/
bool rebalance(DLB & dlb)
bool refine(DLB & dlb)
{
// if the DLB heuristic to use is the "Unbalance Threshold" get unbalance percentage
if (dlb.getHeurisitc() == DLB::Heuristic::UNBALANCE_THRLD)
......@@ -1065,7 +1078,7 @@ public:
if (dlb.rebalanceNeeded())
{
rebalance(dlb.getNTimeStepSinceDLB());
refine(dlb.getNTimeStepSinceDLB());
return true;
}
......@@ -1552,6 +1565,16 @@ public:
dist.setComputationCost(gid, c + i);
}
/*! \brief Get the decomposition counter
*
* \return the decomposition counter
*
*/
size_t get_ndec()
{
return dist.get_ndec();
}
//! friend classes
friend extended_type;
......
......@@ -311,7 +311,7 @@ public:
/*! \brief Returns total number of neighbors of the sub-sub-domain id
*
* \param i id of the sub-sub-domain
* \param id id of the sub-sub-domain
*/
size_t getNSubSubDomainNeighbors(size_t id)
{
......
......@@ -163,7 +163,7 @@ BOOST_AUTO_TEST_CASE( Metis_distribution_test)
// operator= functions
// operator== functions
BOOST_REQUIRE_EQUAL(sizeof(MetisDistribution<3,float>),536ul);
BOOST_REQUIRE_EQUAL(sizeof(MetisDistribution<3,float>),472ul);
}
BOOST_AUTO_TEST_CASE( Parmetis_distribution_test)
......@@ -264,7 +264,7 @@ BOOST_AUTO_TEST_CASE( Parmetis_distribution_test)
//! [refine with parmetis the decomposition]
BOOST_REQUIRE_EQUAL(sizeof(MetisDistribution<3,float>),536ul);
BOOST_REQUIRE_EQUAL(sizeof(MetisDistribution<3,float>),472ul);
}
BOOST_AUTO_TEST_CASE( DistParmetis_distribution_test)
......
......@@ -11,7 +11,7 @@
#include "SubdomainGraphNodes.hpp"
#include "metis_util.hpp"
#define METIS_DISTRIBUTION_ERROR 100001
#define METIS_DISTRIBUTION_ERROR_OBJECT std::runtime_error("Metis runtime error");
/*! \brief Class that distribute sub-sub-domains across processors using Metis Library
*
......@@ -58,7 +58,7 @@ class MetisDistribution
if (id >= gp.getNVertex())
{
std::cerr << "Error " << __FILE__ ":" << __LINE__ << " such sub-sub-domain doesn't exist (id = " << id << ", " << "total size = " << gp.getNVertex() << ")\n";
ACTION_ON_ERROR(METIS_DISTRIBUTION_ERROR)
ACTION_ON_ERROR(METIS_DISTRIBUTION_ERROR_OBJECT)
}
#endif
}
......@@ -74,7 +74,7 @@ class MetisDistribution
if (e >= gp.getNChilds(id))
{
std::cerr << "Error " << __FILE__ ":" << __LINE__ << " for the sub-sub-domain " << id << " such neighborhood doesn't exist (e = " << e << ", " << "total size = " << gp.getNChilds(id) << ")\n";
ACTION_ON_ERROR(METIS_DISTRIBUTION_ERROR)
ACTION_ON_ERROR(METIS_DISTRIBUTION_ERROR_OBJECT)
}
#endif
}
......@@ -208,7 +208,7 @@ public:
check_valid(this,8);
#endif
std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " MetisDistribution does not have refine functionality";
ACTION_ON_ERROR(METIS_DISTRIBUTION_ERROR);
ACTION_ON_ERROR(METIS_DISTRIBUTION_ERROR_OBJECT);
}
/*! \brief Function that return the position (point P1) of the sub-sub domain box in the space
......
......@@ -262,45 +262,6 @@ class ParMetisDistribution
// Update graphs with the received data
updateGraphs();
/////////////////////////////////////////
// Get result partition for this processor
/* idx_t * partition = parmetis_graph.getPartition();
//! Prepare vector of arrays to contain all partitions
partitions.get(p_id).resize(nl_vertex.id);
std::copy(partition, partition + nl_vertex.id, &partitions.get(p_id).get(0));
// Reset data structure to keep trace of new vertices distribution in processors (needed to update main graph)
for (size_t i = 0; i < Np; ++i)
{
v_per_proc.get(i).clear();
}
openfpm::vector<size_t> prc;
openfpm::vector<size_t> sz;
openfpm::vector<void *> ptr;
for (size_t i = 0; i < Np; i++)
{
if (i != v_cl.getProcessUnitID())
{
partitions.get(i).clear();
prc.add(i);
sz.add(nl_vertex.id * sizeof(idx_t));
ptr.add(partitions.get(p_id).getPointer());
}
}
// Exchange informations through processors
v_cl.sendrecvMultipleMessagesNBX(prc.size(), &sz.get(0), &prc.get(0), &ptr.get(0), message_receive, &partitions,
NONE);
// Update graphs with the new distributions
updateGraphs();*/
}
......@@ -408,7 +369,7 @@ public:
parmetis_graph.reset(gp, vtxdist, m2g, verticesGotWeights);
//! Decompose
parmetis_graph.decompose<nm_v::proc_id>(vtxdist);
parmetis_graph.decompose(vtxdist);
// update after decomposition
postDecomposition();
......@@ -428,7 +389,24 @@ public:
parmetis_graph.reset(gp, vtxdist, m2g, verticesGotWeights);
// Refine
parmetis_graph.refine<nm_v::proc_id>(vtxdist);
parmetis_graph.refine(vtxdist);
postDecomposition();
}
/*! \brief Redecompose current decomposition
*
* It makes a redecomposition using Parmetis taking into consideration
* also migration cost
*
*/
void redecompose()
{
// Reset parmetis graph and reconstruct it
parmetis_graph.reset(gp, vtxdist, m2g, verticesGotWeights);
// Refine
parmetis_graph.redecompose(vtxdist);
postDecomposition();
}
......@@ -577,7 +555,7 @@ public:
/*! \brief Returns total number of neighbors of the sub-sub-domain id
*
* \param i id of the sub-sub-domain
* \param id id of the sub-sub-domain
*/
size_t getNSubSubDomainNeighbors(size_t id)
{
......@@ -626,6 +604,16 @@ public:
return *this;
}
/*! \brief Get the decomposition counter
*
* \return the decomposition counter
*
*/
size_t get_ndec()
{
return parmetis_graph.get_ndec();
}
};
#endif /* SRC_DECOMPOSITION_PARMETISDISTRIBUTION_HPP_ */
......@@ -335,7 +335,7 @@ public:
/*! \brief Returns total number of neighbors of the sub-sub-domain id
*
* \param i id of the sub-sub-domain
* \param id id of the sub-sub-domain
*/
size_t getNSubSubDomainNeighbors(size_t id)
{
......
......@@ -96,27 +96,24 @@ struct Parmetis_dist_graph
template<typename Graph>
class DistParmetis
{
// Graph in metis reppresentation
//! Graph in parmetis reppresentation
Parmetis_dist_graph Mg;
// Original graph
// Graph & g;
// Communticator for OpenMPI
//! Communticator for OpenMPI
MPI_Comm comm = (MPI_Comm)NULL;
// VCluster
//! VCluster
Vcluster & v_cl;
// Process rank information
//! Process rank information
int p_id = 0;
// nc Number of partition
//! nc Number of partition
size_t nc = 0;
/*! \brief Construct Adjacency list
*
* \param g Reference graph to get informations
* \param sub_g graph in which we construct the adjacency list
*
*/
void constructAdjList(Graph & sub_g)
......@@ -175,9 +172,9 @@ public:
/*! \brief Constructor
*
* Construct a metis graph from Graph_CSR
* Construct a metis graph from a Graph_CSR
*
* \param g Graph we want to convert to decompose
* \param v_cl Vcluster
* \param nc number of partitions
*
*/
......@@ -362,7 +359,7 @@ public:
*
* \tparam i which property store the decomposition
*
*
* \param sub_g graph to decompose
*
*/
template<unsigned int i>
......@@ -389,6 +386,8 @@ public:
*
* \tparam i which property store the refined decomposition
*
* \param sub_g graph to decompose
*
*/
template<unsigned int i>
......@@ -406,6 +405,8 @@ public:
}
/*! \brief Get graph partition vector
*
* \return the partition or the assignment of each sub-sub-domain
*
*/
idx_t * getPartition()
......@@ -414,6 +415,8 @@ public:
}
/*! \brief Reset graph and reconstruct it
*
* \param sub_g graph to decompose
*
*/
void reset(Graph & sub_g)
......
......@@ -95,33 +95,36 @@ struct Parmetis_graph
template<typename Graph>
class Parmetis
{
// Graph in metis reppresentation
//! Graph in metis reppresentation
Parmetis_graph Mg;
// Original graph
// Graph & g;
// Communticator for OpenMPI
//! Communticator for OpenMPI
MPI_Comm comm = (MPI_Comm)NULL;
// VCluster
//! VCluster
Vcluster & v_cl;
// Process rank information
//! Process rank information
int p_id = 0;
// nc Number of partition
//! nc Number of partition
size_t nc = 0;
// first re-mapped id
//! first re-mapped id
rid first;
// last re-mapped id
//! last re-mapped id
rid last;
// number of vertices that the processor has
//! number of vertices that the processor has
size_t nvertex;
//! indicate how many time decompose/refine/re-decompose has been called
size_t n_dec;
/*! \brief Construct Adjacency list
*
* \param g Global graph
......@@ -196,12 +199,12 @@ public:
*
* Construct a metis graph from Graph_CSR
*
* \param g Graph we want to convert to decompose
* \param v_cl Vcluster object
* \param nc number of partitions
*
*/
Parmetis(Vcluster & v_cl, size_t nc)
:v_cl(v_cl), nc(nc)
:v_cl(v_cl), nc(nc),n_dec(0)
{
// TODO Move into VCluster
MPI_Comm_dup(MPI_COMM_WORLD, &comm);
......@@ -315,9 +318,15 @@ public:
/*! \brief Set the Sub-graph
*
* \param g Global graph to set
* \param vtxdist indicate how the vertex of the graph are distrubuted across
* processors.
* \param m2g map the local ids of the vertex into global-ids
* \param w true if vertices have weights
*/
void initSubGraph(Graph & g, const openfpm::vector<rid> & vtxdist, const std::unordered_map<rid, gid> & m2g, bool w)
void initSubGraph(Graph & g,
const openfpm::vector<rid> & vtxdist,
const std::unordered_map<rid, gid> & m2g,
bool w)
{
p_id = v_cl.getProcessUnitID();
......@@ -338,12 +347,13 @@ public:
* \tparam i which property store the decomposition
*
*/
template<unsigned int i>
void decompose(const openfpm::vector<rid> & vtxdist)
{
// Decompose