Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: Add ElastixFilter.UpdateInParallel GoogleTest unit test #393

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions Common/xout/xoutbase.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ xoutbase & xoutbase::operator[](const char * cellname)
void
xoutbase::WriteBufferedData(void)
{
const LockGuardType mutexLock(GetRecursiveMutex());

/** Update the target c-streams. */
for (const auto & cell : m_CTargetCells)
{
Expand All @@ -78,6 +80,8 @@ xoutbase::WriteBufferedData(void)
int
xoutbase::AddTargetCell(const char * name, std::ostream * cell)
{
const LockGuardType mutexLock(GetRecursiveMutex());

int returndummy = 1;

if (this->m_XTargetCells.count(name))
Expand All @@ -103,6 +107,8 @@ xoutbase::AddTargetCell(const char * name, std::ostream * cell)
int
xoutbase::AddTargetCell(const char * name, Self * cell)
{
const LockGuardType mutexLock(GetRecursiveMutex());

int returndummy = 1;

if (this->m_CTargetCells.count(name))
Expand All @@ -128,6 +134,8 @@ xoutbase::AddTargetCell(const char * name, Self * cell)
int
xoutbase::RemoveTargetCell(const char * name)
{
const LockGuardType mutexLock(GetRecursiveMutex());

int returndummy = 1;

if (this->m_XTargetCells.erase(name) > 0)
Expand All @@ -152,6 +160,8 @@ xoutbase::RemoveTargetCell(const char * name)
void
xoutbase::SetTargetCells(const CStreamMapType & cellmap)
{
const LockGuardType mutexLock(GetRecursiveMutex());

this->m_CTargetCells = cellmap;

} // end SetTargetCells
Expand All @@ -164,6 +174,7 @@ xoutbase::SetTargetCells(const CStreamMapType & cellmap)
void
xoutbase::SetTargetCells(const XStreamMapType & cellmap)
{
const LockGuardType mutexLock(GetRecursiveMutex());
this->m_XTargetCells = cellmap;

} // end SetTargetCells
Expand All @@ -176,7 +187,8 @@ xoutbase::SetTargetCells(const XStreamMapType & cellmap)
int
xoutbase::AddOutput(const char * name, std::ostream * output)
{
int returndummy = 1;
const LockGuardType mutexLock(GetRecursiveMutex());
int returndummy = 1;

if (this->m_XOutputs.count(name))
{
Expand All @@ -200,7 +212,8 @@ xoutbase::AddOutput(const char * name, std::ostream * output)
int
xoutbase::AddOutput(const char * name, Self * output)
{
int returndummy = 1;
const LockGuardType mutexLock(GetRecursiveMutex());
int returndummy = 1;

if (this->m_COutputs.count(name))
{
Expand All @@ -224,7 +237,8 @@ xoutbase::AddOutput(const char * name, Self * output)
int
xoutbase::RemoveOutput(const char * name)
{
int returndummy = 1;
const LockGuardType mutexLock(GetRecursiveMutex());
int returndummy = 1;

if (this->m_XOutputs.count(name))
{
Expand All @@ -250,6 +264,7 @@ xoutbase::RemoveOutput(const char * name)
void
xoutbase::SetOutputs(const CStreamMapType & outputmap)
{
const LockGuardType mutexLock(GetRecursiveMutex());
this->m_COutputs = outputmap;

} // end SetOutputs
Expand All @@ -262,6 +277,7 @@ xoutbase::SetOutputs(const CStreamMapType & outputmap)
void
xoutbase::SetOutputs(const XStreamMapType & outputmap)
{
const LockGuardType mutexLock(GetRecursiveMutex());
this->m_XOutputs = outputmap;

} // end SetOutputs
Expand Down Expand Up @@ -289,4 +305,12 @@ xoutbase::GetCOutputs(void)

} // end GetOutputs


std::recursive_mutex &
xoutbase::GetRecursiveMutex()
{
static std::recursive_mutex mutex;
return mutex;
}

} // end namespace xoutlibrary
8 changes: 8 additions & 0 deletions Common/xout/xoutbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <iostream>
#include <ostream>
#include <map>
#include <mutex>
#include <string>

namespace xoutlibrary
Expand Down Expand Up @@ -147,6 +148,11 @@ class xoutbase
GetXOutputs(void);

protected:
using LockGuardType = std::lock_guard<std::recursive_mutex>;

static std::recursive_mutex &
GetRecursiveMutex();

/** Default-constructor. Only to be used by its derived classes. */
xoutbase() = default;

Expand All @@ -164,6 +170,8 @@ class xoutbase
Self &
SendToTargets(const T & _arg)
{
const LockGuardType mutexLock(GetRecursiveMutex());

/** Send input to the target c-streams. */
for (const auto & cell : m_CTargetCells)
{
Expand Down
2 changes: 2 additions & 0 deletions Common/xout/xoutcell.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ xoutcell::xoutcell()
void
xoutcell::WriteBufferedData(void)
{
const LockGuardType mutexLock(GetRecursiveMutex());

const std::string strbuf = this->m_InternalBuffer.str();

/** Send the string to the outputs */
Expand Down
20 changes: 20 additions & 0 deletions Common/xout/xoutrow.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ using namespace std;
void
xoutrow::WriteBufferedData(void)
{
const LockGuardType mutexLock(GetRecursiveMutex());

/** Write the cell-data to the outputs, separated by tabs. */
auto xit = this->m_XTargetCells.begin();
auto tmpIt = xit;
Expand Down Expand Up @@ -65,6 +67,8 @@ xoutrow::WriteBufferedData(void)
int
xoutrow::AddTargetCell(const char * name)
{
const LockGuardType mutexLock(GetRecursiveMutex());

if (this->m_CellMap.count(name) == 0)
{
/** A new cell (type xoutcell) is created. */
Expand Down Expand Up @@ -98,6 +102,8 @@ xoutrow::AddTargetCell(const char * name)
int
xoutrow::RemoveTargetCell(const char * name)
{
const LockGuardType mutexLock(GetRecursiveMutex());

int returndummy = 1;

if (this->m_XTargetCells.erase(name) > 0)
Expand All @@ -122,6 +128,8 @@ xoutrow::RemoveTargetCell(const char * name)
void
xoutrow::SetTargetCells(const XStreamMapType & cellmap)
{
const LockGuardType mutexLock(GetRecursiveMutex());

/** Clean the this->m_CellMap (cells that are created using the
* AddTarget(const char *) method.
*/
Expand All @@ -143,6 +151,8 @@ xoutrow::SetTargetCells(const XStreamMapType & cellmap)
int
xoutrow::AddOutput(const char * name, std::ostream * output)
{
const LockGuardType mutexLock(GetRecursiveMutex());

int returndummy = 0;

/** Set the output in all cells. */
Expand All @@ -165,6 +175,8 @@ xoutrow::AddOutput(const char * name, std::ostream * output)
int
xoutrow::AddOutput(const char * name, Superclass * output)
{
const LockGuardType mutexLock(GetRecursiveMutex());

int returndummy = 0;

/** Set the output in all cells. */
Expand All @@ -187,6 +199,8 @@ xoutrow::AddOutput(const char * name, Superclass * output)
int
xoutrow::RemoveOutput(const char * name)
{
const LockGuardType mutexLock(GetRecursiveMutex());

int returndummy = 0;
/** Set the output in all cells. */
for (const auto & cell : this->m_XTargetCells)
Expand All @@ -208,6 +222,8 @@ xoutrow::RemoveOutput(const char * name)
void
xoutrow::SetOutputs(const CStreamMapType & outputmap)
{
const LockGuardType mutexLock(GetRecursiveMutex());

/** Set the output in all cells. */
for (const auto & cell : this->m_XTargetCells)
{
Expand All @@ -227,6 +243,8 @@ xoutrow::SetOutputs(const CStreamMapType & outputmap)
void
xoutrow::SetOutputs(const XStreamMapType & outputmap)
{
const LockGuardType mutexLock(GetRecursiveMutex());

/** Set the output in all cells. */
for (const auto & cell : this->m_XTargetCells)
{
Expand All @@ -246,6 +264,8 @@ xoutrow::SetOutputs(const XStreamMapType & outputmap)
void
xoutrow::WriteHeaders(void)
{
const LockGuardType mutexLock(GetRecursiveMutex());

/** Copy '*this'. */
Self headerwriter;
headerwriter.SetTargetCells(this->m_XTargetCells);
Expand Down
44 changes: 44 additions & 0 deletions Core/Kernel/elxElastixMain.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
# include "itkOpenCLSetup.h"
#endif

#include <mutex>


namespace
{
/**
Expand Down Expand Up @@ -139,6 +142,47 @@ xoutManager::xoutManager(const std::string & logFileName, const bool setupLoggin
}
}


std::shared_ptr<const xoutManager>
xoutManager::GetSharedManager(const std::string & logFileName, const bool setupLogging, const bool setupCout)
{
const auto makeManagerPtrPair = [](const std::string & logFileName, const bool setupLogging, const bool setupCout) {
std::shared_ptr<const xoutManager> sharedPtr(new xoutManager(logFileName, setupLogging, setupCout));
std::weak_ptr<const xoutManager> weakPtr(sharedPtr);
return std::make_pair(sharedPtr, weakPtr);
};

// Note that the initialization of this static variable is thread-safe,
// as supported by C++11 "magic statics".
static auto managerPtrPair = makeManagerPtrPair(logFileName, setupLogging, setupCout);

const struct ResetGuard
{
std::shared_ptr<const xoutManager> & sharedPtr;
~ResetGuard() { sharedPtr.reset(); }
} resetGuard{ managerPtrPair.first };

const auto lockedSharedPtr = managerPtrPair.second.lock();

if (lockedSharedPtr == nullptr)
{
// Apply the "double-checked locking" design pattern.
static std::mutex managerMutex;
const std::lock_guard<std::mutex> lock(managerMutex);

const auto doubleCheckedLockedSharedPtr = managerPtrPair.second.lock();

if (doubleCheckedLockedSharedPtr == nullptr)
{
managerPtrPair = makeManagerPtrPair(logFileName, setupLogging, setupCout);
return managerPtrPair.second.lock();
}
return doubleCheckedLockedSharedPtr;
}
return lockedSharedPtr;
}


xoutManager::Guard::~Guard()
{
g_data = {};
Expand Down
3 changes: 3 additions & 0 deletions Core/Kernel/elxElastixMain.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ class xoutManager
/** This explicit constructor does set up the "xout" output streams. */
explicit xoutManager(const std::string & logfilename, const bool setupLogging, const bool setupCout);

static std::shared_ptr<const xoutManager>
GetSharedManager(const std::string & logFileName, const bool setupLogging, const bool setupCout);

/** The default-constructor only just constructs a manager object */
xoutManager() = default;

Expand Down
Loading