[MOAB-dev] commit/MOAB: 2 new changesets
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Mon Mar 17 12:42:27 CDT 2014
2 new commits in MOAB:
https://bitbucket.org/fathomteam/moab/commits/fa4d3ff0c3c9/
Changeset: fa4d3ff0c3c9
Branch: None
User: tautges
Date: 2014-03-17 18:41:58
Summary: AdaptiveKDTree, BVHTree: split some of the stats into separate initialization/traversal stats
TreeStats: add some stats on leaf node objects
ElemEvaluator: return MB_INDEX_NOT_FOUND instead of MB_FAILURE on failure to converge reverse evaluation test, allows applications to react differently to this type of failure. Also, add some documentation of function args.
LinearTet: in reverse evaluation function, on failure to converge, return success if intermediate result is outside element; same thing is done in ElemEvaluator form of this funciton.
BVHTree: fix bug in decrement of unsigned possibly-zero variable.
TreeStats: separate output into init/traversal stats; also add leaf object details, and functionality in compute_stats to compute these quantities.
Affected #: 7 files
diff --git a/src/AdaptiveKDTree.cpp b/src/AdaptiveKDTree.cpp
index 8aafdd1..4b104b4 100644
--- a/src/AdaptiveKDTree.cpp
+++ b/src/AdaptiveKDTree.cpp
@@ -798,7 +798,7 @@ namespace moab {
double& t_enter,
double& t_exit ) const
{
- treeTool->treeStats.leafObjectTests++;
+ treeTool->treeStats.traversalLeafObjectTests++;
return GeomUtil::ray_box_intersect( CartVect(box_min()),
CartVect(box_max()),
CartVect(ray_point),
@@ -850,7 +850,7 @@ namespace moab {
// vertices
for (i = elems.begin(); i != elem_begin; ++i) {
- tree_stats().leafObjectTests++;
+ tree_stats().constructLeafObjectTests++;
rval = moab()->get_coords( &*i, 1, coords[0].array() );
if (MB_SUCCESS != rval)
return rval;
@@ -872,7 +872,7 @@ namespace moab {
// non-polyhedron elements
std::vector<EntityHandle> dum_vector;
for (i = elem_begin; i != poly_begin; ++i) {
- tree_stats().leafObjectTests++;
+ tree_stats().constructLeafObjectTests++;
rval = moab()->get_connectivity( *i, conn, count, true, &dum_vector);
if (MB_SUCCESS != rval)
return rval;
@@ -916,7 +916,7 @@ namespace moab {
// polyhedra
for (i = poly_begin; i != set_begin; ++i) {
- tree_stats().leafObjectTests++;
+ tree_stats().constructLeafObjectTests++;
rval = moab()->get_connectivity( *i, conn, count, true );
if (MB_SUCCESS != rval)
return rval;
@@ -950,7 +950,7 @@ namespace moab {
// sets
BoundBox tbox;
for (i = set_begin; i != elems.end(); ++i) {
- tree_stats().leafObjectTests++;
+ tree_stats().constructLeafObjectTests++;
rval = tbox.update(*moab(), *i);
if (MB_SUCCESS != rval)
return rval;
@@ -1354,7 +1354,7 @@ namespace moab {
treeStats.leavesVisited++;
if (myEval && params) {
rval = myEval->find_containing_entity(node, point, iter_tol, inside_tol,
- leaf_out, params->array(), &treeStats.leafObjectTests);
+ leaf_out, params->array(), &treeStats.traversalLeafObjectTests);
if (MB_SUCCESS != rval) return rval;
}
else
@@ -1494,7 +1494,7 @@ namespace moab {
EntityHandle ent;
CartVect params;
rval = myEval->find_containing_entity(node.handle, from_point, iter_tol, inside_tol,
- ent, params.array(), &treeStats.leafObjectTests);
+ ent, params.array(), &treeStats.traversalLeafObjectTests);
if (MB_SUCCESS != rval) return rval;
else if (ent) {
result_list.push_back(ent);
diff --git a/src/BVHTree.cpp b/src/BVHTree.cpp
index e2592fb..2c13871 100644
--- a/src/BVHTree.cpp
+++ b/src/BVHTree.cpp
@@ -151,6 +151,7 @@ namespace moab
const BoundBox &box = i->myBox;
for (unsigned int dim = 0; dim < 3; ++dim){
const unsigned int index = Bucket::bucket_index(splitsPerDir, box, interval, dim);
+ assert(index < buckets[dim].size());
Bucket &bucket = buckets[dim][index];
if (bucket.mySize > 0)
bucket.boundingBox.update(box);
@@ -452,7 +453,7 @@ namespace moab
if (MB_SUCCESS != rval) return rval;
for(Range::iterator i = entities.begin(); i != entities.end(); i++) {
- treeStats.leafObjectTests++;
+ treeStats.traversalLeafObjectTests++;
myEval->set_ent_handle(*i);
myEval->reverse_eval(&point[0], iter_tol, inside_tol, params.array(), &is_inside);
if (is_inside) {
@@ -518,7 +519,7 @@ namespace moab
EntityHandle entity = 0;
treeStats.leavesVisited++;
ErrorCode rval = myEval->find_containing_entity(startSetHandle+i, point, iter_tol, inside_tol,
- entity, params.array(), &treeStats.leafObjectTests);
+ entity, params.array(), &treeStats.traversalLeafObjectTests);
if (entity) return entity;
else if (MB_SUCCESS != rval) return 0;
}
@@ -584,7 +585,7 @@ namespace moab
}
else if (myTree[ind].dim == 3 && myEval && params) {
rval = myEval->find_containing_entity(startSetHandle+ind, point, iter_tol, inside_tol,
- leaf_out, params->array(), &treeStats.leafObjectTests);
+ leaf_out, params->array(), &treeStats.traversalLeafObjectTests);
if (leaf_out || MB_SUCCESS != rval) return rval;
}
else {
@@ -657,7 +658,7 @@ namespace moab
EntityHandle ent;
CartVect params;
rval = myEval->find_containing_entity(startSetHandle+ind, from_point, iter_tol, inside_tol,
- ent, params.array(), &treeStats.leafObjectTests);
+ ent, params.array(), &treeStats.traversalLeafObjectTests);
if (MB_SUCCESS != rval) return rval;
else if (ent) {
result_list.push_back(ent);
diff --git a/src/LocalDiscretization/ElemEvaluator.cpp b/src/LocalDiscretization/ElemEvaluator.cpp
index 209cd11..68ef791 100644
--- a/src/LocalDiscretization/ElemEvaluator.cpp
+++ b/src/LocalDiscretization/ElemEvaluator.cpp
@@ -57,7 +57,7 @@ namespace moab {
if (det < std::numeric_limits<double>::epsilon()) {
*tmp_inside = (*inside_f)(params, ndim, inside_tol);
if (!(*tmp_inside)) return MB_SUCCESS;
- else return MB_FAILURE;
+ else return MB_INDEX_OUT_OF_RANGE;
}
// new params tries to eliminate residual
diff --git a/src/LocalDiscretization/LinearTet.cpp b/src/LocalDiscretization/LinearTet.cpp
index 6d590e7..d8d381e 100644
--- a/src/LocalDiscretization/LinearTet.cpp
+++ b/src/LocalDiscretization/LinearTet.cpp
@@ -126,10 +126,15 @@ namespace moab
int iters=0;
// while |res| larger than tol
+ int dum, *tmp_inside = (inside ? inside : &dum);
while (res % res > error_tol_sqr) {
- if(++iters>25)
- return MB_FAILURE;
-
+ if(++iters>25) {
+ // if we haven't converged but we're outside, that's defined as success
+ *tmp_inside = (*inside_f)(params, ndim, inside_tol);
+ if (!(*tmp_inside)) return MB_SUCCESS;
+ else return MB_INDEX_OUT_OF_RANGE;
+ }
+
// new params tries to eliminate residual
*cvparams -= Ji * res;
diff --git a/src/LocalDiscretization/moab/ElemEvaluator.hpp b/src/LocalDiscretization/moab/ElemEvaluator.hpp
index 6a1efd0..9989dfc 100644
--- a/src/LocalDiscretization/moab/ElemEvaluator.hpp
+++ b/src/LocalDiscretization/moab/ElemEvaluator.hpp
@@ -118,8 +118,8 @@ namespace moab {
public:
/** \brief Constructor
* \param impl MOAB instance
- * \param ent Entity handle to cache on the evaluator
- * \param tag Tag to cache on the evaluator
+ * \param ent Entity handle to cache on the evaluator; if non-zero, calls set_ent_handle, which does some other stuff.
+ * \param tag Tag to cache on the evaluator; if non-zero, calls set_tag_handle, which does some other stuff too.
* \param tagged_ent_dim Dimension of entities to be tagged to cache on the evaluator
*/
ElemEvaluator(Interface *impl, EntityHandle ent = 0, Tag tag = 0, int tagged_ent_dim = -1);
diff --git a/src/moab/BVHTree.hpp b/src/moab/BVHTree.hpp
index 354d3a1..eb0e4e4 100644
--- a/src/moab/BVHTree.hpp
+++ b/src/moab/BVHTree.hpp
@@ -260,6 +260,7 @@ namespace moab {
const int index, const BoundBox &box,
const int depth=0);
+ // builds up vector of HandleData, which caches elements' bounding boxes
ErrorCode construct_element_vec(std::vector<HandleData> &handle_data_vec,
const Range &elements,
BoundBox & bounding_box);
@@ -300,7 +301,8 @@ namespace moab {
std::cout << "index: " << std::ceil(center/length)-1 << std::endl;
#endif
#endif
- return std::ceil(center/length)-1;
+ unsigned int cl = std::ceil(center/length);
+ return (cl > 0 ? cl-1 : 0);
}
inline BVHTree::BVHTree(Interface *impl) :
diff --git a/src/moab/TreeStats.hpp b/src/moab/TreeStats.hpp
index 4ae685b..0bb9478 100644
--- a/src/moab/TreeStats.hpp
+++ b/src/moab/TreeStats.hpp
@@ -43,8 +43,11 @@ namespace moab
//! print the contents of this structure
void print() const ;
- //! output the contents of this structure on a single line
- void output() const ;
+ //! output all the contents of this structure on a single line
+ void output_all_stats(const bool with_endl = true) const ;
+
+ //! output just the traversal stats of this structure on a single line
+ void output_trav_stats(const bool with_endl = true) const ;
// times
double initTime;
@@ -53,13 +56,18 @@ namespace moab
unsigned int maxDepth;
unsigned int numNodes;
unsigned int numLeaves;
+ double avgObjPerLeaf;
+ unsigned int minObjPerLeaf;
+ unsigned int maxObjPerLeaf;
+
// traversal statistics
- unsigned int nodesVisited;
- unsigned int leavesVisited;
- unsigned int numTraversals;
- unsigned int leafObjectTests;
- unsigned int boxElemTests;
+ unsigned int nodesVisited; // number of tree nodes visited since last reset
+ unsigned int leavesVisited; // number of tree leaves visited since last reset
+ unsigned int numTraversals; // number of tree traversals since last reset
+ unsigned int constructLeafObjectTests; // during construction, number of tests of objects (e.g. elements)
+ unsigned int traversalLeafObjectTests; // during traversals, number of tests of objects (e.g. elements)
+ unsigned int boxElemTests; // during construction, number of calls to GeomUtil::box_elem_overlap (KD tree only)
private:
ErrorCode traverse(Interface *impl, EntityHandle node, unsigned int &depth);
@@ -71,7 +79,13 @@ namespace moab
maxDepth = 0;
numNodes = 0;
numLeaves = 0;
- return traverse(impl, root_node, maxDepth);
+ avgObjPerLeaf = 0.0;
+ minObjPerLeaf = 0;
+ maxObjPerLeaf = 0;
+
+ ErrorCode rval = traverse(impl, root_node, maxDepth);
+ avgObjPerLeaf = (avgObjPerLeaf > 0 ? avgObjPerLeaf/(double)numLeaves : 0.0);
+ return rval;
}
inline ErrorCode TreeStats::traverse(Interface *impl, EntityHandle node, unsigned int &depth)
@@ -84,6 +98,11 @@ namespace moab
if (MB_SUCCESS != rval) return rval;
if (children.empty()) {
numLeaves++;
+ rval = impl->get_entities_by_handle(node, children);
+ if (MB_SUCCESS != rval) return rval;
+ avgObjPerLeaf += children.size();
+ minObjPerLeaf = std::min((unsigned int)children.size(), minObjPerLeaf);
+ maxObjPerLeaf = std::max((unsigned int)children.size(), maxObjPerLeaf);
return MB_SUCCESS;
}
else {
@@ -104,6 +123,11 @@ namespace moab
maxDepth = 0;
numNodes = 0;
numLeaves = 0;
+ constructLeafObjectTests = 0;
+ boxElemTests = 0;
+ avgObjPerLeaf = 0.0;
+ minObjPerLeaf = 0.0;
+ maxObjPerLeaf = 0.0;
reset_trav_stats();
}
@@ -113,8 +137,7 @@ namespace moab
nodesVisited = 0;
leavesVisited = 0;
numTraversals = 0;
- leafObjectTests = 0;
- boxElemTests = 0;
+ traversalLeafObjectTests = 0;
}
inline void TreeStats::print() const {
@@ -124,17 +147,32 @@ namespace moab
std::cout << "Num leaves = " << numLeaves << std::endl;
std::cout << "Max depth = " << maxDepth << std::endl << std::endl;
+ std::cout << "Avg objs per leaf = " << avgObjPerLeaf << std::endl;
+ std::cout << "Min objs per leaf = " << minObjPerLeaf << std::endl;
+ std::cout << "Max objs per leaf = " << maxObjPerLeaf << std::endl;
+
+ std::cout << "Construction Leaf Object Tests = " << constructLeafObjectTests << std::endl;
+ std::cout << "Box-Element Tests = " << boxElemTests << std::endl;
+
std::cout << "NodesVisited = " << nodesVisited << std::endl;
std::cout << "LeavesVisited = " << leavesVisited << std::endl;
std::cout << "Num Traversals = " << numTraversals << std::endl;
- std::cout << "Leaf Object Tests = " << leafObjectTests << std::endl;
- std::cout << "Box-Element Tests = " << boxElemTests << std::endl;
+ std::cout << "Traversal Leaf Object Tests = " << traversalLeafObjectTests << std::endl;
+ }
+
+ inline void TreeStats::output_all_stats(const bool with_endl) const
+ {
+ std::cout << initTime << " " << numNodes << " " << numLeaves << " " << maxDepth << " "
+ << avgObjPerLeaf << " " << minObjPerLeaf << " " << maxObjPerLeaf << " "
+ << constructLeafObjectTests << " " << boxElemTests << " "
+ << nodesVisited << " " << leavesVisited << " " << numTraversals << " " << traversalLeafObjectTests << " ";
+ if (with_endl) std::cout << std::endl;
}
- inline void TreeStats::output() const
+ inline void TreeStats::output_trav_stats(const bool with_endl) const
{
- std::cout << initTime << " " << nodesVisited << " " << leavesVisited << " " << numTraversals << " " << leafObjectTests << " " << boxElemTests
- << " # initTime, nodesVisited, leavesVisited, numTraversals, leafObjectTests, boxElemTests" << std::endl;
+ std::cout << nodesVisited << " " << leavesVisited << " " << numTraversals << " " << traversalLeafObjectTests << " ";
+ if (with_endl) std::cout << std::endl;
}
}
https://bitbucket.org/fathomteam/moab/commits/c88d8437a1c2/
Changeset: c88d8437a1c2
Branch: master
User: tautges
Date: 2014-03-17 18:41:58
Summary: Adding a timing class for spatial locator; all times on this object are local, but a function is provided for
accumulating results across procs.
Affected #: 4 files
diff --git a/src/Makefile.am b/src/Makefile.am
index 5772d12..a9adf0d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -193,6 +193,7 @@ nobase_libMOAB_la_include_HEADERS = \
moab/SetIterator.hpp \
moab/Skinner.hpp \
moab/SpatialLocator.hpp \
+ moab/SpatialLocatorTimes.hpp \
moab/SpectralMeshTool.hpp \
moab/Tree.hpp \
moab/TreeStats.hpp \
diff --git a/src/SpatialLocator.cpp b/src/SpatialLocator.cpp
index 702399e..8556a81 100644
--- a/src/SpatialLocator.cpp
+++ b/src/SpatialLocator.cpp
@@ -11,13 +11,14 @@
#include "moab/ParallelComm.hpp"
#endif
-bool debug = true;
+bool debug = false;
namespace moab
{
SpatialLocator::SpatialLocator(Interface *impl, Range &elems, Tree *tree, ElemEvaluator *eval)
- : mbImpl(impl), myElems(elems), myDim(-1), myTree(tree), elemEval(eval), iCreatedTree(false)
+ : mbImpl(impl), myElems(elems), myDim(-1), myTree(tree), elemEval(eval), iCreatedTree(false),
+ timerInitialized(false)
{
create_tree();
@@ -178,14 +179,20 @@ namespace moab
TupleList TLforward_o; //TLforward_outbound
TupleList TLsearch_results_o; //TLsearch_results_outbound
+ // initialize timer
+ myTimer.time_elapsed();
+ timerInitialized = true;
// steps 1-2 - initialize the alternative decomposition box from global box
rval = initialize_intermediate_partition(pc);
+ if (rval != MB_SUCCESS) return rval;
//steps 3-6 - set up TLreg_o, gs_transfer, gather registrations
rval = register_src_with_intermediate_procs(pc, abs_iter_tol, TLreg_o);
if (rval != MB_SUCCESS) return rval;
+ myTimes.slTimes[SpatialLocatorTimes::INTMED_INIT] = myTimer.time_elapsed();
+
// actual parallel point location using intermediate partition
// target_pts: TL(to_proc, tgt_index, x, y, z): tuples sent to source mesh procs representing pts to be located
@@ -219,6 +226,8 @@ namespace moab
if (pc)
pc->proc_config().crystal_router()->gs_transfer(1, TLquery_o, 0);
+ myTimes.slTimes[SpatialLocatorTimes::INTMED_SEND] = myTimer.time_elapsed();
+
//now read forwarding requests and forward to corresponding procs
//TLquery_o is now TLforw_req_i
@@ -244,9 +253,17 @@ namespace moab
}
+ myTimes.slTimes[SpatialLocatorTimes::INTMED_SEARCH] = myTimer.time_elapsed();
+
if (pc)
pc->proc_config().crystal_router()->gs_transfer(1, TLforward_o, 0);
+ myTimes.slTimes[SpatialLocatorTimes::SRC_SEND] = myTimer.time_elapsed();
+
+ // cache time here, because locate_points also calls elapsed functions and we want to account
+ // for tuple list initialization here
+ double tstart = myTimer.time_since_birth();
+
//step 12
//now read Point Search requests
//TLforward_o is now TLsearch_req_i
@@ -285,10 +302,14 @@ namespace moab
}
locTable.disableWriteAccess();
+ myTimes.slTimes[SpatialLocatorTimes::SRC_SEARCH] = myTimer.time_since_birth() - tstart;
+ myTimer.time_elapsed(); // call this to reset last time called
+
//step 14: send TLsearch_results_o and receive TLloc_i
if (pc)
pc->proc_config().crystal_router()->gs_transfer(1, TLsearch_results_o, 0);
+ myTimes.slTimes[SpatialLocatorTimes::TARG_RETURN] = myTimer.time_elapsed();
// store proc/index tuples in parLocTable
parLocTable.initialize(2, 0, 0, 0, num_points);
@@ -308,6 +329,8 @@ namespace moab
<< " (" << 100.0*((double)num_found/num_points) << "%)" << std::endl;
}
+ myTimes.slTimes[SpatialLocatorTimes::TARG_STORE] = myTimer.time_elapsed();
+
return MB_SUCCESS;
}
@@ -317,6 +340,13 @@ namespace moab
const double rel_iter_tol, const double abs_iter_tol,
const double inside_tol)
{
+ bool i_initialized = false;
+ if (!timerInitialized) {
+ myTimer.time_elapsed();
+ timerInitialized = true;
+ i_initialized = true;
+ }
+
assert(!verts.empty() && mbImpl->type_from_handle(*verts.rbegin()) == MBVERTEX);
std::vector<double> pos(3*verts.size());
ErrorCode rval = mbImpl->get_coords(verts, &pos[0]);
@@ -324,6 +354,10 @@ namespace moab
rval = locate_points(&pos[0], verts.size(), rel_iter_tol, abs_iter_tol, inside_tol);
if (MB_SUCCESS != rval) return rval;
+ // only call this if I'm the top-level function, since it resets the last time called
+ if (i_initialized)
+ myTimes.slTimes[SpatialLocatorTimes::SRC_SEARCH] = myTimer.time_elapsed();
+
return MB_SUCCESS;
}
@@ -331,6 +365,12 @@ namespace moab
const double rel_iter_tol, const double abs_iter_tol,
const double inside_tol)
{
+ bool i_initialized = false;
+ if (!timerInitialized) {
+ myTimer.time_elapsed();
+ timerInitialized = true;
+ i_initialized = true;
+ }
// initialize to tuple structure (p_ui, hs_ul, r[3]_d) (see header comments for locTable)
locTable.initialize(1, 0, 1, 3, num_points);
locTable.enableWriteAccess();
@@ -341,7 +381,12 @@ namespace moab
std::fill(locTable.vi_wr, locTable.vi_wr+num_points, 0);
locTable.set_n(num_points);
if (MB_SUCCESS != rval) return rval;
+
+ // only call this if I'm the top-level function, since it resets the last time called
+ if (i_initialized)
+ myTimes.slTimes[SpatialLocatorTimes::SRC_SEARCH] = myTimer.time_elapsed();
+
return MB_SUCCESS;
}
@@ -350,11 +395,24 @@ namespace moab
const double rel_iter_tol, const double abs_iter_tol,
const double inside_tol)
{
+ bool i_initialized = false;
+ if (!timerInitialized) {
+ myTimer.time_elapsed();
+ timerInitialized = true;
+ i_initialized = true;
+ }
+
assert(!verts.empty() && mbImpl->type_from_handle(*verts.rbegin()) == MBVERTEX);
std::vector<double> pos(3*verts.size());
ErrorCode rval = mbImpl->get_coords(verts, &pos[0]);
if (MB_SUCCESS != rval) return rval;
- return locate_points(&pos[0], verts.size(), ents, params, is_inside, rel_iter_tol, abs_iter_tol, inside_tol);
+ rval = locate_points(&pos[0], verts.size(), ents, params, is_inside, rel_iter_tol, abs_iter_tol, inside_tol);
+
+ // only call this if I'm the top-level function, since it resets the last time called
+ if (i_initialized)
+ myTimes.slTimes[SpatialLocatorTimes::SRC_SEARCH] = myTimer.time_elapsed();
+
+ return rval;
}
ErrorCode SpatialLocator::locate_points(const double *pos, int num_points,
@@ -362,6 +420,13 @@ namespace moab
const double rel_iter_tol, const double abs_iter_tol,
const double inside_tol)
{
+ bool i_initialized = false;
+ if (!timerInitialized) {
+ myTimer.time_elapsed();
+ timerInitialized = true;
+ i_initialized = true;
+ }
+
double tmp_abs_iter_tol = abs_iter_tol;
if (rel_iter_tol && !tmp_abs_iter_tol) {
// relative epsilon given, translate to absolute epsilon using box dimensions
@@ -389,6 +454,10 @@ namespace moab
if (is_inside) is_inside[i] = (ents[i] ? true : false);
}
+ // only call this if I'm the top-level function, since it resets the last time called
+ if (i_initialized)
+ myTimes.slTimes[SpatialLocatorTimes::SRC_SEARCH] = myTimer.time_elapsed();
+
return rval;
}
diff --git a/src/moab/SpatialLocator.hpp b/src/moab/SpatialLocator.hpp
index 2690058..95e6feb 100644
--- a/src/moab/SpatialLocator.hpp
+++ b/src/moab/SpatialLocator.hpp
@@ -35,6 +35,8 @@
#include "moab/Range.hpp"
#include "moab/TupleList.hpp"
#include "moab/BoundBox.hpp"
+#include "moab/SpatialLocatorTimes.hpp"
+#include "moab/CpuTimer.hpp"
#include <string>
#include <vector>
@@ -166,7 +168,13 @@ namespace moab {
/* set elemEval */
void elem_eval(ElemEvaluator *eval) {elemEval = eval; if (myTree) myTree->set_eval(eval);}
+
+ /** \brief Get spatial locator times object */
+ SpatialLocatorTimes &sl_times() {return myTimes;}
+ /** \brief Get spatial locator times object */
+ const SpatialLocatorTimes &sl_times() const {return myTimes;}
+
private:
#ifdef USE_MPI
@@ -262,6 +270,17 @@ namespace moab {
*/
std::map<int, BoundBox> srcProcBoxes;
+ /* \brief Timing object for spatial location
+ */
+ SpatialLocatorTimes myTimes;
+
+ /* \brief Timer object to manage overloaded search functions
+ */
+ CpuTimer myTimer;
+
+ /* \brief Flag to manage initialization of timer for overloaded search functions
+ */
+ bool timerInitialized;
};
inline SpatialLocator::~SpatialLocator()
diff --git a/src/moab/SpatialLocatorTimes.hpp b/src/moab/SpatialLocatorTimes.hpp
new file mode 100644
index 0000000..e0b210d
--- /dev/null
+++ b/src/moab/SpatialLocatorTimes.hpp
@@ -0,0 +1,138 @@
+/**\file SpatialLocatorTimes.hpp
+ * \class moab::SpatialLocatorTimes
+ * \brief Statistics for spatial location
+ *
+ * Class to accumulate statistics on performance of spatial location. This structure stores
+ * only local (single proc) statistics, but provides functions for accumulating max/min/avg
+ * time properties for performance reporting.
+ *
+ * Similar to TreeStats, this class is very lightweight, with most variables publicly accessible.
+ *
+ */
+
+#ifndef SPATIALLOCATORTIMES_HPP
+#define SPATIALLOCATORTIMES_HPP
+
+#include "moab/Interface.hpp"
+
+#include <iostream>
+
+#ifdef USE_MPI
+#include "moab_mpi.h"
+#endif
+
+namespace moab
+{
+class SpatialLocatorTimes
+{
+public:
+ /* constructor
+ */
+ SpatialLocatorTimes() {reset();}
+
+ /* \brief Reset all stats defined here
+ */
+ void reset();
+
+ /* \brief Output header for stats names
+ */
+ void output_header(bool print_endl = false) const;
+
+ /* \brief Output stats all on one line
+ */
+ void output(bool print_head = false, bool print_endl = false) const;
+
+#ifdef USE_MPI
+ /* \brief Accumulate times over all processors into provided array
+ * Max and min is accumulated over all processors, onto root, for each stat. If avg_stats is non-NULL,
+ * all stats are gathered to root so average can be taken too.
+ *
+ * This function must be called collectively on the communicator
+ * \param comm MPI communictor over which this accumulation is done
+ * \param max_times Array of size NUM_STATS into which max times are inserted
+ * \param min_times Array of size NUM_STATS into which min times are inserted
+ * \param avg_times Array of size NUM_STATS into which avg times are inserted; if NULL, no avg times are computed.
+
+ */
+ ErrorCode accumulate_times(MPI_Comm comm, double *max_times, double *min_times,
+ double *avg_times = NULL);
+#endif
+
+ /* \brief Enumeration to identify fields in performance data
+ */
+ enum {INTMED_INIT = 0, // time to compute intermediate partition, incl global bounding box
+ INTMED_SEND, // time to send search points from target to intermediate parts
+ INTMED_SEARCH, // time to find candidate src boxes for search points on intermidiate procs
+ SRC_SEND, // time to send search points to src procs
+ SRC_SEARCH, // time to search local box/elements on src procs
+ TARG_RETURN, // time to return point location data to target procs
+ TARG_STORE, // time to store point location into local SpatialLocator object
+ NUM_STATS // number of stats, useful for array sizing and terminating loops over stats
+ };
+
+ double slTimes[NUM_STATS];
+};
+
+inline void SpatialLocatorTimes::reset()
+{
+ for (int i = 0; i < NUM_STATS; i++) slTimes[i] = 0.0;
+}
+
+#ifdef USE_MPI
+inline ErrorCode SpatialLocatorTimes::accumulate_times(MPI_Comm comm,
+ double *min_times, double *max_times, double *avg_times)
+{
+ ErrorCode rval = MB_SUCCESS;
+ int success = MPI_Reduce(slTimes, min_times, NUM_STATS, MPI_DOUBLE, MPI_MIN, 0, comm);
+ if (!success) rval = MB_FAILURE;
+
+ success = MPI_Reduce(slTimes, max_times, NUM_STATS, MPI_DOUBLE, MPI_MAX, 0, comm);
+ if (!success) rval = MB_FAILURE;
+
+ if (avg_times) {
+ int sz, rank;
+ MPI_Comm_size(comm, &sz);
+ MPI_Comm_rank(comm, &rank);
+ std::vector<double> all_times;
+ if (!rank) all_times.resize(NUM_STATS*sz+NUM_STATS);
+ success = MPI_Gather(slTimes, NUM_STATS, MPI_DOUBLE, (rank ? NULL : &all_times[0]), NUM_STATS, MPI_DOUBLE, 0, comm);
+ if (!success) rval = MB_FAILURE;
+ if (!rank) {
+ std::fill(avg_times, avg_times+NUM_STATS, 0.0);
+ for (int p = 0; p < sz; p++) {
+ for (int s = 0; s < NUM_STATS; s++)
+ avg_times[s] += all_times[p*NUM_STATS+s];
+ }
+
+ for (int s = 0; s <= NUM_STATS; s++) avg_times[s] /= (double)sz;
+ }
+ }
+
+ return rval;
+}
+#endif
+
+ /* \brief Output stats all on one line
+ */
+inline void SpatialLocatorTimes::output_header(bool print_endl) const
+{
+ std::cout << "Intmed_init Intmed_send Intmed_search src_send src_search targ_return targ_store";
+ if (print_endl) std::cout << std::endl;
+}
+
+ /* \brief Output stats all on one line
+ */
+inline void SpatialLocatorTimes::output(bool print_head, bool print_endl) const
+{
+ if (print_head) output_header(true);
+ for (int i = 0; i < NUM_STATS; i++) std::cout << slTimes[i] << " ";
+
+ if (print_endl) std::cout << std::endl;
+}
+
+
+} // namespace moab
+
+#endif
+
+
Repository URL: https://bitbucket.org/fathomteam/moab/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
More information about the moab-dev
mailing list