Commit 1dff35b5 authored by Paal Kvamme's avatar Paal Kvamme
Browse files

Add logging of OpenMP loops.

parent cf8bc462
......@@ -1650,7 +1650,7 @@ ZgyInternalBulk::_writeAlignedRegion(
std::vector<std::shared_ptr<const WriteBrickArgPack>> const_queue(worksize);
std::vector<std::shared_ptr<const WriteNowArgPack>> normal_queue(worksize);
MTGuard guard;
MTGuard guard("copy-in", -1);
#pragma omp parallel for if(enable_compress_mt() && worksize > 1)
for (std::int64_t ix = 0; ix < static_cast<std::int64_t>(worksize); ++ix) {
guard.run([&](){
......
......@@ -276,7 +276,7 @@ LocalFileLinux::xx_readv(const ReadList& requests, bool parallel_ok, bool immuta
const int threadcount = static_cast<int>
(std::min(requestcount,static_cast<std::int64_t>(omp_get_max_threads())));
MTGuard guard;
MTGuard guard("local-read", threadcount);
#pragma omp parallel num_threads(threadcount)
{
std::int64_t datasize = 0;
......
......@@ -117,7 +117,7 @@ FileParallelizer::xx_readv(
// Deliver the buffers that we cached to the caller.
const std::int64_t threadcount = std::min(std::min(requestcount, (std::int64_t)omp_get_max_threads()), _cputhreads);
MTGuard guard;
MTGuard guard("paralellizer", threadcount);
#pragma omp parallel for num_threads(threadcount)
for (std::int64_t ii = 0; ii < requestcount; ++ii) {
guard.run([&](){
......
......@@ -1254,7 +1254,7 @@ SeismicStoreFile::xx_readv(const ReadList& requests, bool parallel_ok, bool immu
static_cast<std::int64_t>(omp_get_max_threads())),
_config->_iothreads),
static_cast<std::int64_t>(1));
MTGuard guard;
MTGuard guard("cloud-read", threadcount);
//std::cerr << "Access seismic store (" << worksize << "): ";
#pragma omp parallel for num_threads(threadcount) schedule(dynamic,1)
for (std::int64_t ii=0; ii<worksize; ++ii) {
......@@ -1462,7 +1462,7 @@ SeismicStoreFile::do_write_many(
this->_dataset->info()->checkOnWrite(blocknum, std::min(size, blobsize));
const int blobcount = (size + blobsize - 1) / blobsize;
MTGuard guard;
MTGuard guard("cloud-write", blobcount);
#pragma omp parallel for num_threads(blobcount)
for (int ii = 0; ii < blobcount; ++ii) {
if (/*blocknum == 1 &&*/ ii == 0 && _logger(1, "")) {
......
......@@ -986,7 +986,7 @@ void createLodMT(const std::shared_ptr<DataBuffer>& result,
// 4 or 8 bytes. So, always slice the slowest dim.
if (input_slice_dim != -1 && input_slice_dim == output_slice_dim) {
SimpleTimerEx tt(timerMT);
MTGuard guard;
MTGuard guard("lod", -1);
#pragma omp parallel
{
std::int64_t slices_per_thread = (isize[input_slice_dim]-1) / omp_get_num_threads() + 1;
......
......@@ -15,6 +15,7 @@
#include "mtguard.h"
#include <iostream>
#include <sstream>
#include <omp.h>
namespace InternalZGY {
......@@ -22,9 +23,30 @@ namespace InternalZGY {
}
#endif
// Logically a member of class MTGuard, but Windows doesn't like that.
static thread_local std::atomic<int> MTGuard__debug_nesting(0);
MTGuard::MTGuard()
: _errors(0)
, _first_ex()
, _debug_name("anonymous")
, _debug_requested(0)
, _debug_reported(true) // set false to enable reporting
{
}
/**
* \brief Allow caller to provide more information for debugging and logging.
* \details
* It is ok to let the code permanently use this overloaded constructor,
* although it does add more clutter to the code.
*/
MTGuard::MTGuard(const std::string& name, int requested)
: _errors(0)
, _first_ex()
, _debug_name(name)
, _debug_requested(requested)
, _debug_reported(true) // set false to enable reporting
{
}
......@@ -67,11 +89,27 @@ MTGuard::failed() const {
*/
void
MTGuard::run(const std::function<void()>& fn) {
// Used to debug which OpenMT loops are run serially.
// Only works if the loop uses MTGuard. And even in that
// case your mileage may vary.
if (!_debug_reported && omp_get_thread_num() == 0) {
std::stringstream ss;
ss << "OpenMP \"" << _debug_name << "\""
<< " level " << MTGuard__debug_nesting + 1
<< " wants " << _debug_requested
<< " got " << omp_get_num_threads()
<< " threads.\n";
std::cerr << ss.str() << std::flush;
_debug_reported = true;
}
if (_errors.load() == 0) {
try {
MTGuard__debug_nesting++;
fn();
MTGuard__debug_nesting--;
}
catch (...) {
MTGuard__debug_nesting--;
fail();
}
}
......@@ -115,6 +153,21 @@ MTGuardWithProgress::MTGuardWithProgress(const progress_fn fn, std::int64_t tota
{
}
/**
* \brief Allow caller to provide more information for debugging and logging.
* \details
* It is ok to let the code permanently use this overloaded constructor,
* although it does add more clutter to the code.
*/
MTGuardWithProgress::MTGuardWithProgress(const progress_fn fn, std::int64_t total, const std::string& name, int requested)
: MTGuard(name, requested)
, _progress(fn)
, _total(total)
, _done(0)
, _last_done_by(-1)
{
}
/**
* Keep track of the progress i.e. how far we have come in the
* parallel for. User callbacks are invoked but only from thread
......@@ -138,7 +191,7 @@ MTGuardWithProgress::progress(std::int64_t steps)
if (!_progress(localdone, _total))
throw std::runtime_error("aborted");
}
catch (const std::exception& ex) {
catch (const std::exception&) {
fail();
}
}
......
......@@ -20,6 +20,7 @@
#include <atomic>
#include <functional>
#include <cstdint>
#include <string>
namespace InternalZGY {
#if 0
......@@ -55,9 +56,15 @@ class OPENZGY_TEST_API MTGuard
private:
std::atomic<int> _errors;
std::exception_ptr _first_ex;
std::string _debug_name;
int _debug_requested;
bool _debug_reported;
// cannot be inside class on Windows.
//static thread_local int _debug_nesting;
public:
explicit MTGuard();
MTGuard(const std::string& name, int requested);
~MTGuard();
MTGuard(const MTGuard&) = delete;
MTGuard& operator=(const MTGuard&) = delete;
......@@ -102,6 +109,7 @@ private:
public:
MTGuardWithProgress(const progress_fn progress, std::int64_t total);
MTGuardWithProgress(const progress_fn progress, std::int64_t total, const std::string& name, int requested);
MTGuardWithProgress(const MTGuardWithProgress&) = delete;
MTGuardWithProgress& operator=(const MTGuardWithProgress&) = delete;
void progress(std::int64_t steps = 1);
......
Supports Markdown
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