From a96a1e46249f3b2eeab723feeeb0b94e34df7bc1 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Sun, 30 May 2021 18:32:42 +0200 Subject: [PATCH 1/9] separate memtracer.hpp --- libsrc/core/CMakeLists.txt | 2 +- libsrc/core/array.hpp | 2 +- libsrc/core/memtracer.hpp | 174 ++++++++++++++++++++++++++++++++++++ libsrc/core/profiler.hpp | 157 +------------------------------- libsrc/core/table.hpp | 67 +++++++++++++- libsrc/core/taskmanager.hpp | 64 +------------ 6 files changed, 245 insertions(+), 221 deletions(-) create mode 100644 libsrc/core/memtracer.hpp diff --git a/libsrc/core/CMakeLists.txt b/libsrc/core/CMakeLists.txt index 3d6a438d..e0208867 100644 --- a/libsrc/core/CMakeLists.txt +++ b/libsrc/core/CMakeLists.txt @@ -69,7 +69,7 @@ install(TARGETS ngcore DESTINATION ${NG_INSTALL_DIR} COMPONENT netgen) target_link_libraries(ngcore PUBLIC netgen_mpi PRIVATE "$" ${CMAKE_THREAD_LIBS_INIT}) -install(FILES ngcore.hpp archive.hpp type_traits.hpp version.hpp ngcore_api.hpp logging.hpp +install(FILES ngcore.hpp archive.hpp type_traits.hpp version.hpp ngcore_api.hpp logging.hpp memtracer.hpp exception.hpp symboltable.hpp paje_trace.hpp utils.hpp profiler.hpp mpi_wrapper.hpp array.hpp taskmanager.hpp concurrentqueue.h localheap.hpp python_ngcore.hpp flags.hpp xbool.hpp signal.hpp bitarray.hpp table.hpp hashtable.hpp ranges.hpp diff --git a/libsrc/core/array.hpp b/libsrc/core/array.hpp index 4f1e8324..20139061 100644 --- a/libsrc/core/array.hpp +++ b/libsrc/core/array.hpp @@ -11,7 +11,7 @@ #include "archive.hpp" #include "exception.hpp" #include "localheap.hpp" -#include "profiler.hpp" +#include "memtracer.hpp" #include "utils.hpp" namespace ngcore diff --git a/libsrc/core/memtracer.hpp b/libsrc/core/memtracer.hpp new file mode 100644 index 00000000..0a0d0cb3 --- /dev/null +++ b/libsrc/core/memtracer.hpp @@ -0,0 +1,174 @@ +#ifndef NETGEN_CORE_MEMTRACER_HPP +#define NETGEN_CORE_MEMTRACER_HPP + +#include +#include +#include +#include + +#include "array.hpp" +#include "logging.hpp" +#include "paje_trace.hpp" +#include "utils.hpp" + +namespace ngcore +{ + + class MemoryTracer; + + namespace detail + { + //Type trait to check if a class implements a 'void SetMemoryTacing(int)' function + template + struct has_StartMemoryTracing + { + private: + template + static constexpr auto check(T2*) -> + typename std::is_same().StartMemoryTracing()),void>::type; + template + static constexpr std::false_type check(...); + using type = decltype(check(nullptr)); // NOLINT + public: + static constexpr bool value = type::value; + }; + } // namespace detail + + class MemoryTracer + { + #ifdef NETGEN_TRACE_MEMORY + NGCORE_API static std::vector names; + NGCORE_API static std::vector parents; + + static int CreateId(const std::string& name) + { + int id = names.size(); + names.push_back(name); + parents.push_back(0); + if(id==10*8*1024) + std::cerr << "Allocated " << id << " MemoryTracer objects" << std::endl; + return id; + } + int id; + + public: + + MemoryTracer( std::string name ) + { + id = CreateId(name); + } + + // not tracing + MemoryTracer() : id(0) {} + + template + MemoryTracer( std::string name, TRest & ... rest ) + { + id = CreateId(name); + Track(rest...); + } + + NETGEN_INLINE void Alloc(size_t size) const + { + if(id && trace) + trace->AllocMemory(id, size); + } + + void Free(size_t size) const + { + if(id && trace) + trace->FreeMemory(id, size); + } + + void Swap(size_t mysize, MemoryTracer& other, size_t other_size) const + { + if(!trace || (id == 0 && other.id == 0)) + return; + if(id == 0) + return trace->ChangeMemory(other.id, mysize - other_size); + if(other.id == 0) + return trace->ChangeMemory(id, other_size - mysize); + + // first decrease memory, otherwise have artificial/wrong high peak memory usage + if(mysizeChangeMemory(other.id, mysize-other_size); + trace->ChangeMemory(id, other_size-mysize); + } + else + { + trace->ChangeMemory(id, other_size-mysize); + trace->ChangeMemory(other.id, mysize-other_size); + } + } + + int GetId() const { return id; } + + template + void Track( T1 & obj, const std::string& name, TRest & ... rest ) const + { + Track(obj, name); + Track(rest...); + } + + template + void Track( T & obj, const std::string& name ) const + { + obj.GetMemoryTracer().Activate(obj, name); + parents[obj.GetMemoryTracer().GetId()] = id; + } + + static std::string GetName(int id) + { + return names[id]; + } + + std::string GetName() const + { + return names[id]; + } + + template + void Activate(T& me, const std::string& name) const + { + if(!id) + { + const_cast(this)->id = CreateId(name); + if constexpr(detail::has_StartMemoryTracing::value) + me.StartMemoryTracing(); + } + else + SetName(name); + } + + void SetName(const std::string& name) const + { + names[id] = name; + } + + + static const std::vector & GetNames() { return names; } + static const std::vector & GetParents() { return parents; } +#else // NETGEN_TRACE_MEMORY + public: + MemoryTracer() {} + MemoryTracer( std::string /* name */ ) {} + template + MemoryTracer( std::string /* name */, TRest & ... ) {} + + void Alloc(size_t /* size */) const {} + void Free(size_t /* size */) const {} + void Swap(...) const {} + int GetId() const { return 0; } + + template + void Track(TRest&...) const {} + + static std::string GetName(int /* id */) { return ""; } + std::string GetName() const { return ""; } + void SetName(std::string /* name */) const {} +#endif // NETGEN_TRACE_MEMORY + }; +} // namespace ngcore + +#endif // NETGEN_CORE_MEMTRACER_HPP diff --git a/libsrc/core/profiler.hpp b/libsrc/core/profiler.hpp index d49b6543..294928d3 100644 --- a/libsrc/core/profiler.hpp +++ b/libsrc/core/profiler.hpp @@ -6,8 +6,10 @@ #include #include +#include "array.hpp" #include "logging.hpp" #include "paje_trace.hpp" +#include "taskmanager.hpp" #include "utils.hpp" namespace ngcore @@ -300,161 +302,6 @@ namespace ngcore return tres; } - class MemoryTracer; - - namespace detail - { - //Type trait to check if a class implements a 'void SetMemoryTacing(int)' function - template - struct has_StartMemoryTracing - { - private: - template - static constexpr auto check(T2*) -> - typename std::is_same().StartMemoryTracing()),void>::type; - template - static constexpr std::false_type check(...); - using type = decltype(check(nullptr)); // NOLINT - public: - static constexpr bool value = type::value; - }; - } // namespace detail - - class MemoryTracer - { - #ifdef NETGEN_TRACE_MEMORY - NGCORE_API static std::vector names; - NGCORE_API static std::vector parents; - - static int CreateId(const std::string& name) - { - int id = names.size(); - names.push_back(name); - parents.push_back(0); - if(id==10*NgProfiler::SIZE) - std::cerr << "Allocated " << id << " MemoryTracer objects" << std::endl; - return id; - } - int id; - - public: - - MemoryTracer( std::string name ) - { - id = CreateId(name); - } - - // not tracing - MemoryTracer() : id(0) {} - - template - MemoryTracer( std::string name, TRest & ... rest ) - { - id = CreateId(name); - Track(rest...); - } - - NETGEN_INLINE void Alloc(size_t size) const - { - if(id && trace) - trace->AllocMemory(id, size); - } - - void Free(size_t size) const - { - if(id && trace) - trace->FreeMemory(id, size); - } - - void Swap(size_t mysize, MemoryTracer& other, size_t other_size) const - { - if(!trace || (id == 0 && other.id == 0)) - return; - if(id == 0) - return trace->ChangeMemory(other.id, mysize - other_size); - if(other.id == 0) - return trace->ChangeMemory(id, other_size - mysize); - - // first decrease memory, otherwise have artificial/wrong high peak memory usage - if(mysizeChangeMemory(other.id, mysize-other_size); - trace->ChangeMemory(id, other_size-mysize); - } - else - { - trace->ChangeMemory(id, other_size-mysize); - trace->ChangeMemory(other.id, mysize-other_size); - } - } - - int GetId() const { return id; } - - template - void Track( T1 & obj, const std::string& name, TRest & ... rest ) const - { - Track(obj, name); - Track(rest...); - } - - template - void Track( T & obj, const std::string& name ) const - { - obj.GetMemoryTracer().Activate(obj, name); - parents[obj.GetMemoryTracer().GetId()] = id; - } - - static std::string GetName(int id) - { - return names[id]; - } - - std::string GetName() const - { - return names[id]; - } - - template - void Activate(T& me, const std::string& name) const - { - if(!id) - { - const_cast(this)->id = CreateId(name); - if constexpr(detail::has_StartMemoryTracing::value) - me.StartMemoryTracing(); - } - else - SetName(name); - } - - void SetName(const std::string& name) const - { - names[id] = name; - } - - - static const std::vector & GetNames() { return names; } - static const std::vector & GetParents() { return parents; } -#else // NETGEN_TRACE_MEMORY - public: - MemoryTracer() {} - MemoryTracer( std::string /* name */ ) {} - template - MemoryTracer( std::string /* name */, TRest & ... ) {} - - void Alloc(size_t /* size */) const {} - void Free(size_t /* size */) const {} - void Swap(...) const {} - int GetId() const { return 0; } - - template - void Track(TRest&...) const {} - - static std::string GetName(int /* id */) { return ""; } - std::string GetName() const { return ""; } - void SetName(std::string /* name */) const {} -#endif // NETGEN_TRACE_MEMORY - }; } // namespace ngcore // Helper macro to easily add multiple timers in a function for profiling diff --git a/libsrc/core/table.hpp b/libsrc/core/table.hpp index 6a851605..8dbde01c 100644 --- a/libsrc/core/table.hpp +++ b/libsrc/core/table.hpp @@ -13,8 +13,10 @@ #include "array.hpp" #include "bitarray.hpp" -#include "taskmanager.hpp" +#include "memtracer.hpp" #include "ngcore_api.hpp" +#include "profiler.hpp" +#include "taskmanager.hpp" namespace ngcore { @@ -672,6 +674,69 @@ namespace ngcore return s; } + + // Helper function to calculate coloring of a set of indices for parallel processing of independent elements/points/etc. + // Assigns a color to each of colors.Size() elements, such that two elements with the same color don't share a common 'dof', + // the mapping from element to dofs is provided by the function getDofs(int) -> iterable + // + // Returns the number of used colors + template + int ComputeColoring( FlatArray colors, size_t ndofs, Tmask const & getDofs) + { + static Timer timer("ComputeColoring - "+Demangle(typeid(Tmask).name())); RegionTimer rt(timer); + static_assert(sizeof(unsigned int)==4, "Adapt type of mask array"); + size_t n = colors.Size(); + + Array mask(ndofs); + + size_t colored_blocks = 0; + + // We are coloring with 32 colors at once and use each bit to mask conflicts + unsigned int check = 0; + unsigned int checkbit = 0; + + int current_color = 0; + colors = -1; + int maxcolor = 0; + + while(colored_blocks-1) continue; + check = 0; + const auto & dofs = getDofs(i); + + // Check if adjacent dofs are already marked by current color + for (auto dof : dofs) + check|=mask[dof]; + + // Did we find a free color? + if(check != 0xFFFFFFFF) + { + checkbit = 1; + int color = current_color; + // find the actual color, which is free (out of 32) + while (check & checkbit) + { + color++; + checkbit *= 2; + } + colors[i] = color; + maxcolor = color > maxcolor ? color : maxcolor; + colored_blocks++; + // mask all adjacent dofs with the found color + for (auto dof : dofs) + mask[dof] |= checkbit; + } + } + current_color+=32; + } + return maxcolor+1; + } + + typedef DynamicTable IntTable; } // namespace ngcore diff --git a/libsrc/core/taskmanager.hpp b/libsrc/core/taskmanager.hpp index 7025ce3d..27de9090 100644 --- a/libsrc/core/taskmanager.hpp +++ b/libsrc/core/taskmanager.hpp @@ -15,7 +15,7 @@ #include "array.hpp" #include "paje_trace.hpp" -#include "profiler.hpp" +#include "taskmanager.hpp" #ifdef USE_NUMA #include @@ -1058,68 +1058,6 @@ public: #endif // USE_NUMA - // Helper function to calculate coloring of a set of indices for parallel processing of independent elements/points/etc. - // Assigns a color to each of colors.Size() elements, such that two elements with the same color don't share a common 'dof', - // the mapping from element to dofs is provided by the function getDofs(int) -> iterable - // - // Returns the number of used colors - template - int ComputeColoring( FlatArray colors, size_t ndofs, Tmask const & getDofs) - { - static Timer timer("ComputeColoring - "+Demangle(typeid(Tmask).name())); RegionTimer rt(timer); - static_assert(sizeof(unsigned int)==4, "Adapt type of mask array"); - size_t n = colors.Size(); - - Array mask(ndofs); - - size_t colored_blocks = 0; - - // We are coloring with 32 colors at once and use each bit to mask conflicts - unsigned int check = 0; - unsigned int checkbit = 0; - - int current_color = 0; - colors = -1; - int maxcolor = 0; - - while(colored_blocks-1) continue; - check = 0; - const auto & dofs = getDofs(i); - - // Check if adjacent dofs are already marked by current color - for (auto dof : dofs) - check|=mask[dof]; - - // Did we find a free color? - if(check != 0xFFFFFFFF) - { - checkbit = 1; - int color = current_color; - // find the actual color, which is free (out of 32) - while (check & checkbit) - { - color++; - checkbit *= 2; - } - colors[i] = color; - maxcolor = color > maxcolor ? color : maxcolor; - colored_blocks++; - // mask all adjacent dofs with the found color - for (auto dof : dofs) - mask[dof] |= checkbit; - } - } - current_color+=32; - } - return maxcolor+1; - } - - } From eee7a6d211cef5380d4c1f330906269ec770510a Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Tue, 8 Jun 2021 11:54:31 +0200 Subject: [PATCH 2/9] initialize childs in GradingBox also in default ctor --- libsrc/meshing/localh.cpp | 4 ---- libsrc/meshing/localh.hpp | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/libsrc/meshing/localh.cpp b/libsrc/meshing/localh.cpp index 3afe8e25..27700630 100644 --- a/libsrc/meshing/localh.cpp +++ b/libsrc/meshing/localh.cpp @@ -11,10 +11,6 @@ namespace netgen for (int i = 0; i < 3; i++) xmid[i] = 0.5 * (ax1[i] + ax2[i]); - for (int i = 0; i < 8; i++) - childs[i] = NULL; - father = NULL; - flags.cutboundary = 0; flags.isinner = 0; flags.oldcell = 0; diff --git a/libsrc/meshing/localh.hpp b/libsrc/meshing/localh.hpp index caff6540..7d2ec433 100644 --- a/libsrc/meshing/localh.hpp +++ b/libsrc/meshing/localh.hpp @@ -20,9 +20,9 @@ namespace netgen /// half edgelength float h2; /// - GradingBox * childs[8]; + GradingBox * childs[8] = {nullptr}; /// - GradingBox * father; + GradingBox * father = nullptr; /// double hopt; /// From 873de8149c33a4f66334ad3a5cba889c6d5767f6 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Thu, 10 Jun 2021 09:42:04 +0200 Subject: [PATCH 3/9] thread-safe delaunay --- libsrc/meshing/delaunay.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libsrc/meshing/delaunay.cpp b/libsrc/meshing/delaunay.cpp index 8bee0775..0bf229f9 100644 --- a/libsrc/meshing/delaunay.cpp +++ b/libsrc/meshing/delaunay.cpp @@ -233,7 +233,7 @@ namespace netgen NgArray > & centers, NgArray & radi2, NgArray & connected, NgArray & treesearch, NgArray & freelist, SphereList & list, - IndexSet & insphere, IndexSet & closesphere) + IndexSet & insphere, IndexSet & closesphere, Array & newels) { static Timer t("Meshing3::AddDelaunayPoint");// RegionTimer reg(t); // static Timer tsearch("addpoint, search"); @@ -399,8 +399,6 @@ namespace netgen } } // while (changed) - // NgArray newels; - static NgArray newels; newels.SetSize(0); Element2d face(TRIG); @@ -684,6 +682,7 @@ namespace netgen for (PointIndex pi : mesh.Points().Range().Modify(0, -4)) mixed[pi] = PointIndex ( (prim * pi) % np + PointIndex::BASE ); + Array newels; // for (PointIndex pi = mesh.Points().Begin(); pi < mesh.Points().End()-4; pi++) for (PointIndex pi : mesh.Points().Range().Modify(0, -4)) { @@ -710,7 +709,7 @@ namespace netgen AddDelaunayPoint (newpi, newp, tempels, mesh, tettree, meshnb, centers, radi2, - connected, treesearch, freelist, list, insphere, closesphere); + connected, treesearch, freelist, list, insphere, closesphere, newels); } From c734a276218340223c94e6d3361b2092f03098f6 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Mon, 7 Jun 2021 11:38:01 +0200 Subject: [PATCH 4/9] TABLE -> Table in PointFunction --- libsrc/meshing/smoothing3.cpp | 59 ++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/libsrc/meshing/smoothing3.cpp b/libsrc/meshing/smoothing3.cpp index 0f8652f6..60773d9d 100644 --- a/libsrc/meshing/smoothing3.cpp +++ b/libsrc/meshing/smoothing3.cpp @@ -304,7 +304,7 @@ namespace netgen public: Mesh::T_POINTS & points; const Array & elements; - TABLE &elementsonpoint; + Table &elementsonpoint; bool own_elementsonpoint; const MeshingParameters & mp; PointIndex actpind; @@ -319,7 +319,7 @@ namespace netgen virtual void SetPointIndex (PointIndex aactpind); void SetLocalH (double ah) { h = ah; } double GetLocalH () const { return h; } - const TABLE & GetPointToElementTable() { return elementsonpoint; }; + const Table & GetPointToElementTable() { return elementsonpoint; }; virtual double PointFunctionValue (const Point<3> & pp) const; virtual double PointFunctionValueGrad (const Point<3> & pp, Vec<3> & grad) const; virtual double PointFunctionValueDeriv (const Point<3> & pp, const Vec<3> & dir, double & deriv) const; @@ -335,13 +335,20 @@ namespace netgen PointFunction :: PointFunction (Mesh::T_POINTS & apoints, const Array & aelements, const MeshingParameters & amp) - : points(apoints), elements(aelements), elementsonpoint(* new TABLE(apoints.Size())), own_elementsonpoint(true), mp(amp) + : points(apoints), elements(aelements), elementsonpoint(* new Table()), own_elementsonpoint(true), mp(amp) { static Timer tim("PointFunction - build elementsonpoint table"); RegionTimer reg(tim); - for (int i = 0; i < elements.Size(); i++) - if (elements[i].NP() == 4) - for (int j = 0; j < elements[i].NP(); j++) - elementsonpoint.Add (elements[i][j], i); + elementsonpoint = std::move(ngcore::CreateSortedTable( elements.Range(), + [&](auto & table, ElementIndex ei) + { + const auto & el = elements[ei]; + + if(el.NP()!=4) + return; + + for (PointIndex pi : el.PNums()) + table.Add (pi, ei); + }, points.Size())); } void PointFunction :: SetPointIndex (PointIndex aactpind) @@ -359,9 +366,9 @@ namespace netgen hp = points[actpind]; points[actpind] = Point<3> (pp); - for (int j = 0; j < elementsonpoint[actpind].Size(); j++) + for (auto ei : elementsonpoint[actpind]) { - const Element & el = elements[elementsonpoint[actpind][j]]; + const Element & el = elements[ei]; badness += CalcTetBadness (points[el[0]], points[el[1]], points[el[2]], points[el[3]], -1, mp); } @@ -379,9 +386,9 @@ namespace netgen Vec<3> vgradi, vgrad(0,0,0); points[actpind] = Point<3> (pp); - for (int j = 0; j < elementsonpoint[actpind].Size(); j++) + for (auto ei : elementsonpoint[actpind]) { - const Element & el = elements[elementsonpoint[actpind][j]]; + const Element & el = elements[ei]; for (int k = 0; k < 4; k++) if (el[k] == actpind) { @@ -409,9 +416,9 @@ namespace netgen points[actpind] = pp; double f = 0; - for (int j = 0; j < elementsonpoint[actpind].Size(); j++) + for (auto ei : elementsonpoint[actpind]) { - const Element & el = elements[elementsonpoint[actpind][j]]; + const Element & el = elements[ei]; for (int k = 1; k <= 4; k++) if (el.PNum(k) == actpind) @@ -435,10 +442,9 @@ namespace netgen // try point movement NgArray faces; - for (int j = 0; j < elementsonpoint[actpind].Size(); j++) + for (auto ei : elementsonpoint[actpind]) { - const Element & el = - elements[elementsonpoint[actpind][j]]; + const Element & el = elements[ei]; for (int k = 1; k <= 4; k++) if (el.PNum(k) == actpind) @@ -1013,11 +1019,8 @@ double JacobianPointFunction :: Func (const Vector & v) const points[actpind] -= (v(0)*nv(0)+v(1)*nv(1)+v(2)*nv(2)) * nv; - for (j = 1; j <= elementsonpoint.EntrySize(actpind); j++) - { - int eli = elementsonpoint.Get(actpind, j); - badness += elements[eli-1].CalcJacobianBadness (points); - } + for (auto eli : elementsonpoint[actpind]) + badness += elements[eli].CalcJacobianBadness (points); points[actpind] = hp; @@ -1046,10 +1049,9 @@ FuncGrad (const Vector & x, Vector & g) const g.SetSize(3); g = 0; - for (j = 1; j <= elementsonpoint.EntrySize(actpind); j++) + for (auto ei : elementsonpoint[actpind]) { - int eli = elementsonpoint.Get(actpind, j); - const Element & el = elements[eli-1]; + const Element & el = elements[ei]; lpi = 0; for (k = 1; k <= el.GetNP(); k++) @@ -1057,7 +1059,7 @@ FuncGrad (const Vector & x, Vector & g) const lpi = k; if (!lpi) cerr << "loc point not found" << endl; - badness += elements[eli-1]. + badness += elements[ei]. CalcJacobianBadnessGradient (points, lpi, hderiv); for(k=0; k<3; k++) @@ -1119,10 +1121,9 @@ FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const vdir -= scal*nv; } - for (j = 1; j <= elementsonpoint.EntrySize(actpind); j++) + for (auto ei : elementsonpoint[actpind]) { - int eli = elementsonpoint.Get(actpind, j); - const Element & el = elements[eli-1]; + const Element & el = elements[ei]; lpi = 0; for (k = 1; k <= el.GetNP(); k++) @@ -1130,7 +1131,7 @@ FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const lpi = k; if (!lpi) cerr << "loc point not found" << endl; - badness += elements[eli-1]. + badness += elements[ei]. CalcJacobianBadnessDirDeriv (points, lpi, vdir, hderiv); deriv += hderiv; } From 6cdfefcc82a34831e98d2b26ffd4c448d1ab33e3 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Thu, 10 Jun 2021 09:51:56 +0200 Subject: [PATCH 5/9] Use CreateTable for coloring table --- libsrc/meshing/smoothing3.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/libsrc/meshing/smoothing3.cpp b/libsrc/meshing/smoothing3.cpp index 60773d9d..79530dbf 100644 --- a/libsrc/meshing/smoothing3.cpp +++ b/libsrc/meshing/smoothing3.cpp @@ -1483,17 +1483,13 @@ void Mesh :: ImproveMesh (const MeshingParameters & mp, OPTIMIZEGOAL goal) tcoloring.Start(); int ncolors = ngcore::ComputeColoring( colors, ne, getDofs ); - TableCreator creator(ncolors); - for ( ; !creator.Done(); creator++) - { - ParallelForRange( Range(colors), [&](auto myrange) + auto color_table = CreateTable( points.Size(), + [&] ( auto & table, int i ) { - for(auto i : myrange) - creator.Add(colors[i], i); - }); - } + PointIndex pi = i+static_cast(PointIndex::BASE); + table.Add(colors[i], pi); + }, ncolors); - auto color_table = creator.MoveTable(); tcoloring.Stop(); if (goal == OPT_QUALITY) @@ -1530,12 +1526,12 @@ void Mesh :: ImproveMesh (const MeshingParameters & mp, OPTIMIZEGOAL goal) topt.Start(); int counter = 0; - for (int color : Range(color_table.Size())) + for (auto icolor : Range(ncolors)) { if (multithread.terminate) throw NgException ("Meshing stopped"); - ParallelForRange( Range(color_table[color].Size()), [&](auto myrange) + ParallelForRange( color_table[icolor].Range(), [&](auto myrange) { RegionTracer reg(ngcore::TaskManager::GetThreadId(), trange, myrange.Size()); Vector x(3); @@ -1550,7 +1546,7 @@ void Mesh :: ImproveMesh (const MeshingParameters & mp, OPTIMIZEGOAL goal) for (auto i : myrange) { - PointIndex pi(color_table[color][i]+PointIndex::BASE); + PointIndex pi = color_table[icolor][i]; if ( (*this)[pi].Type() == INNERPOINT ) { counter++; From b677ef5e22ea8f61e15c44ffc2576d4609bce097 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Thu, 10 Jun 2021 09:53:42 +0200 Subject: [PATCH 6/9] Fix RangeException (prepare for local optimizations, with partially filled elementsonpoint table) --- libsrc/meshing/smoothing3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/meshing/smoothing3.cpp b/libsrc/meshing/smoothing3.cpp index 79530dbf..b172ddaf 100644 --- a/libsrc/meshing/smoothing3.cpp +++ b/libsrc/meshing/smoothing3.cpp @@ -1476,7 +1476,7 @@ void Mesh :: ImproveMesh (const MeshingParameters & mp, OPTIMIZEGOAL goal) const auto & getDofs = [&] (int i) { i += PointIndex::BASE; - return FlatArray(elementsonpoint[i].Size(), &elementsonpoint[i][0]); + return FlatArray(elementsonpoint[i].Size(), elementsonpoint[i].Data()); }; Array colors(points.Size()); From 80d648c0055058adb2ed1ba27ca3ef3e3d58a0fc Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Thu, 10 Jun 2021 09:54:38 +0200 Subject: [PATCH 7/9] parallel evaluation of localh in ImproveMesh() --- libsrc/meshing/smoothing3.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libsrc/meshing/smoothing3.cpp b/libsrc/meshing/smoothing3.cpp index b172ddaf..a5787cb1 100644 --- a/libsrc/meshing/smoothing3.cpp +++ b/libsrc/meshing/smoothing3.cpp @@ -1459,6 +1459,7 @@ void Mesh :: ImproveMesh (const MeshingParameters & mp, OPTIMIZEGOAL goal) static Timer tcalcbadmax("Calc badmax"); static Timer topt("optimize"); static Timer trange("range"); + static Timer tloch("loch"); // return ImproveMeshSequential(mp, goal); BuildBoundaryEdges(false); @@ -1502,12 +1503,16 @@ void Mesh :: ImproveMesh (const MeshingParameters & mp, OPTIMIZEGOAL goal) (*testout) << setprecision(8); - NgArray pointh (points.Size()); + Array pointh (points.Size()); if(lochfunc) { - for (PointIndex pi : points.Range()) - pointh[pi] = GetH(points[pi]); + RegionTimer rt(tloch); + ParallelForRange(points.Range(), [&] (auto myrange) + { + for(auto pi : myrange) + pointh[pi] = GetH(points[pi]); + }); } else { From 3f93ccd3bda7e97676f8396aff722327744a1af1 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Thu, 10 Jun 2021 09:56:42 +0200 Subject: [PATCH 8/9] remove static array in ruler3 (prepare for parallel meshing) --- libsrc/meshing/ruler3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/meshing/ruler3.cpp b/libsrc/meshing/ruler3.cpp index 42c1d83f..dd70a8ab 100644 --- a/libsrc/meshing/ruler3.cpp +++ b/libsrc/meshing/ruler3.cpp @@ -685,7 +685,7 @@ int Meshing3 :: ApplyRules for (int i = 1; i <= lfaces.Size() && ok; i++) { - static NgArray lpi(4); + NgArrayMem lpi(4); if (!fused.Get(i)) { From 8df49eee2ada3a126863c4a03646e5744340fa26 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Thu, 10 Jun 2021 10:15:55 +0200 Subject: [PATCH 9/9] Reduce sizeof(MeshPoint) from 48 to 40 bytes --- libsrc/meshing/meshtype.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/meshing/meshtype.hpp b/libsrc/meshing/meshtype.hpp index cff7bd5f..9bf8084b 100644 --- a/libsrc/meshing/meshtype.hpp +++ b/libsrc/meshing/meshtype.hpp @@ -49,7 +49,7 @@ namespace netgen #define ELEMENT2D_MAXPOINTS 8 - enum POINTTYPE { FIXEDPOINT = 1, EDGEPOINT = 2, SURFACEPOINT = 3, INNERPOINT = 4 }; + enum POINTTYPE : unsigned char { FIXEDPOINT = 1, EDGEPOINT = 2, SURFACEPOINT = 3, INNERPOINT = 4 }; enum ELEMENTTYPE { FREEELEMENT, FIXEDELEMENT }; enum OPTIMIZEGOAL { OPT_QUALITY, OPT_CONFORM, OPT_REST, OPT_WORSTCASE, OPT_LEGAL }; @@ -336,8 +336,8 @@ namespace netgen */ class MeshPoint : public Point<3> { - int layer; double singular; // singular factor for hp-refinement + int layer; POINTTYPE type;