Compare commits
2 Commits
multi-fini
...
develop.me
| Author | SHA1 | Date | |
|---|---|---|---|
| d6cc79fe76 | |||
| 9dee2cad3e |
@ -204,16 +204,6 @@ int main(int argc, char *argv[])
|
||||
Info<<" " << *iter;
|
||||
}
|
||||
Info<< nl;
|
||||
|
||||
Info<< "data:" << Foam::name(ident.cdata())
|
||||
<< " size:" << ident.size() << nl;
|
||||
|
||||
|
||||
Info<< "resize_unsafe(10)" << nl;
|
||||
ident.resize_unsafe(10);
|
||||
|
||||
Info<< "data:" << Foam::name(ident.cdata())
|
||||
<< " size:" << ident.size() << nl;
|
||||
}
|
||||
|
||||
if (false)
|
||||
|
||||
@ -132,6 +132,11 @@ projectDir="$HOME/OpenFOAM/OpenFOAM-$WM_PROJECT_VERSION"
|
||||
# projectDir="@PROJECT_DIR@"
|
||||
: # Safety statement (if the user removed all fallback values)
|
||||
|
||||
# [FOAM_MEMORY_POOL] - Optional memory management
|
||||
# - overrides the 'memory_pool' etc/controlDict entry
|
||||
# = "true | false | host [size=nn] [incr=nn]"
|
||||
#export FOAM_MEMORY_POOL="host"
|
||||
|
||||
# [FOAM_SIGFPE] - Trap floating-point exceptions.
|
||||
# - overrides the 'trapFpe' controlDict entry
|
||||
# = true | false
|
||||
|
||||
@ -221,6 +221,9 @@ OptimisationSwitches
|
||||
// Other
|
||||
// =====
|
||||
|
||||
// Optional memory management (sizing in MB)
|
||||
// memory_pool "host; size=1024; incr=5"
|
||||
|
||||
// Trap floating point exception.
|
||||
// Can override with FOAM_SIGFPE env variable (true|false)
|
||||
trapFpe 1;
|
||||
|
||||
@ -134,6 +134,11 @@ set projectDir=`lsof +p $$ |& sed -ne 's#^[^/]*##;\@/'"$projectName"'[^/]*/etc/c
|
||||
# Or optionally hard-coded (eg, with autoconfig)
|
||||
# set projectDir="@PROJECT_DIR@"
|
||||
|
||||
# [FOAM_MEMORY_POOL] - Optional memory management
|
||||
# - overrides the 'memory_pool' etc/controlDict entry
|
||||
# = "true | false | host [size=nn] [incr=nn]"
|
||||
#setenv FOAM_MEMORY_POOL "host"
|
||||
|
||||
# [FOAM_SIGFPE] - Trap floating-point exceptions.
|
||||
# - overrides the 'trapFpe' controlDict entry
|
||||
# = true | false
|
||||
|
||||
@ -3,6 +3,8 @@ MSwindows.C
|
||||
cpuInfo/cpuInfo.C
|
||||
memInfo/memInfo.C
|
||||
|
||||
memory/MemoryPool.cxx
|
||||
|
||||
signals/sigFpe.cxx
|
||||
signals/sigInt.cxx
|
||||
signals/sigQuit.cxx
|
||||
|
||||
83
src/OSspecific/MSwindows/memory/MemoryPool.cxx
Normal file
83
src/OSspecific/MSwindows/memory/MemoryPool.cxx
Normal file
@ -0,0 +1,83 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM 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.
|
||||
|
||||
OpenFOAM 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 OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "MemoryPool.H"
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
// bool Foam::MemoryPool::create(const std::string& ctrl, bool verbose)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
|
||||
bool Foam::MemoryPool::create(bool verbose)
|
||||
{
|
||||
// No banner information since it is currently never an option
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Foam::MemoryPool::destroy(bool verbose)
|
||||
{}
|
||||
|
||||
|
||||
bool Foam::MemoryPool::active() noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::MemoryPool::suspend() noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Foam::MemoryPool::resume() noexcept
|
||||
{}
|
||||
|
||||
|
||||
bool Foam::MemoryPool::is_pool(void* ptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void* Foam::MemoryPool::try_allocate(std::size_t nbytes)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::MemoryPool::try_deallocate(void* ptr)
|
||||
{
|
||||
return (!ptr);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -2,6 +2,7 @@
|
||||
cd "${0%/*}" || exit # Run from this directory
|
||||
targetType=libo # Preferred library type
|
||||
. ${WM_PROJECT_DIR:?}/wmake/scripts/AllwmakeParseArguments $*
|
||||
. ${WM_PROJECT_DIR:?}/wmake/scripts/have_umpire
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Hack for MacOS (with Gcc).
|
||||
@ -59,6 +60,47 @@ then
|
||||
export COMP_FLAGS="-DFOAM_USE_INOTIFY"
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Have -lumpire, but also -lcamp etc.
|
||||
# Also need to follow the link order
|
||||
get_umpire_libs()
|
||||
{
|
||||
if [ -d "${UMPIRE_LIB_DIR}" ]
|
||||
then
|
||||
set -- $(
|
||||
# Expected link order
|
||||
for name in umpire fmt camp
|
||||
do
|
||||
[ -f "$UMPIRE_LIB_DIR/lib${name}.a" ] && echo "-l$name"
|
||||
done
|
||||
)
|
||||
echo "$@"
|
||||
else
|
||||
echo
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if have_umpire
|
||||
then
|
||||
libNames="$(get_umpire_libs)"
|
||||
|
||||
if [ -n "$libNames" ]
|
||||
then
|
||||
echo " found umpire -- enabling memory pool interface" 1>&2
|
||||
echo " umpire libs: $libNames" 1>&2
|
||||
|
||||
COMP_FLAGS="$COMP_FLAGS -DFOAM_USE_UMPIRE -I${UMPIRE_INC_DIR}"
|
||||
LINK_FLAGS="$LINK_FLAGS -L${UMPIRE_LIB_DIR} $libNames"
|
||||
export COMP_FLAGS LINK_FLAGS
|
||||
else
|
||||
echo " expecting umpire, but did not resolve the libraries" 1>&2
|
||||
fi
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Make object (non-shared by default)
|
||||
# Never want/need openmp, especially for static objects
|
||||
wmake -no-openmp $targetType
|
||||
|
||||
@ -4,6 +4,8 @@ cpuInfo/cpuInfo.C
|
||||
cpuTime/cpuTimePosix.C
|
||||
memInfo/memInfo.C
|
||||
|
||||
memory/MemoryPool.cxx
|
||||
|
||||
signals/sigFpe.cxx
|
||||
signals/sigSegv.cxx
|
||||
signals/sigInt.cxx
|
||||
|
||||
@ -1 +1,4 @@
|
||||
EXE_INC = $(COMP_FLAGS)
|
||||
/* umpire uses old-style cast etc */
|
||||
EXE_INC = $(COMP_FLAGS) $(c++LESSWARN)
|
||||
|
||||
LIBO_LIBS = $(LINK_FLAGS)
|
||||
|
||||
510
src/OSspecific/POSIX/memory/MemoryPool.cxx
Normal file
510
src/OSspecific/POSIX/memory/MemoryPool.cxx
Normal file
@ -0,0 +1,510 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM 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.
|
||||
|
||||
OpenFOAM 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 OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "MemoryPool.H"
|
||||
#include "debug.H"
|
||||
#include "dictionary.H"
|
||||
#include "sigFpe.H"
|
||||
#include "OSspecific.H" // For getEnv
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef FOAM_USE_UMPIRE
|
||||
|
||||
// #include <cerrno>
|
||||
#include <cinttypes>
|
||||
#include <tuple>
|
||||
|
||||
#include "umpire/Allocator.hpp"
|
||||
#include "umpire/ResourceManager.hpp"
|
||||
#include "umpire/strategy/AlignedAllocator.hpp"
|
||||
#include "umpire/strategy/DynamicPoolList.hpp"
|
||||
|
||||
static bool disabled_(false);
|
||||
static umpire::Allocator aligned_allocator;
|
||||
static umpire::Allocator pooled_allocator;
|
||||
static umpire::ResourceManager* manager_(nullptr);
|
||||
static umpire::ResourceManager* suspended_(nullptr);
|
||||
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef FOAM_USE_UMPIRE
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// Different supported allocation types
|
||||
enum class Types { undefined, none, host, device, managed };
|
||||
|
||||
typedef std::tuple<Types, std::size_t, std::size_t> ctrlTuple;
|
||||
|
||||
// Extract key=INT, the key includes the '='
|
||||
int getIntParameter(const std::string& key, const std::string& ctrl)
|
||||
{
|
||||
int val(0);
|
||||
|
||||
const auto pos = ctrl.find(key);
|
||||
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
const char* buf = (ctrl.data() + pos + key.size());
|
||||
|
||||
char *endptr = nullptr;
|
||||
errno = 0;
|
||||
auto parsed = std::strtoimax(buf, &endptr, 10);
|
||||
|
||||
if (errno || endptr == buf)
|
||||
{
|
||||
// Some type of error OR no conversion
|
||||
}
|
||||
else
|
||||
{
|
||||
val = int(parsed);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
ctrlTuple getControlValues(const std::string& ctrl)
|
||||
{
|
||||
ctrlTuple result(Types::undefined, 0, 0);
|
||||
|
||||
bool checkParam = false;
|
||||
|
||||
// Also find things that look like Switch constants.
|
||||
// Unfortunately need to do this manually since Switch::find()
|
||||
// itself would not manage to parse something like "true; size=10"
|
||||
|
||||
if (ctrl.empty())
|
||||
{
|
||||
// Nothing => undefined
|
||||
}
|
||||
else if
|
||||
(
|
||||
std::string::npos != ctrl.find("false") // ctrl.contains("false")
|
||||
|| std::string::npos != ctrl.find("off") // ctrl.contains("off")
|
||||
|| std::string::npos != ctrl.find("no") // ctrl.contains("no")
|
||||
|| std::string::npos != ctrl.find("none") // ctrl.contains("none")
|
||||
)
|
||||
{
|
||||
std::get<0>(result) = Types::none;
|
||||
}
|
||||
else if
|
||||
(
|
||||
std::string::npos != ctrl.find("true") // ctrl.contains("true")
|
||||
|| std::string::npos != ctrl.find("on") // ctrl.contains("on")
|
||||
|| std::string::npos != ctrl.find("yes") // ctrl.contains("yes")
|
||||
|
||||
|| std::string::npos != ctrl.find("host") // ctrl.contains("host")
|
||||
|| std::string::npos != ctrl.find("system") // ctrl.contains("system")
|
||||
)
|
||||
{
|
||||
std::get<0>(result) = Types::host;
|
||||
checkParam = true;
|
||||
}
|
||||
|
||||
// These need more testing
|
||||
else if
|
||||
(
|
||||
std::string::npos != ctrl.find("device") // ctrl.contains("device")
|
||||
)
|
||||
{
|
||||
std::get<0>(result) = Types::device;
|
||||
checkParam = true;
|
||||
}
|
||||
else if
|
||||
(
|
||||
std::string::npos != ctrl.find("managed") // ctrl.contains("managed")
|
||||
)
|
||||
{
|
||||
std::get<0>(result) = Types::managed;
|
||||
checkParam = true;
|
||||
}
|
||||
|
||||
if (checkParam)
|
||||
{
|
||||
std::get<1>(result) = getIntParameter("size=", ctrl);
|
||||
std::get<2>(result) = getIntParameter("incr=", ctrl);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool create_from(const ctrlTuple& controls, bool verbose)
|
||||
{
|
||||
using namespace Foam;
|
||||
|
||||
if (manager_ || suspended_)
|
||||
{
|
||||
// Already created
|
||||
return true;
|
||||
}
|
||||
|
||||
// Type, initial size, increment
|
||||
auto [which, size, incr] = controls;
|
||||
|
||||
// std::cerr
|
||||
// << "which=" << int(which)
|
||||
// << ", size=" << int(size)
|
||||
// << ", incr=" << int(incr) << '\n';
|
||||
|
||||
|
||||
constexpr size_t MegaByte(1024*1024);
|
||||
|
||||
switch (which)
|
||||
{
|
||||
case Types::undefined :
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
Info<< "memory pool : unused" << nl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Types::none :
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
Info<< "memory pool : disabled" << nl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Types::host :
|
||||
{
|
||||
// Default sizing parameters
|
||||
if (!size) size = 1024;
|
||||
if (!incr) incr = 5;
|
||||
|
||||
auto& rm = umpire::ResourceManager::getInstance();
|
||||
manager_ = &rm;
|
||||
|
||||
aligned_allocator =
|
||||
rm.makeAllocator<umpire::strategy::AlignedAllocator>
|
||||
(
|
||||
"aligned_allocator",
|
||||
rm.getAllocator("HOST"),
|
||||
|
||||
// alignment
|
||||
256
|
||||
);
|
||||
|
||||
pooled_allocator =
|
||||
rm.makeAllocator<umpire::strategy::DynamicPoolList>
|
||||
(
|
||||
"openfoam_HOST_pool",
|
||||
aligned_allocator,
|
||||
|
||||
// initial block allocation size
|
||||
(size*MegaByte),
|
||||
|
||||
// incremental block allocation size
|
||||
(incr*MegaByte)
|
||||
);
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
Info<< "memory pool : host (size="
|
||||
<< int(size) << "MB, incr="
|
||||
<< int(incr) << "MB)\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Types::device :
|
||||
{
|
||||
auto& rm = umpire::ResourceManager::getInstance();
|
||||
manager_ = &rm;
|
||||
|
||||
aligned_allocator = rm.getAllocator("DEVICE");
|
||||
|
||||
pooled_allocator =
|
||||
rm.makeAllocator<umpire::strategy::DynamicPoolList>
|
||||
(
|
||||
"openfoam_DEVICE_pool",
|
||||
aligned_allocator
|
||||
);
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
Info<< "memory pool : device" << nl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Types::managed :
|
||||
{
|
||||
// Default sizing parameters
|
||||
if (!size) size = 10*1024;
|
||||
if (!incr) incr = 10;
|
||||
|
||||
auto& rm = umpire::ResourceManager::getInstance();
|
||||
manager_ = &rm;
|
||||
|
||||
aligned_allocator = rm.getAllocator("UM");
|
||||
|
||||
pooled_allocator =
|
||||
rm.makeAllocator<umpire::strategy::DynamicPoolList>
|
||||
(
|
||||
"openfoam_UM_pool",
|
||||
aligned_allocator,
|
||||
|
||||
// initial block allocation size
|
||||
(size*MegaByte),
|
||||
|
||||
// incremental block allocation size
|
||||
(incr*MegaByte)
|
||||
);
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
Info<< "memory pool : managed (size="
|
||||
<< int(size) << "MB, incr="
|
||||
<< int(incr) << "MB)\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (which != Types::undefined && which != Types::none);
|
||||
}
|
||||
|
||||
|
||||
} // End anonymous namespace
|
||||
|
||||
#endif // FOAM_USE_UMPIRE
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
// bool Foam::MemoryPool::create(const std::string& ctrl, bool verbose)
|
||||
// {
|
||||
// #ifdef FOAM_USE_UMPIRE
|
||||
// if (manager_ || suspended_)
|
||||
// {
|
||||
// // Already created
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// auto controls = getControlValues(ctrl);
|
||||
//
|
||||
// return create_from(controls, verbose);
|
||||
// #else
|
||||
// return false;
|
||||
// #endif
|
||||
// }
|
||||
|
||||
|
||||
bool Foam::MemoryPool::create(bool verbose)
|
||||
{
|
||||
#ifdef FOAM_USE_UMPIRE
|
||||
if (disabled_)
|
||||
{
|
||||
// Disallowed
|
||||
return false;
|
||||
}
|
||||
else if (manager_ || suspended_)
|
||||
{
|
||||
// Already created
|
||||
return true;
|
||||
}
|
||||
|
||||
// First check environment
|
||||
auto controls = getControlValues(Foam::getEnv("FOAM_MEMORY_POOL"));
|
||||
|
||||
if (std::get<0>(controls) == Types::none)
|
||||
{
|
||||
// Disabled from environment - has highest priority
|
||||
disabled_ = true;
|
||||
}
|
||||
|
||||
// Currently no easy way to handle <system>/controlDict...
|
||||
|
||||
// Fallback from etc/controlDict
|
||||
if (std::get<0>(controls) == Types::undefined)
|
||||
{
|
||||
// From central etc/controlDict
|
||||
const auto& dict = Foam::debug::optimisationSwitches();
|
||||
|
||||
if (auto* eptr = dict.findStream("memory_pool", keyType::LITERAL))
|
||||
{
|
||||
const token& firstToken = eptr->front();
|
||||
|
||||
if (firstToken.isStringType())
|
||||
{
|
||||
controls = getControlValues(firstToken.stringToken());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return create_from(controls, verbose);
|
||||
#else
|
||||
if (verbose)
|
||||
{
|
||||
Info<< "memory pool : not available" << nl;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Foam::MemoryPool::destroy(bool verbose)
|
||||
{
|
||||
// Nothing currently needed but could add in something like this:
|
||||
|
||||
// if (manager_ || suspended_)
|
||||
// {
|
||||
// pooled_allocator.release();
|
||||
// }
|
||||
|
||||
// However, need to find the proper sequence within
|
||||
// Foam::exit() or UPstream::exit() ...
|
||||
}
|
||||
|
||||
|
||||
bool Foam::MemoryPool::active() noexcept
|
||||
{
|
||||
#ifdef FOAM_USE_UMPIRE
|
||||
return bool(manager_);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool Foam::MemoryPool::suspend() noexcept
|
||||
{
|
||||
#ifdef FOAM_USE_UMPIRE
|
||||
bool status(suspended_);
|
||||
if (manager_) // <- and (!suspended_)
|
||||
{
|
||||
std::swap(manager_, suspended_);
|
||||
}
|
||||
return status;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Foam::MemoryPool::resume() noexcept
|
||||
{
|
||||
#ifdef FOAM_USE_UMPIRE
|
||||
if (suspended_) // <- and (!manager_)
|
||||
{
|
||||
std::swap(manager_, suspended_);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool Foam::MemoryPool::is_pool(void* ptr)
|
||||
{
|
||||
#ifdef FOAM_USE_UMPIRE
|
||||
if (ptr)
|
||||
{
|
||||
if (manager_)
|
||||
{
|
||||
return manager_->hasAllocator(ptr);
|
||||
}
|
||||
else if (suspended_)
|
||||
{
|
||||
return suspended_->hasAllocator(ptr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void* Foam::MemoryPool::try_allocate(std::size_t nbytes)
|
||||
{
|
||||
void* ptr = nullptr;
|
||||
|
||||
#ifdef FOAM_USE_UMPIRE
|
||||
if (manager_)
|
||||
{
|
||||
ptr = pooled_allocator.allocate(nbytes);
|
||||
|
||||
// std::cerr<< "allocate(" << int(nbytes) << ")\n";
|
||||
|
||||
// Optionally fill with NaN (depends on current flags)
|
||||
Foam::sigFpe::fillNan_if(ptr, nbytes);
|
||||
|
||||
if (!ptr)
|
||||
{
|
||||
// Pout<< "umpire failed to allocate memory\n";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::MemoryPool::try_deallocate(void* ptr)
|
||||
{
|
||||
#ifdef FOAM_USE_UMPIRE
|
||||
if (ptr)
|
||||
{
|
||||
if (manager_)
|
||||
{
|
||||
if (manager_->hasAllocator(ptr)) // <- ie, is_pool()
|
||||
{
|
||||
// std::cerr<< "deallocate()\n";
|
||||
manager_->deallocate(ptr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (suspended_)
|
||||
{
|
||||
// Deallocate even if nominally suspended
|
||||
|
||||
if (suspended_->hasAllocator(ptr)) // <- ie, is_pool()
|
||||
{
|
||||
// std::cerr<< "deallocate()\n";
|
||||
suspended_->deallocate(ptr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return (!ptr);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -203,7 +203,7 @@ public:
|
||||
|
||||
//- Change the value for the list capacity directly (ADVANCED, UNSAFE)
|
||||
//- Does not perform any memory management or resizing.
|
||||
void setCapacity_unsafe(const label len) noexcept { capacity_ = len; }
|
||||
void setCapacity_unsafe(label len) noexcept { capacity_ = len; }
|
||||
|
||||
//- Reserve allocation space for at least this size, allocating new
|
||||
//- space if required and \em retaining old content.
|
||||
@ -251,11 +251,6 @@ public:
|
||||
//- Shrink the allocated space to the number of elements used.
|
||||
inline void shrink_to_fit();
|
||||
|
||||
//- Shrink the internal bookkeeping of the allocated space to the
|
||||
//- number of addressed elements without affecting allocation.
|
||||
// \note when empty() it will delete any allocated memory.
|
||||
inline void shrink_unsafe();
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
|
||||
@ -68,7 +68,9 @@ inline void Foam::DynamicList<T, SizeMin>::doCapacity
|
||||
// Addressable length, possibly truncated by new capacity
|
||||
const label currLen = Foam::min(List<T>::size(), newCapacity);
|
||||
|
||||
// Consistent allocated sizing
|
||||
List<T>::setAddressableSize(capacity_);
|
||||
|
||||
if (nocopy)
|
||||
{
|
||||
List<T>::resize_nocopy(newCapacity);
|
||||
@ -95,6 +97,9 @@ inline void Foam::DynamicList<T, SizeMin>::doReserve
|
||||
// Preserve addressed size
|
||||
const label currLen = List<T>::size();
|
||||
|
||||
// Consistent allocated sizing
|
||||
List<T>::setAddressableSize(capacity_);
|
||||
|
||||
// Increase capacity (eg, doubling)
|
||||
capacity_ =
|
||||
Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_);
|
||||
@ -105,8 +110,10 @@ inline void Foam::DynamicList<T, SizeMin>::doReserve
|
||||
}
|
||||
else
|
||||
{
|
||||
List<T>::resize(capacity_);
|
||||
List<T>::resize_copy(currLen, capacity_);
|
||||
}
|
||||
|
||||
capacity_ = List<T>::size();
|
||||
List<T>::setAddressableSize(currLen);
|
||||
}
|
||||
}
|
||||
@ -271,7 +278,7 @@ inline Foam::DynamicList<T, SizeMin>::DynamicList
|
||||
List<T>(std::move(static_cast<List<T>&>(list))),
|
||||
capacity_(list.capacity())
|
||||
{
|
||||
list.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
|
||||
list.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
|
||||
|
||||
@ -285,7 +292,7 @@ inline Foam::DynamicList<T, SizeMin>::DynamicList
|
||||
List<T>(std::move(static_cast<List<T>&>(list))),
|
||||
capacity_(list.capacity())
|
||||
{
|
||||
list.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
|
||||
list.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
|
||||
|
||||
@ -361,8 +368,15 @@ inline void Foam::DynamicList<T, SizeMin>::reserve_exact
|
||||
// Preserve addressed size
|
||||
const label currLen = List<T>::size();
|
||||
|
||||
capacity_ = len;
|
||||
List<T>::resize(capacity_);
|
||||
// Consistent allocated sizing
|
||||
List<T>::setAddressableSize(capacity_);
|
||||
|
||||
// if (!nocopy)
|
||||
{
|
||||
List<T>::resize_copy(currLen, len);
|
||||
}
|
||||
|
||||
capacity_ = List<T>::size();
|
||||
List<T>::setAddressableSize(currLen);
|
||||
}
|
||||
}
|
||||
@ -449,18 +463,6 @@ inline void Foam::DynamicList<T, SizeMin>::shrink_to_fit()
|
||||
}
|
||||
|
||||
|
||||
template<class T, int SizeMin>
|
||||
inline void Foam::DynamicList<T, SizeMin>::shrink_unsafe()
|
||||
{
|
||||
if (List<T>::empty())
|
||||
{
|
||||
// Delete storage if empty
|
||||
List<T>::clear();
|
||||
}
|
||||
capacity_ = List<T>::size();
|
||||
}
|
||||
|
||||
|
||||
template<class T, int SizeMin>
|
||||
inline void
|
||||
Foam::DynamicList<T, SizeMin>::swap(List<T>& list)
|
||||
|
||||
@ -236,13 +236,6 @@ public:
|
||||
// Otherwise the contents will be uninitialized.
|
||||
inline void resize_nocopy(const label len);
|
||||
|
||||
//- Change the addressed list size directly without affecting
|
||||
//- any memory management (advanced usage).
|
||||
//
|
||||
// It is left to the caller to avoid \em unsafe lengthening beyond
|
||||
// the allocated memory region.
|
||||
inline void resize_unsafe(const label len) noexcept;
|
||||
|
||||
//- Alias for resize()
|
||||
void setSize(const label n) { this->resize(n); }
|
||||
|
||||
|
||||
@ -178,13 +178,6 @@ inline void Foam::List<T>::resize_nocopy(const label len)
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline void Foam::List<T>::resize_unsafe(const label len) noexcept
|
||||
{
|
||||
UList<T>::setAddressableSize(len);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline T& Foam::List<T>::newElmt(const label i)
|
||||
{
|
||||
|
||||
@ -34,6 +34,7 @@ Description
|
||||
#ifndef Foam_ListPolicy_H
|
||||
#define Foam_ListPolicy_H
|
||||
|
||||
#include "MemoryPool.H" // Also includes <cstdint>
|
||||
#include "contiguous.H" // Also includes <type_traits>
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -103,6 +104,18 @@ template<> struct no_linebreak<wordRe> : std::true_type {};
|
||||
// - use_offload(n) :
|
||||
// Lower threshold for switching to device offloading
|
||||
//
|
||||
//
|
||||
// Use of the memory-pool is controlled by the 'is_aligned_type()' test
|
||||
// and the minimum field size, controlled by the 'use_memory_pool()' test.
|
||||
//
|
||||
// If the memory-pool is not enabled or not required according to the two
|
||||
// above tests, the allocation falls back to either an aligned or unaligned
|
||||
// allocation.
|
||||
//
|
||||
// The decision about when to choose aligned vs unaligned allocation
|
||||
// is still a compile-time option. Made by direct edit of the
|
||||
// appropriate functions.
|
||||
//
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- Consider aligned allocation for the given type?
|
||||
@ -146,27 +159,104 @@ inline constexpr bool use_offload(IntType n) noexcept
|
||||
}
|
||||
|
||||
|
||||
//- Default alignment for larger fields
|
||||
inline constexpr std::align_val_t default_alignment() noexcept
|
||||
{
|
||||
return std::align_val_t(256);
|
||||
}
|
||||
|
||||
|
||||
//- Allocate from memory pool (if active), or aligned, or normal
|
||||
template<class T, class IntType>
|
||||
inline T* allocate(IntType n)
|
||||
{
|
||||
// Plain new
|
||||
return new T[n];
|
||||
if constexpr (ListPolicy::is_aligned_type<T>())
|
||||
{
|
||||
// Note: threshold for use_memory_pool() >= use_alignment()
|
||||
|
||||
if (ListPolicy::use_alignment(n))
|
||||
{
|
||||
if
|
||||
(
|
||||
void *pool_ptr
|
||||
(
|
||||
// Consider memory pool for large amounts of data
|
||||
ListPolicy::use_memory_pool(n)
|
||||
? Foam::MemoryPool::try_allocate(sizeof(T)*n)
|
||||
: nullptr
|
||||
);
|
||||
pool_ptr
|
||||
)
|
||||
{
|
||||
// Placement new
|
||||
return new (pool_ptr) T[n];
|
||||
}
|
||||
else
|
||||
{
|
||||
return new (ListPolicy::default_alignment()) T[n];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Plain new
|
||||
return new T[n];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Plain new
|
||||
return new T[n];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//- Deallocate from memory pool, or normal
|
||||
template<class T, class IntType>
|
||||
inline void deallocate(T* ptr)
|
||||
{
|
||||
// Plain new
|
||||
delete[] ptr;
|
||||
if constexpr (ListPolicy::is_aligned_type<T>())
|
||||
{
|
||||
if (ptr && !Foam::MemoryPool::try_deallocate(ptr))
|
||||
{
|
||||
// Plain new
|
||||
delete[] ptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Plain new
|
||||
delete[] ptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//- Deallocate from memory pool, or aligned, or normal
|
||||
template<class T, class IntType>
|
||||
inline void deallocate(T* ptr, [[maybe_unused]] IntType n)
|
||||
{
|
||||
// Plain new
|
||||
delete[] ptr;
|
||||
if constexpr (ListPolicy::is_aligned_type<T>())
|
||||
{
|
||||
// Note: threshold for use_memory_pool() >= use_alignment()
|
||||
|
||||
if (ListPolicy::use_alignment(n))
|
||||
{
|
||||
if (ptr && !Foam::MemoryPool::try_deallocate(ptr))
|
||||
{
|
||||
// Alignment depends on the number of elements
|
||||
::operator delete[](ptr, ListPolicy::default_alignment());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Plain new
|
||||
delete[] ptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Plain new
|
||||
delete[] ptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -112,23 +112,26 @@ public:
|
||||
|
||||
//- Change the value for the list capacity directly (ADVANCED, UNSAFE)
|
||||
//- Does not perform any memory management or resizing.
|
||||
void setCapacity_unsafe(const label len) noexcept { capacity_ = len; }
|
||||
void setCapacity_unsafe(label len) noexcept { capacity_ = len; }
|
||||
|
||||
//- Reserve allocation space for at least this size.
|
||||
// New entries are initialized to nullptr.
|
||||
inline void reserve(const label len);
|
||||
|
||||
//- Reserve allocation space for at least this size.
|
||||
//- If allocation is required, uses the specified size
|
||||
//- without any other resizing logic.
|
||||
// New entries are initialized to nullptr.
|
||||
inline void reserve_exact(const label len);
|
||||
|
||||
//- Alter the addressed list size.
|
||||
inline void resize(const label newLen);
|
||||
// New entries are initialized to nullptr.
|
||||
inline void resize(const label len);
|
||||
|
||||
//- Set the addressed list to the given size,
|
||||
//- deleting all existing entries.
|
||||
//- Afterwards the list contains all \c nullptr entries.
|
||||
inline void resize_null(const label newLen);
|
||||
inline void resize_null(const label len);
|
||||
|
||||
//- Clear the addressed list, i.e. set the size to zero.
|
||||
// Allocated size does not change
|
||||
@ -140,11 +143,6 @@ public:
|
||||
//- Shrink the allocated space to the number of elements used.
|
||||
inline void shrink_to_fit();
|
||||
|
||||
//- Shrink the internal bookkeeping of the allocated space to the
|
||||
//- number of addressed elements without affecting allocation.
|
||||
// \note when empty() it will delete any allocated memory.
|
||||
inline void shrink_unsafe();
|
||||
|
||||
//- Alias for shrink_to_fit()
|
||||
void shrink() { this->shrink_to_fit(); }
|
||||
|
||||
|
||||
@ -82,10 +82,7 @@ inline Foam::PtrDynList<T, SizeMin>::PtrDynList
|
||||
PtrList<T>(std::move(list)),
|
||||
capacity_(list.capacity())
|
||||
{
|
||||
// FUTURE:
|
||||
// list.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
|
||||
|
||||
list.clearStorage(); // capacity=0 etc.
|
||||
list.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
|
||||
|
||||
@ -99,10 +96,7 @@ inline Foam::PtrDynList<T, SizeMin>::PtrDynList
|
||||
PtrList<T>(std::move(list)),
|
||||
capacity_(list.capacity())
|
||||
{
|
||||
// FUTURE:
|
||||
// list.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
|
||||
|
||||
list.clearStorage(); // capacity=0 etc.
|
||||
list.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
|
||||
|
||||
@ -135,11 +129,17 @@ inline void Foam::PtrDynList<T, SizeMin>::reserve(const label len)
|
||||
// Preserve addressed size
|
||||
const label currLen = PtrList<T>::size();
|
||||
|
||||
// Consistent allocated sizing
|
||||
PtrList<T>::setAddressableSize(capacity_);
|
||||
|
||||
// Increase capacity (eg, doubling)
|
||||
capacity_ =
|
||||
Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_);
|
||||
|
||||
// No PtrList<T>::resize_copy(...) -> copying nullptr is cheap
|
||||
PtrList<T>::resize(capacity_);
|
||||
|
||||
capacity_ = PtrList<T>::size();
|
||||
PtrList<T>::setAddressableSize(currLen);
|
||||
}
|
||||
}
|
||||
@ -153,8 +153,13 @@ inline void Foam::PtrDynList<T, SizeMin>::reserve_exact(const label len)
|
||||
// Preserve addressed size
|
||||
const label currLen = PtrList<T>::size();
|
||||
|
||||
capacity_ = len;
|
||||
PtrList<T>::resize(capacity_);
|
||||
// Consistent allocated sizing
|
||||
PtrList<T>::setAddressableSize(capacity_);
|
||||
|
||||
// No PtrList<T>::resize_copy(...) -> copying nullptr is cheap
|
||||
PtrList<T>::resize(len);
|
||||
|
||||
capacity_ = PtrList<T>::size();
|
||||
PtrList<T>::setAddressableSize(currLen);
|
||||
}
|
||||
}
|
||||
@ -164,16 +169,12 @@ template<class T, int SizeMin>
|
||||
inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen)
|
||||
{
|
||||
auto& ptrs = this->ptrs_;
|
||||
|
||||
const label oldLen = ptrs.size();
|
||||
|
||||
if (capacity_ < newLen)
|
||||
{
|
||||
// Increase capacity (eg, doubling)
|
||||
capacity_ =
|
||||
Foam::ListPolicy::reserve_size<SizeMin, 2>(newLen, capacity_);
|
||||
|
||||
PtrList<T>::resize(capacity_);
|
||||
// Extend list
|
||||
this->reserve(newLen);
|
||||
}
|
||||
else if (newLen != oldLen)
|
||||
{
|
||||
@ -191,13 +192,16 @@ inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen)
|
||||
|
||||
|
||||
template<class T, int SizeMin>
|
||||
inline void Foam::PtrDynList<T, SizeMin>::resize_null(const label newLen)
|
||||
inline void Foam::PtrDynList<T, SizeMin>::resize_null(const label len)
|
||||
{
|
||||
if (capacity_ < newLen)
|
||||
if (capacity_ < len)
|
||||
{
|
||||
// Consistent allocated sizing
|
||||
PtrList<T>::setAddressableSize(capacity_);
|
||||
|
||||
// Increase capacity (eg, doubling)
|
||||
capacity_ =
|
||||
Foam::ListPolicy::reserve_size<SizeMin, 2>(newLen, capacity_);
|
||||
Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_);
|
||||
|
||||
PtrList<T>::resize_null(capacity_);
|
||||
}
|
||||
@ -207,7 +211,7 @@ inline void Foam::PtrDynList<T, SizeMin>::resize_null(const label newLen)
|
||||
}
|
||||
|
||||
// Adjust addressed size
|
||||
PtrList<T>::setAddressableSize(newLen);
|
||||
PtrList<T>::setAddressableSize(len);
|
||||
}
|
||||
|
||||
|
||||
@ -240,18 +244,6 @@ inline void Foam::PtrDynList<T, SizeMin>::shrink_to_fit()
|
||||
}
|
||||
|
||||
|
||||
template<class T, int SizeMin>
|
||||
inline void Foam::PtrDynList<T, SizeMin>::shrink_unsafe()
|
||||
{
|
||||
if (PtrList<T>::empty())
|
||||
{
|
||||
// Delete empty list
|
||||
PtrList<T>::clear();
|
||||
}
|
||||
capacity_ = PtrList<T>::size();
|
||||
}
|
||||
|
||||
|
||||
template<class T, int SizeMin>
|
||||
inline Foam::label Foam::PtrDynList<T, SizeMin>::squeezeNull()
|
||||
{
|
||||
|
||||
@ -217,7 +217,7 @@ public:
|
||||
|
||||
//- Change the value for the list capacity directly (ADVANCED, UNSAFE)
|
||||
//- Does not perform any memory management or resizing.
|
||||
void setCapacity_unsafe(const label len) noexcept { capacity_ = len; }
|
||||
void setCapacity_unsafe(label len) noexcept { capacity_ = len; }
|
||||
|
||||
//- Reserve allocation space for at least this size, allocating new
|
||||
//- space if required and \em retaining old content.
|
||||
@ -265,11 +265,6 @@ public:
|
||||
//- Shrink the allocated space to the number of elements used.
|
||||
inline void shrink_to_fit();
|
||||
|
||||
//- Shrink the internal bookkeeping of the allocated space to the
|
||||
//- number of addressed elements without affecting allocation.
|
||||
// \note when empty() it will delete any allocated memory.
|
||||
inline void shrink_unsafe();
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
|
||||
@ -66,7 +66,9 @@ inline void Foam::DynamicField<T, SizeMin>::doCapacity
|
||||
// Addressable length, possibly truncated by new capacity
|
||||
const label currLen = Foam::min(List<T>::size(), newCapacity);
|
||||
|
||||
// Consistent allocated sizing
|
||||
List<T>::setAddressableSize(capacity_);
|
||||
|
||||
if (nocopy)
|
||||
{
|
||||
List<T>::resize_nocopy(newCapacity);
|
||||
@ -93,6 +95,9 @@ inline void Foam::DynamicField<T, SizeMin>::doReserve
|
||||
// Preserve addressed size
|
||||
const label currLen = List<T>::size();
|
||||
|
||||
// Consistent allocated sizing
|
||||
List<T>::setAddressableSize(capacity_);
|
||||
|
||||
// Increase capacity (eg, doubling)
|
||||
capacity_ =
|
||||
Foam::ListPolicy::reserve_size<SizeMin, 2>(len, capacity_);
|
||||
@ -103,8 +108,10 @@ inline void Foam::DynamicField<T, SizeMin>::doReserve
|
||||
}
|
||||
else
|
||||
{
|
||||
List<T>::resize(capacity_);
|
||||
List<T>::resize_copy(currLen, capacity_);
|
||||
}
|
||||
|
||||
capacity_ = List<T>::size();
|
||||
List<T>::setAddressableSize(currLen);
|
||||
}
|
||||
}
|
||||
@ -246,7 +253,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
|
||||
Field<T>(std::move(static_cast<List<T>&>(content))),
|
||||
capacity_(content.capacity())
|
||||
{
|
||||
content.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
|
||||
content.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
|
||||
|
||||
@ -259,7 +266,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
|
||||
Field<T>(std::move(static_cast<List<T>&>(content))),
|
||||
capacity_(content.capacity())
|
||||
{
|
||||
content.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
|
||||
content.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
|
||||
|
||||
@ -273,7 +280,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
|
||||
Field<T>(std::move(static_cast<List<T>&>(content))),
|
||||
capacity_(content.capacity())
|
||||
{
|
||||
content.setCapacity_unsafe(0); // Same as shrink_unsafe() but noexcept
|
||||
content.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
|
||||
|
||||
@ -292,7 +299,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
|
||||
{
|
||||
Field<T>::transfer(static_cast<List<T>&>(content));
|
||||
capacity_ = content.capacity();
|
||||
content.setCapacity_unsafe(0);
|
||||
content.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -317,7 +324,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField
|
||||
{
|
||||
Field<T>::transfer(static_cast<List<T>&>(content));
|
||||
capacity_ = content.capacity();
|
||||
content.setCapacity_unsafe(0);
|
||||
content.setCapacity_unsafe(0); // All contents moved
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -462,8 +469,15 @@ inline void Foam::DynamicField<T, SizeMin>::reserve_exact
|
||||
// Preserve addressed size
|
||||
const label currLen = List<T>::size();
|
||||
|
||||
capacity_ = len;
|
||||
List<T>::resize(capacity_);
|
||||
// Consistent allocated sizing
|
||||
List<T>::setAddressableSize(capacity_);
|
||||
|
||||
// if (!nocopy)
|
||||
{
|
||||
List<T>::resize_copy(currLen, len);
|
||||
}
|
||||
|
||||
capacity_ = List<T>::size();
|
||||
List<T>::setAddressableSize(currLen);
|
||||
}
|
||||
}
|
||||
@ -551,18 +565,6 @@ inline void Foam::DynamicField<T, SizeMin>::shrink_to_fit()
|
||||
}
|
||||
|
||||
|
||||
template<class T, int SizeMin>
|
||||
inline void Foam::DynamicField<T, SizeMin>::shrink_unsafe()
|
||||
{
|
||||
if (List<T>::empty())
|
||||
{
|
||||
// Delete storage if empty
|
||||
List<T>::clear();
|
||||
}
|
||||
capacity_ = List<T>::size();
|
||||
}
|
||||
|
||||
|
||||
template<class T, int SizeMin>
|
||||
inline void
|
||||
Foam::DynamicField<T, SizeMin>::swap(List<T>& list)
|
||||
|
||||
@ -37,6 +37,7 @@ License
|
||||
#include "IOobject.H"
|
||||
#include "dynamicCode.H"
|
||||
#include "simpleObjectRegistry.H"
|
||||
#include "MemoryPool.H"
|
||||
#include "sigFpe.H"
|
||||
#include "sigInt.H"
|
||||
#include "sigQuit.H"
|
||||
@ -2182,6 +2183,9 @@ void Foam::argList::parse
|
||||
sigQuit::set(bannerEnabled());
|
||||
sigSegv::set(bannerEnabled());
|
||||
|
||||
// Create memory pool (if any) after MPI has been setup
|
||||
MemoryPool::create(bannerEnabled());
|
||||
|
||||
if (UPstream::master() && bannerEnabled())
|
||||
{
|
||||
Info<< "fileModificationChecking : "
|
||||
|
||||
116
src/OpenFOAM/memory/pool/MemoryPool.H
Normal file
116
src/OpenFOAM/memory/pool/MemoryPool.H
Normal file
@ -0,0 +1,116 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM 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.
|
||||
|
||||
OpenFOAM 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 OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::MemoryPool
|
||||
|
||||
Description
|
||||
Optional memory management using a memory pool such as Umpire
|
||||
(https://github.com/LLNL/Umpire).
|
||||
|
||||
When compiled with Umpire, its use can be controlled by the
|
||||
\c FOAM_MEMORY_POOL environment variable, or the
|
||||
\c memory_pool Optimisation switch (etc/controlDict).
|
||||
|
||||
It currently looks for any of the following entries, in this order:
|
||||
- true - same as \em "host"
|
||||
- false/none - disabled.
|
||||
- \em "host" - uses host memory pool
|
||||
- \em "system" - same as \em "host"
|
||||
- \em "device" - uses device memory pool
|
||||
- \em "managed" - uses managed host/device memory pool
|
||||
.
|
||||
|
||||
The parameters "size=nn" and "incr=nn" (in MegaBytes) can be used
|
||||
to specify alternatives to the default sizing.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Foam_MemoryPool_H
|
||||
#define Foam_MemoryPool_H
|
||||
|
||||
#include <cstdint> // For size_t
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class MemoryPool Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class MemoryPool
|
||||
{
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Create a memory pool instance (if not already active).
|
||||
// Uses environment or etc/controlDict entry
|
||||
static bool create(bool verbose = false);
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
//- Remove the memory pool instance (currently does nothing)
|
||||
static void destroy(bool verbose = false);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- True if pool is active (ie, created and not suspended)
|
||||
static bool active() noexcept;
|
||||
|
||||
//- Suspend use of memory pool (for allocation).
|
||||
// \return previous suspend status
|
||||
static bool suspend() noexcept;
|
||||
|
||||
//- Resume use of memory pool (if previously active)
|
||||
static void resume() noexcept;
|
||||
|
||||
//- Test if given pointer belongs to the pool
|
||||
static bool is_pool(void *ptr);
|
||||
|
||||
//- Allocate from pool (if active).
|
||||
// \returns nullptr if the pool is not active
|
||||
static void* try_allocate(std::size_t nbytes);
|
||||
|
||||
//- Deallocate a pointer managed by the pool
|
||||
// \returns True if a nullptr (no-op) or when the pointer was
|
||||
// managed by the pool.
|
||||
static bool try_deallocate(void *ptr);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user