Skip to content
Snippets Groups Projects
Commit 9ebd889a authored by Wuttke, Joachim's avatar Wuttke, Joachim
Browse files

replace OpenMP by C++ threads;

this introduces an OS dependency (pthread) into lib/CmaeLists.txt.
parent 38962fff
No related branches found
No related tags found
No related merge requests found
...@@ -19,22 +19,9 @@ enable_testing() ...@@ -19,22 +19,9 @@ enable_testing()
#option(FRIDA_MAN "Build a user manual" OFF) #option(FRIDA_MAN "Build a user manual" OFF)
#option(BUILD_DEBIAN "Build a debian package" 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 # 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(Boost REQUIRED) # used header-only modules: format algorithm
find_package(BISON REQUIRED) find_package(BISON REQUIRED)
find_package(FLEX REQUIRED) find_package(FLEX REQUIRED)
......
...@@ -9,9 +9,9 @@ ...@@ -9,9 +9,9 @@
#include "defs.hpp" #include "defs.hpp"
#include <functional>
#include <thread> #include <thread>
#include <boost/format.hpp> #include <boost/format.hpp>
#include <omp.h>
#include <lmmin.h> #include <lmmin.h>
#include "../readplus/ask.hpp" #include "../readplus/ask.hpp"
...@@ -32,6 +32,26 @@ namespace NCurveFit { ...@@ -32,6 +32,26 @@ namespace NCurveFit {
void fit_global( POlc fc, ROld fd, int k, const lm_control_struct& control ); 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 //* Fit tuning parameters
...@@ -212,7 +232,7 @@ string NCurveFit::fit_one_spec( POlc fc, ROld fd, int k, int j, const lm_control ...@@ -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: // 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; lm_status_struct status;
lmmin( npfree, &(Par[0]), nd, &data, fit_evaluate, &control, &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, ...@@ -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"); throw S("inconsistent number of free parameters");
bool want_error = wt==COlc::_VAR || wt==COlc::_VARC; bool want_error = wt==COlc::_VAR || wt==COlc::_VARC;
#pragma omp parallel for // if ( !NCurveFit::verbosity ) conditionally_parallel_for (
for( int jj=0; jj<mydata->J2J.size(); ++jj ) { !NCurveFit::verbosity, mydata->J2J.size(),
compute_residues( [&](int jj) -> void {
fvec, mydata->Offset[jj], mydata->J2J[jj], fd->VS(mydata->J2J[jj]), compute_residues(
fc->eval_curve( fd->VS(mydata->J2J[jj])->x, mydata->k, mydata->J2J[jj], fvec, mydata->Offset[jj], mydata->J2J[jj], fd->VS(mydata->J2J[jj]),
want_error ), fc->eval_curve( fd->VS(mydata->J2J[jj])->x, mydata->k, mydata->J2J[jj],
wt ); want_error ),
} wt ); },
[&](int jj) -> void {} );
} catch ( string& s ) { } catch ( string& s ) {
cout << "\n" << s << "\n"; cout << "\n" << s << "\n";
*userbreak = -1; *userbreak = -1;
...@@ -504,16 +525,12 @@ void NCurveFit::fit( bool _allow_slow_conv ) ...@@ -504,16 +525,12 @@ void NCurveFit::fit( bool _allow_slow_conv )
if ( !fc->VC(j)->frozen ) if ( !fc->VC(j)->frozen )
J.push_back( j ); J.push_back( j );
vector<string> out(J.size(), ""); vector<string> out(J.size(), "");
vector<std::thread> workers; conditionally_parallel_for(
for ( int jj=0; jj<J.size(); ++jj ) { !NCurveFit::verbosity, J.size(),
workers.push_back( std::thread([&](int _jj) -> void { [&](int _jj) -> void {
out[_jj] = fit_one_spec( fc, fd, fiter.k(), J[_jj], control ) + out[_jj] = fit_one_spec( fc, fd, fiter.k(), J[_jj], control ) + "\n"; },
"\n"; }, jj ) ); [&](int _jj) -> void {
} cout << out[_jj]; } );
for ( int jj=0; jj<J.size(); ++jj ) {
workers[jj].join();
cout << out[jj];
}
} // fit mode } // fit mode
} // k } // k
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment