diff --git a/pub/CMakeLists.txt b/pub/CMakeLists.txt index a992b214f081b8a6ba4e2b6e456eadf71bd6de57..3bde863310724d3440af5b0d24aa23d37fcbceaf 100644 --- a/pub/CMakeLists.txt +++ b/pub/CMakeLists.txt @@ -19,22 +19,9 @@ enable_testing() #option(FRIDA_MAN "Build a user manual" OFF) #option(BUILD_DEBIAN "Build a debian package" OFF) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g -pedantic -Wall -Wno-sign-compare -Wno-unused-result -Wno-parentheses -Werror") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g -pedantic -Wall -Wno-sign-compare -Wno-unused-result -Wno-parentheses -Wno-unknown-pragmas -Werror") # to use C99 _Complex, add -fext-numeric-literals to CXX_FLAGS -option (openmp "Enable multithreading with OpenMP" ON) -if (openmp) - find_package (OpenMP) - if (OPENMP_FOUND) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - endif() - message( STATUS "OpenMP: on" ) -else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas") - message( STATUS "OpenMP: off" ) -endif() - find_package(Boost REQUIRED) # used header-only modules: format algorithm find_package(BISON REQUIRED) find_package(FLEX REQUIRED) diff --git a/pub/lib/fit.cpp b/pub/lib/fit.cpp index 5c5ff64923687d50fafa966fffc5fcbf202029fd..42f87cdd67cf40758fda16a961e1f99efffaad97 100644 --- a/pub/lib/fit.cpp +++ b/pub/lib/fit.cpp @@ -9,9 +9,9 @@ #include "defs.hpp" +#include <functional> #include <thread> #include <boost/format.hpp> -#include <omp.h> #include <lmmin.h> #include "../readplus/ask.hpp" @@ -32,6 +32,26 @@ namespace NCurveFit { void fit_global( POlc fc, ROld fd, int k, const lm_control_struct& control ); } +void conditionally_parallel_for( + bool condition, int niter, + const std::function<void(int)>& exec, const std::function<void(int)>& report ) +{ + if ( condition ) { + vector<std::thread> workers; + for ( int i=0; i<niter; ++i ) { + workers.push_back( std::thread(exec, i) ); + } + for ( int i=0; i<niter; ++i ) { + workers[i].join(); + report(i); + } + } else { + for ( int i=0; i<niter; ++i ) { + exec(i); + report(i); + } + } +} //************************************************************************************************** //* Fit tuning parameters @@ -212,7 +232,7 @@ string NCurveFit::fit_one_spec( POlc fc, ROld fd, int k, int j, const lm_control // Levenberg-Marquardt routine from library lmfit: - data.timeout = time(nullptr) + omp_get_num_threads()*maxtime; + data.timeout = time(nullptr) + std::thread::hardware_concurrency()*maxtime; lm_status_struct status; lmmin( npfree, &(Par[0]), nd, &data, fit_evaluate, &control, &status ); @@ -304,14 +324,15 @@ static void fit_evaluate_glo( const double* par, int m_dat, const void *data, throw S("inconsistent number of free parameters"); bool want_error = wt==COlc::_VAR || wt==COlc::_VARC; -#pragma omp parallel for // if ( !NCurveFit::verbosity ) - for( int jj=0; jj<mydata->J2J.size(); ++jj ) { - compute_residues( - fvec, mydata->Offset[jj], mydata->J2J[jj], fd->VS(mydata->J2J[jj]), - fc->eval_curve( fd->VS(mydata->J2J[jj])->x, mydata->k, mydata->J2J[jj], - want_error ), - wt ); - } + conditionally_parallel_for ( + !NCurveFit::verbosity, mydata->J2J.size(), + [&](int jj) -> void { + compute_residues( + fvec, mydata->Offset[jj], mydata->J2J[jj], fd->VS(mydata->J2J[jj]), + fc->eval_curve( fd->VS(mydata->J2J[jj])->x, mydata->k, mydata->J2J[jj], + want_error ), + wt ); }, + [&](int jj) -> void {} ); } catch ( string& s ) { cout << "\n" << s << "\n"; *userbreak = -1; @@ -504,16 +525,12 @@ void NCurveFit::fit( bool _allow_slow_conv ) if ( !fc->VC(j)->frozen ) J.push_back( j ); vector<string> out(J.size(), ""); - vector<std::thread> workers; - for ( int jj=0; jj<J.size(); ++jj ) { - workers.push_back( std::thread([&](int _jj) -> void { - out[_jj] = fit_one_spec( fc, fd, fiter.k(), J[_jj], control ) + - "\n"; }, jj ) ); - } - for ( int jj=0; jj<J.size(); ++jj ) { - workers[jj].join(); - cout << out[jj]; - } + conditionally_parallel_for( + !NCurveFit::verbosity, J.size(), + [&](int _jj) -> void { + out[_jj] = fit_one_spec( fc, fd, fiter.k(), J[_jj], control ) + "\n"; }, + [&](int _jj) -> void { + cout << out[_jj]; } ); } // fit mode } // k }