\(\newcommand{\W}[1]{ \; #1 \; }\) \(\newcommand{\R}[1]{ {\rm #1} }\) \(\newcommand{\B}[1]{ {\bf #1} }\) \(\newcommand{\D}[2]{ \frac{\partial #1}{\partial #2} }\) \(\newcommand{\DD}[3]{ \frac{\partial^2 #1}{\partial #2 \partial #3} }\) \(\newcommand{\Dpow}[2]{ \frac{\partial^{#1}}{\partial {#2}^{#1}} }\) \(\newcommand{\dpow}[2]{ \frac{ {\rm d}^{#1}}{{\rm d}\, {#2}^{#1}} }\)
multi_newton_takedown¶
View page sourceTake Down Multi-threaded Newton Method¶
Syntax¶
ok =
harmonic_takedown
( xout )
Purpose¶
This routine does the takedown for splitting the Newton method into sub-intervals.
Thread¶
It is assumed that this function is called by thread zero, and all the other threads have completed their work and are blocked (waiting).
xout¶
See multi_newton_run .
Source¶
namespace {
bool multi_newton_takedown(vector<double>& xout)
{ // number of threads in the calculation
size_t num_threads = std::max(num_threads_, size_t(1));
// remove duplicates and points that are not solutions
xout.resize(0);
bool ok = true;
ok &= thread_alloc::thread_num() == 0;
// initialize as more that sub_length_ / 2 from any possible solution
double xlast = - sub_length_;
for(size_t thread_num = 0; thread_num < num_threads; thread_num++)
{ vector<double>& x = work_all_[thread_num]->x;
size_t i;
for(i = 0; i < x.size(); i++)
{ // check for case where this point is lower limit for this
// thread and upper limit for previous thread
if( fabs(x[i] - xlast) >= sub_length_ )
{ xout.push_back( x[i] );
xlast = x[i];
}
else
{ double fcur, flast, df;
fun_(x[i], fcur, df);
fun_(xlast, flast, df);
if( fabs(fcur) < fabs(flast) )
{ xout[ xout.size() - 1] = x[i];
xlast = x[i];
}
}
}
// check that this thread was ok with the work it did
ok &= work_all_[thread_num]->ok;
}
// go down so free memory for other threads before memory for master
size_t thread_num = num_threads;
while(thread_num--)
{
# if USE_THREAD_ALLOC_FOR_WORK_ALL
// call the destructor for vector destructor
work_all_[thread_num]->x.~vector<double>();
// delete the raw memory allocation
void* v_ptr = static_cast<void*>( work_all_[thread_num] );
thread_alloc::return_memory( v_ptr );
# else
delete work_all_[thread_num];
# endif
// Note that xout corresponds to memroy that is inuse by master
// (so we can only chech have freed all their memory).
if( thread_num > 0 )
{ // check that there is no longer any memory inuse by this thread
ok &= thread_alloc::inuse(thread_num) == 0;
// return all memory being held for future use by this thread
thread_alloc::free_available(thread_num);
}
}
// now we are done with the work_all_ vector so free its memory
// (because it is a static variable)
work_all_.clear();
return ok;
}
}