summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorglisse <glisse@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2015-10-18 20:31:25 +0000
committerglisse <glisse@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2015-10-18 20:31:25 +0000
commit91a2adbaeec76b4ee172123a5a833065f910f5ab (patch)
tree3d3960cb7139bf1b824b4dc296e78c1380a6a1ba
parent5776d22f10e8d117fbee8a4652007f26a3d5145d (diff)
Also use TBB to build Hasse_complex in parallel.
git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/tbb@870 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 6633f9b8261cfb2acfb62d1f4748df73375086bd
-rw-r--r--src/Hasse_complex/include/gudhi/Hasse_complex.h30
-rw-r--r--src/common/include/gudhi/allocator.h55
2 files changed, 75 insertions, 10 deletions
diff --git a/src/Hasse_complex/include/gudhi/Hasse_complex.h b/src/Hasse_complex/include/gudhi/Hasse_complex.h
index 67079687..af9ae5e9 100644
--- a/src/Hasse_complex/include/gudhi/Hasse_complex.h
+++ b/src/Hasse_complex/include/gudhi/Hasse_complex.h
@@ -29,6 +29,12 @@
#include <utility> // for pair
#include <vector>
+#include <gudhi/allocator.h>
+
+#ifdef GUDHI_USE_TBB
+#include <tbb/parallel_for.h>
+#endif
+
namespace Gudhi {
template < class HasseCpx >
@@ -97,20 +103,24 @@ class Hasse_complex {
template < class Complex_ds >
Hasse_complex(Complex_ds & cpx)
- : complex_()
+ : complex_(cpx.num_simplices())
, vertices_()
, threshold_(cpx.filtration())
, num_vertices_()
, dim_max_(cpx.dimension()) {
- complex_.reserve(cpx.num_simplices());
- int idx = 0;
- for (auto cpx_sh : cpx.filtration_simplex_range()) {
- complex_.push_back(Hasse_simp(cpx, cpx_sh));
- if (dimension(idx) == 0) {
+ int size = complex_.size();
+#ifdef GUDHI_USE_TBB
+ tbb::parallel_for(0,size,[&](int idx){new (&complex_[idx]) Hasse_simp(cpx, cpx.simplex(idx));});
+ for (int idx=0; idx<size; ++idx)
+ if (complex_[idx].boundary_.empty())
+ vertices_.push_back(idx);
+#else
+ for (int idx=0; idx<size; ++idx) {
+ new (&complex_[idx]) Hasse_simp(cpx, cpx.simplex(idx));
+ if (complex_[idx].boundary_.empty())
vertices_.push_back(idx);
- }
- ++idx;
}
+#endif
}
Hasse_complex()
@@ -194,7 +204,7 @@ class Hasse_complex {
}
}
- std::vector< Hasse_simp > complex_;
+ std::vector< Hasse_simp, Gudhi::no_init_allocator<Hasse_simp> > complex_;
std::vector<Simplex_handle> vertices_;
Filtration_value threshold_;
size_t num_vertices_;
@@ -218,7 +228,7 @@ std::istream& operator>>(std::istream & is
// read all simplices in the file as a list of vertices
while (read_hasse_simplex(is, boundary, fil)) {
// insert every simplex in the simplex tree
- hcpx.complex_.push_back(Hasse_simplex< Hasse_complex<T1, T2, T3> >(key, fil, boundary));
+ hcpx.complex_.emplace_back(key, fil, boundary);
if (max_dim < hcpx.dimension(key)) {
max_dim = hcpx.dimension(key);
diff --git a/src/common/include/gudhi/allocator.h b/src/common/include/gudhi/allocator.h
new file mode 100644
index 00000000..b825173b
--- /dev/null
+++ b/src/common/include/gudhi/allocator.h
@@ -0,0 +1,55 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Marc Glisse
+ *
+ * Copyright (C) 2015 INRIA Saclay - Ile de France
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GUDHI_ALLOCATOR_H_
+#define GUDHI_ALLOCATOR_H_
+
+#include <memory>
+#include <utility>
+
+namespace Gudhi {
+
+/** \private
+ * An allocator that can be used to build an uninitialized vector.
+ */
+template <class T, class Base = std::allocator<T>>
+struct no_init_allocator : Base {
+ typedef std::allocator_traits<Base> Base_traits;
+ template <class U> struct rebind {
+ typedef no_init_allocator<U, typename Base_traits::template rebind_alloc<U>> other;
+ };
+
+ // Inherit constructors.
+ using Base::Base;
+
+ // Do nothing: that's the whole point!
+ template<class P>
+ void construct(P*)noexcept{}
+
+ template<class P, class...U> void construct(P*p, U&&...u){
+ Base_traits::construct(*(Base*)this, p, std::forward<U>(u)...);
+ }
+};
+
+} // namespace Gudhi
+
+#endif // GUDHI_ALLOCATOR_H_