Skip to content

Commit

Permalink
Respect the new SUBPAR_NO_OPENMP macro when choosing the lock method.
Browse files Browse the repository at this point in the history
Also avoid include's of the standard headers inside our own namespace.
  • Loading branch information
LTLA committed Aug 26, 2024
1 parent f69aaf5 commit 693c3c5
Showing 1 changed file with 12 additions and 13 deletions.
25 changes: 12 additions & 13 deletions include/tatami_hdf5/serialize.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,55 +6,54 @@
* @brief Default locking for serial access.
*/

namespace tatami_hdf5 {

/**
* @cond
*/
#ifndef TATAMI_HDF5_PARALLEL_LOCK
#ifndef _OPENMP
#if !defined(_OPENMP) || defined(SUBPAR_NO_OPENMP)
#include <thread>
#include <mutex>

namespace tatami_hdf5 {
inline auto& get_default_hdf5_lock() {
static std::mutex hdf5_lock;
return hdf5_lock;
}
}
#endif
#endif
/**
* @endcond
*/

namespace tatami_hdf5 {

/**
* Serialize a function's execution to avoid simultaneous calls to the (non-thread-safe) HDF5 library.
* Serialize a function's execution to avoid simultaneous calls to the (non-thread-safe) HDF5 library within `tatami::parallelize()` calls.
*
* If the `TATAMI_HDF5_PARALLEL_LOCK` macro is defined, it should be a function-like macro that accepts `f` and executes it in a serial section.
* If `TATAMI_CUSTOM_PARALLEL` or `SUBPAR_CUSTOM_PARALLEL` is defined, the user is expected to define a `TATAMI_HDF5_PARALLEL_LOCK` macro.
* The latter should be a function-like macro that accepts `f` and executes it in a serial section that is appropriate to the custom parallelization scheme of the former.
*
* If OpenMP is available, serialization is achieved by running `f` inside OpenMP critical regions named `"hdf5"`.
* Otherwise, if OpenMP is available and `SUBPAR_NO_OPENMP` is not defined, it is assumed that `tatami::parallelize()` will use OpenMP.
* In this case, serialization is achieved by running `f` inside OpenMP critical regions named `"hdf5"`.
*
* Otherwise, we use a mutex from the standard `<thread>` library to guard the execution of `f`.
* Otherwise, we use a mutex from the standard `<mutex>` library to guard the execution of `f`.
*
* @param f Function to be run in a serial section.
* This accepts no arguments and returns no outputs.
*
*/
template<class Function_>
void serialize(Function_ f) {
#ifdef TATAMI_HDF5_PARALLEL_LOCK
TATAMI_HDF5_PARALLEL_LOCK(f);
#else
#ifdef _OPENMP
#elif defined(_OPENMP) && !defined(SUBPAR_NO_OPENMP)
#pragma omp critical(hdf5)
{
f();
}
#else
static std::mutex hdf5_lock;
std::lock_guard<std::mutex> thing(get_hdf5_lock());
f();
#endif
#endif
}

}
Expand Down

0 comments on commit 693c3c5

Please sign in to comment.