Skip to content
Snippets Groups Projects
Commit 15e2055d authored by Carlos Mastalli's avatar Carlos Mastalli
Browse files

Merge branch 'topic/omp' into 'devel'

Include the multithreading in shooting calcDiff

See merge request loco-3d/crocoddyl!218
parents 5d4c219c ba7dae2d
No related branches found
No related tags found
No related merge requests found
...@@ -40,7 +40,7 @@ SET(CXX_DISABLE_WERROR True) ...@@ -40,7 +40,7 @@ SET(CXX_DISABLE_WERROR True)
OPTION(ENABLE_VECTORIZATION "Enable vectorization and futhers processor-related optimizations" OFF) OPTION(ENABLE_VECTORIZATION "Enable vectorization and futhers processor-related optimizations" OFF)
OPTION(BUILD_PYTHON_INTERFACE "Build the python binding" ON) OPTION(BUILD_PYTHON_INTERFACE "Build the python binding" ON)
OPTION(BUILD_UNIT_TESTS "Build the unitary tests" ON) OPTION(BUILD_UNIT_TESTS "Build the unitary tests" ON)
OPTION(BUILD_BENCHMARK "Build the benchmark" OFF) OPTION(BUILD_BENCHMARK "Build the benchmark" ON)
IF(ENABLE_VECTORIZATION) IF(ENABLE_VECTORIZATION)
...@@ -57,6 +57,29 @@ ADD_OPTIONAL_DEPENDENCY("multicontact-api >= 1.1.0") ...@@ -57,6 +57,29 @@ ADD_OPTIONAL_DEPENDENCY("multicontact-api >= 1.1.0")
ADD_OPTIONAL_DEPENDENCY("quadprog") ADD_OPTIONAL_DEPENDENCY("quadprog")
ADD_OPTIONAL_DEPENDENCY("scipy") ADD_OPTIONAL_DEPENDENCY("scipy")
OPTION(BUILD_WITH_MULTITHREADS "Build the library with the OpenMP support (required OpenMP)" OFF)
IF(BUILD_WITH_MULTITHREADS)
SET(BUILD_WITH_NTHREADS "4" CACHE STRING "Number of threads")
string(REGEX MATCH "^[0-9]+$" BUILD_WITH_NTHREADS ${BUILD_WITH_NTHREADS})
IF(NOT BUILD_WITH_NTHREADS MATCHES "^[0-9]+$")
SET(BUILD_WITH_NTHREADS 4)
MESSAGE("Warning: the number of threads have to be an interger value, set to ${BUILD_WITH_NTHREADS}")
ENDIF()
ENDIF()
# Add OpenMP
if(BUILD_WITH_MULTITHREADS)
find_package(OpenMP)
ENDIF()
if(OPENMP_FOUND AND BUILD_WITH_MULTITHREADS)
SET(CMAKE_CXX_FLAGS "-fopenmp")
ADD_DEFINITIONS(-DWITH_MULTITHREADING)
ADD_DEFINITIONS(-DWITH_NTHREADS=${BUILD_WITH_NTHREADS})
LIST(APPEND CFLAGS_DEPENDENCIES "-DWITH_MULTITHREADING" "-DWITH_NTHREADS")
ENDIF()
SET(BOOST_REQUIERED_COMPONENTS filesystem serialization system) SET(BOOST_REQUIERED_COMPONENTS filesystem serialization system)
SET(BOOST_BUILD_COMPONENTS unit_test_framework) SET(BOOST_BUILD_COMPONENTS unit_test_framework)
SET(BOOST_OPTIONAL_COMPONENTS "") SET(BOOST_OPTIONAL_COMPONENTS "")
...@@ -97,4 +120,4 @@ IF(BUILD_BENCHMARK) ...@@ -97,4 +120,4 @@ IF(BUILD_BENCHMARK)
ENDIF(BUILD_BENCHMARK) ENDIF(BUILD_BENCHMARK)
SETUP_PROJECT_FINALIZE() SETUP_PROJECT_FINALIZE()
\ No newline at end of file
...@@ -40,17 +40,52 @@ int main() { ...@@ -40,17 +40,52 @@ int main() {
} }
// Solving the optimal control problem // Solving the optimal control problem
std::clock_t c_start, c_end; struct timespec start, finish;
double elapsed;
Eigen::ArrayXd duration(T); Eigen::ArrayXd duration(T);
for (unsigned int i = 0; i < T; ++i) { for (unsigned int i = 0; i < T; ++i) {
c_start = std::clock(); clock_gettime(CLOCK_MONOTONIC, &start);
ddp.solve(xs, us, MAXITER); ddp.solve(xs, us, MAXITER);
c_end = std::clock(); clock_gettime(CLOCK_MONOTONIC, &finish);
duration[i] = 1e3 * (double)(c_end - c_start) / CLOCKS_PER_SEC; elapsed = (finish.tv_sec - start.tv_sec) * 1000000.0;
elapsed += (finish.tv_nsec - start.tv_nsec) / 1000.0;
duration[i] = elapsed / 1000.;
} }
double avrg_duration = duration.sum() / T; double avrg_duration = duration.sum() / T;
double min_duration = duration.minCoeff(); double min_duration = duration.minCoeff();
double max_duration = duration.maxCoeff(); double max_duration = duration.maxCoeff();
std::cout << "CPU time [ms]: " << avrg_duration << " (" << min_duration << "-" << max_duration << ")" << std::endl; std::cout << "Wall time [mu]: " << avrg_duration << " (" << min_duration << "-" << max_duration << ")" << std::endl;
// Running calc
for (unsigned int i = 0; i < T; ++i) {
clock_gettime(CLOCK_MONOTONIC, &start);
problem.calc(xs, us);
clock_gettime(CLOCK_MONOTONIC, &finish);
elapsed = (finish.tv_sec - start.tv_sec) * 1000000.0;
elapsed += (finish.tv_nsec - start.tv_nsec) / 1000.0;
duration[i] = elapsed / 1000.;
}
avrg_duration = duration.sum() / T;
min_duration = duration.minCoeff();
max_duration = duration.maxCoeff();
std::cout << "Wall time calc [ms]: " << avrg_duration << " (" << min_duration << "-" << max_duration << ")"
<< std::endl;
// Running calcDiff
for (unsigned int i = 0; i < T; ++i) {
clock_gettime(CLOCK_MONOTONIC, &start);
problem.calcDiff(xs, us);
clock_gettime(CLOCK_MONOTONIC, &finish);
elapsed = (finish.tv_sec - start.tv_sec) * 1000000.0;
elapsed += (finish.tv_nsec - start.tv_nsec) / 1000.0;
duration[i] = elapsed / 1000.;
}
avrg_duration = duration.sum() / T;
min_duration = duration.minCoeff();
max_duration = duration.maxCoeff();
std::cout << "Wall time calcDiff [ms]: " << avrg_duration << " (" << min_duration << "-" << max_duration << ")"
<< std::endl;
} }
\ No newline at end of file
#include "crocoddyl/core/actions/unicycle.hpp" #include "crocoddyl/core/actions/unicycle.hpp"
#include "crocoddyl/core/utils/callbacks.hpp" #include "crocoddyl/core/utils/callbacks.hpp"
#include "crocoddyl/core/solvers/ddp.hpp" #include "crocoddyl/core/solvers/ddp.hpp"
#include <ctime> #include <time.h>
#ifdef WITH_MULTITHREADING
#include <omp.h>
#endif // WITH_MULTITHREADING
int main() { int main() {
bool CALLBACKS = false; bool CALLBACKS = false;
...@@ -37,17 +41,53 @@ int main() { ...@@ -37,17 +41,53 @@ int main() {
} }
// Solving the optimal control problem // Solving the optimal control problem
std::clock_t c_start, c_end; struct timespec start, finish;
double elapsed;
Eigen::ArrayXd duration(T); Eigen::ArrayXd duration(T);
for (unsigned int i = 0; i < T; ++i) { for (unsigned int i = 0; i < T; ++i) {
c_start = std::clock(); clock_gettime(CLOCK_MONOTONIC, &start);
ddp.solve(xs, us, MAXITER); ddp.solve(xs, us, MAXITER);
c_end = std::clock(); clock_gettime(CLOCK_MONOTONIC, &finish);
duration[i] = 1e3 * (double)(c_end - c_start) / CLOCKS_PER_SEC; elapsed = (finish.tv_sec - start.tv_sec) * 1000000.0;
elapsed += (finish.tv_nsec - start.tv_nsec) / 1000.0;
duration[i] = elapsed / 1000.;
} }
double avrg_duration = duration.sum() / T; double avrg_duration = duration.sum() / T;
double min_duration = duration.minCoeff(); double min_duration = duration.minCoeff();
double max_duration = duration.maxCoeff(); double max_duration = duration.maxCoeff();
std::cout << "CPU time [ms]: " << avrg_duration << " (" << min_duration << "-" << max_duration << ")" << std::endl; std::cout << "Wall time solve [ms]: " << avrg_duration << " (" << min_duration << "-" << max_duration << ")"
<< std::endl;
// Running calc
for (unsigned int i = 0; i < T; ++i) {
clock_gettime(CLOCK_MONOTONIC, &start);
problem.calc(xs, us);
clock_gettime(CLOCK_MONOTONIC, &finish);
elapsed = (finish.tv_sec - start.tv_sec) * 1000000.0;
elapsed += (finish.tv_nsec - start.tv_nsec) / 1000.0;
duration[i] = elapsed / 1000.;
}
avrg_duration = duration.sum() / T;
min_duration = duration.minCoeff();
max_duration = duration.maxCoeff();
std::cout << "Wall time calc [ms]: " << avrg_duration << " (" << min_duration << "-" << max_duration << ")"
<< std::endl;
// Running calcDiff
for (unsigned int i = 0; i < T; ++i) {
clock_gettime(CLOCK_MONOTONIC, &start);
problem.calcDiff(xs, us);
clock_gettime(CLOCK_MONOTONIC, &finish);
elapsed = (finish.tv_sec - start.tv_sec) * 1000000.0;
elapsed += (finish.tv_nsec - start.tv_nsec) / 1000.0;
duration[i] = elapsed / 1000.;
}
avrg_duration = duration.sum() / T;
min_duration = duration.minCoeff();
max_duration = duration.maxCoeff();
std::cout << "Wall time calcDiff [ms]: " << avrg_duration << " (" << min_duration << "-" << max_duration << ")"
<< std::endl;
} }
...@@ -49,6 +49,10 @@ IF(UNIX) ...@@ -49,6 +49,10 @@ IF(UNIX)
PKG_CONFIG_USE_DEPENDENCY(${PROJECT_NAME} pinocchio) PKG_CONFIG_USE_DEPENDENCY(${PROJECT_NAME} pinocchio)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_SERIALIZATION_LIBRARY}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_SERIALIZATION_LIBRARY})
if(OPENMP_FOUND)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OpenMP_CXX_LIBRARIES})
ENDIF()
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib) INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib)
INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/
DESTINATION include DESTINATION include
......
...@@ -7,6 +7,11 @@ ...@@ -7,6 +7,11 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#include "crocoddyl/core/optctrl/shooting.hpp" #include "crocoddyl/core/optctrl/shooting.hpp"
#include <iostream>
#ifdef WITH_MULTITHREADING
#include <omp.h>
#define NUM_THREADS WITH_NTHREADS
#endif // WITH_MULTITHREADING
namespace crocoddyl { namespace crocoddyl {
...@@ -47,15 +52,20 @@ double ShootingProblem::calcDiff(const std::vector<Eigen::VectorXd>& xs, const s ...@@ -47,15 +52,20 @@ double ShootingProblem::calcDiff(const std::vector<Eigen::VectorXd>& xs, const s
assert(us.size() == T_ && "Wrong dimension of the control trajectory, it should be T."); assert(us.size() == T_ && "Wrong dimension of the control trajectory, it should be T.");
cost_ = 0; cost_ = 0;
for (unsigned int i = 0; i < T_; ++i) { unsigned int i;
ActionModelAbstract* model = running_models_[i];
boost::shared_ptr<ActionDataAbstract>& data = running_datas_[i]; #ifdef WITH_MULTITHREADING
const Eigen::VectorXd& x = xs[i]; omp_set_num_threads(NUM_THREADS);
const Eigen::VectorXd& u = us[i]; #pragma omp parallel for
#endif
for (i = 0; i < T_; ++i) {
running_models_[i]->calcDiff(running_datas_[i], xs[i], us[i]);
}
model->calcDiff(data, x, u); for (unsigned int i = 0; i < T_; ++i) {
cost_ += data->cost; cost_ += running_datas_[i]->cost;
} }
terminal_model_->calcDiff(terminal_data_, xs.back()); terminal_model_->calcDiff(terminal_data_, xs.back());
cost_ += terminal_data_->cost; cost_ += terminal_data_->cost;
return cost_; return cost_;
......
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