Skip to content

Commit

Permalink
first parallel optimizer
Browse files Browse the repository at this point in the history
  • Loading branch information
schalkdaniel committed Feb 28, 2019
1 parent bdb9504 commit 141b8d5
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 7 deletions.
10 changes: 8 additions & 2 deletions src/Makevars
@@ -1,6 +1,12 @@
PKG_CFLAGS = $(SHLIB_OPENMP_CFLAGS)
PKG_LIBS = $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) $(SHLIB_OPENMP_CXXFLAGS)
CXX_STD = CXX11
PKG_LIBS = $(SHLIB_OPENMP_CFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)

PKG_CXXFLAGS=$(SHLIB_OPENMP_CXXFLAGS)

SHLIB_OPENMP_CFLAGS=$(SHLIB_OPENMP_CFLAGS)
SHLIB_OPENMP_CXXFLAGS=$(SHLIB_OPENMP_CXXFLAGS)
SHLIB_OPENMP_FCFLAGS=$(SHLIB_OPENMP_FCFLAGS)
SHLIB_OPENMP_FFLAGS=$(SHLIB_OPENMP_FFLAGS)

# strip debug symbols for smaller Linux binaries
strippedLib: $(SHLIB)
Expand Down
10 changes: 8 additions & 2 deletions src/Makevars.win
@@ -1,3 +1,9 @@
PKG_CFLAGS = $(SHLIB_OPENMP_CFLAGS)
PKG_LIBS = $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) $(SHLIB_OPENMP_CXXFLAGS)
CXX_STD = CXX11
PKG_LIBS = $(SHLIB_OPENMP_CFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)

PKG_CXXFLAGS=$(SHLIB_OPENMP_CXXFLAGS)

SHLIB_OPENMP_CFLAGS=$(SHLIB_OPENMP_CFLAGS)
SHLIB_OPENMP_CXXFLAGS=$(SHLIB_OPENMP_CXXFLAGS)
SHLIB_OPENMP_FCFLAGS=$(SHLIB_OPENMP_FCFLAGS)
SHLIB_OPENMP_FFLAGS=$(SHLIB_OPENMP_FFLAGS)
10 changes: 9 additions & 1 deletion src/compboost_modules.cpp
Expand Up @@ -2097,7 +2097,14 @@ class OptimizerWrapper
class OptimizerCoordinateDescent : public OptimizerWrapper
{
public:
OptimizerCoordinateDescent () { sh_ptr_optimizer = std::make_shared<optimizer::OptimizerCoordinateDescent>(); }

OptimizerCoordinateDescent () {
sh_ptr_optimizer = std::make_shared<optimizer::OptimizerCoordinateDescent>();
}

OptimizerCoordinateDescent (unsigned int num_threads) {
sh_ptr_optimizer = std::make_shared<optimizer::OptimizerCoordinateDescent>(num_threads);
}
};

//' Coordinate Descent with line search
Expand Down Expand Up @@ -2147,6 +2154,7 @@ RCPP_MODULE(optimizer_module)
class_<OptimizerCoordinateDescent> ("OptimizerCoordinateDescent")
.derives<OptimizerWrapper> ("Optimizer")
.constructor ()
.constructor <unsigned int> ()
;

class_<OptimizerCoordinateDescentLineSearch> ("OptimizerCoordinateDescentLineSearch")
Expand Down
66 changes: 65 additions & 1 deletion src/optimizer.cpp
Expand Up @@ -43,9 +43,72 @@ OptimizerCoordinateDescent::OptimizerCoordinateDescent () {
step_sizes.assign(1, 1.0);
}

OptimizerCoordinateDescent::OptimizerCoordinateDescent (const unsigned int& num_threads)
: num_threads (num_threads) {
// Initialize step size vector as scalar:
step_sizes.assign(1, 1.0);
}

std::shared_ptr<blearner::Baselearner> OptimizerCoordinateDescent::findBestBaselearner (const std::string& iteration_id,
std::shared_ptr<response::Response> sh_ptr_response, const blearner_factory_map& my_blearner_factory_map) const
{
std::map<double, std::shared_ptr<blearner::Baselearner>> best_blearner_map;

#pragma omp parallel num_threads(num_threads) default(none) shared(iteration_id, sh_ptr_response, my_blearner_factory_map, best_blearner_map)
{
// private per core:
double ssq_best = std::numeric_limits<double>::infinity();
double ssq_temp;
std::shared_ptr<blearner::Baselearner> blearner_temp;
std::shared_ptr<blearner::Baselearner> blearner_best;

#pragma omp for
for (unsigned int i = 0; i < my_blearner_factory_map.size(); i++) {

// increment iterator to "index map elements by index" (https://stackoverflow.com/questions/8848870/use-openmp-in-iterating-over-a-map):
auto it_factory_pair = my_blearner_factory_map.begin();
std::advance(it_factory_pair, i);

// Paste string identifier for new base-learner:
std::string id = "(" + iteration_id + ") " + it_factory_pair->second->getBaselearnerType();

// Create new base-learner out of the actual factory (just the
// pointer is overwritten):
blearner_temp = it_factory_pair->second->createBaselearner(id);
blearner_temp->train(sh_ptr_response->getPseudoResiduals());
ssq_temp = helper::calculateSumOfSquaredError(sh_ptr_response->getPseudoResiduals(), blearner_temp->predict());

// Check if SSE of new temporary base-learner is smaller then SSE of the best
// base-learner. If so, assign the temporary base-learner with the best
// base-learner (This is always triggered within the first iteration since
// ssq_best is declared as infinity):
if (ssq_temp < ssq_best) {
ssq_best = ssq_temp;
// // Deep copy since the temporary base-learner is deleted every time which
// // will also deletes the data for the best base-learner if we don't copy
// // the whole data of the object:
// blearner_best = blearner_temp->clone();
blearner_best = blearner_temp;
}
}

#pragma omp critical
{
// return best blearner per core with corresponding ssq to master:
best_blearner_map[ssq_best] = blearner_best;
}
}
if (best_blearner_map.size() == 1) {
return best_blearner_map.begin()->second;
} else {
auto it = min_element(best_blearner_map.begin(), best_blearner_map.end(),
[](decltype(best_blearner_map)::value_type& l, decltype(best_blearner_map)::value_type& r) -> bool { return l.first < r.first; });
return it->second;
}

/* ****************************************************************************************
* OLD SEQUENTIAL LOOP:
*
double ssq_temp;
double ssq_best = std::numeric_limits<double>::infinity();
Expand Down Expand Up @@ -76,7 +139,8 @@ std::shared_ptr<blearner::Baselearner> OptimizerCoordinateDescent::findBestBasel
blearner_best = blearner_temp;
}
}
return blearner_best;
**************************************************************************************** */
// return blearner_best;
}

void OptimizerCoordinateDescent::calculateStepSize (std::shared_ptr<loss::Loss> sh_ptr_loss, std::shared_ptr<response::Response> sh_ptr_response,
Expand Down
9 changes: 8 additions & 1 deletion src/optimizer.h
Expand Up @@ -34,6 +34,10 @@
#include "line_search.h"
#include "helper.h"

#ifdef _OPENMP
#include <omp.h>
#endif

namespace optimizer {

// -------------------------------------------------------------------------- //
Expand Down Expand Up @@ -70,8 +74,11 @@ class Optimizer
class OptimizerCoordinateDescent : public Optimizer
{
public:
// No special initialization necessary:

unsigned int num_threads = 1;

OptimizerCoordinateDescent ();
OptimizerCoordinateDescent (const unsigned int&);

std::shared_ptr<blearner::Baselearner> findBestBaselearner (const std::string&, std::shared_ptr<response::Response>,
const blearner_factory_map&) const;
Expand Down

0 comments on commit 141b8d5

Please sign in to comment.