Notice: If you are member of any public project or group, please make sure that your GitLab username is not the same as the LRZ identifier/Kennung (see https://gitlab.lrz.de/profile/account). Please change your username if necessary. For more information see the section "Public projects / Öffentliche Projekte" at https://doku.lrz.de/display/PUBLIC/GitLab . Thank you!

Commit 18fedcd4 authored by Jens Petit's avatar Jens Petit

Extended critical section and added docu for CoW

parent bb97fdaa
......@@ -30,6 +30,12 @@ set(MODULE_SOURCES
add_library(${ELSA_MODULE_TARGET_NAME} ${MODULE_HEADERS} ${MODULE_SOURCES})
add_library(elsa::${ELSA_MODULE_NAME} ALIAS ${ELSA_MODULE_TARGET_NAME})
# use OpenMP is available
find_package(OpenMP REQUIRED)
if(OpenMP_CXX_FOUND)
target_link_libraries(${ELSA_MODULE_TARGET_NAME} PRIVATE OpenMP::OpenMP_CXX)
endif()
target_include_directories(${ELSA_MODULE_TARGET_NAME}
PUBLIC
$<INSTALL_INTERFACE:include/${ELSA_MODULE_NAME}>
......
......@@ -283,10 +283,12 @@ namespace elsa {
template <typename data_t>
void DataContainer<data_t>::detach()
{
if (_dataHandler.use_count() == 1)
return;
_dataHandler = _dataHandler->clone();
if (_dataHandler.use_count() != 1) {
#pragma omp barrier
#pragma omp single
_dataHandler = _dataHandler->clone();
}
return;
}
// ------------------------------------------
......
......@@ -23,6 +23,9 @@ namespace elsa
* This class provides a container for a signal that is stored in memory. This signal can
* be n-dimensional, and will be stored in memory in a linearized fashion. The information
* on how this linearization is performed is provided by an associated DataDescriptor.
*
* The class implements copy-on-write. Therefore any non-const functions should call the
* detach() function first to trigger the copy-on-write mechanism.
*/
template <typename data_t = real_t>
class DataContainer {
......@@ -88,7 +91,6 @@ namespace elsa
*/
DataContainer<data_t>& operator=(DataContainer<data_t>&& other);
/// return the current DataDescriptor
const DataDescriptor& getDataDescriptor() const;
......@@ -191,8 +193,6 @@ namespace elsa
/// comparison with another DataContainer
bool operator!=(const DataContainer<data_t>& other) const;
/// creates the deep copy for the copy-on-write mechanism
void detach();
private:
/// the current DataDescriptor
std::unique_ptr<DataDescriptor> _dataDescriptor;
......@@ -205,6 +205,9 @@ namespace elsa
/// private constructor accepting a DataDescriptor and a DataHandler
explicit DataContainer(const DataDescriptor& dataDescriptor, std::unique_ptr<DataHandler<data_t>> dataHandler);
/// creates the deep copy for the copy-on-write mechanism
void detach();
};
......
......@@ -402,8 +402,7 @@ SCENARIO("Testing the copy-on-write mechanism") {
dc.dot(dc2);
dc.l1Norm();
// TODO(Jens): this can't really be tested as the member is private - make test scenario friend?
THEN("the data handlers are the same") {
THEN("the data should still be the same") {
REQUIRE(dc3 == dc);
}
}
......
......@@ -64,8 +64,6 @@ namespace elsa
template <bool adjoint>
void BinaryMethod<data_t>::traverseVolume(const DataContainer<data_t>& vector, DataContainer<data_t>& result) const
{
result.detach();
index_t maxIterations{0};
if (adjoint) {
maxIterations = vector.getSize();
......
......@@ -65,7 +65,6 @@ namespace elsa
template <bool adjoint>
void JosephsMethod<data_t>::traverseVolume(const DataContainer<data_t>& vector, DataContainer<data_t>& result) const
{
result.detach();
if(adjoint) result = 0;
const index_t sizeOfRange = _rangeDescriptor->getNumberOfCoefficients();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment