Skip to content

Added extended testing, separated tests and benchmarks #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: devel
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Xcode*
coverage*
.vscode*
*.orig
.cache
.DS_Store
Comment on lines +9 to +10
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be set in your local .gitignore on your computer.

# pixi environments
.pixi
*.egg-info
39 changes: 39 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ endif()
# --- OPTIONS ----------------------------------------
option(BUILD_WITH_VERSION_SUFFIX "Build libraries with version appended to suffix" OFF)
option(ENABLE_TEMPLATE_INSTANTIATION "Template instantiation of the main library" ON)
option(BUILD_WITH_EXTENDED_TESTING "Build library with extended testing" OFF)
option(BUILD_WITH_BENCHMARK "Build library with timing benchmarks" OFF)
Comment on lines +88 to +89
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
option(BUILD_WITH_EXTENDED_TESTING "Build library with extended testing" OFF)
option(BUILD_WITH_BENCHMARK "Build library with timing benchmarks" OFF)
option(BUILD_EXTENDED_TESTING "Build library with extended testing" OFF)
option(BUILD_BENCHMARK "Build library with timing benchmarks" OFF)


# --- OPTIONAL DEPENDENCIES -------------------------
option(INITIALIZE_WITH_NAN "Initialize Eigen entries with NaN" OFF)
Expand All @@ -109,6 +111,17 @@ if(ENABLE_TEMPLATE_INSTANTIATION)
list(APPEND CFLAGS_DEPENDENCIES "-DLOIK_ENABLE_TEMPLATE_INSTANTIATION")
endif()

if(BUILD_WITH_BENCHMARK)
message(STATUS "Benchmarking is enabled")
add_compile_definitions(ENABLE_BENCHMARK)
endif()

if(BUILD_WITH_EXTENDED_TESTING)
message(STATUS "Extended testing is enabled")
add_compile_definitions(ENABLE_EXTENDED_TESTING)
add_compile_definitions(LOIK_PROBLEM_DATA_DIR="${PROJECT_SOURCE_DIR}/problems")
endif()

macro(TAG_LIBRARY_VERSION target)
set_target_properties(${target} PROPERTIES SOVERSION ${PROJECT_VERSION})
endmacro()
Expand Down Expand Up @@ -142,6 +155,14 @@ set(LIB_HEADERS
set(LIB_TEMPLATE_INSTANTIATION_HEADERS
${LIB_HEADER_DIR}/loik-loid.txx ${LIB_HEADER_DIR}/loik-loid-optimized.txx
${LIB_HEADER_DIR}/loik-loid-data.txx ${LIB_HEADER_DIR}/loik-loid-data-optimized.txx)
# set(LIB_EXTENDED_TEST_DIR ${PROJECT_SOURCE_DIR}/problems)
# set(LIB_EXTENDED_TEST_HEADERS
# ${LIB_EXTENDED_TEST_DIR}/test-problems.hpp)
# set(LIB_EXTENDED_TEST_SOURCES
# ${LIB_EXTENDED_TEST_DIR}/test-problems.cpp)
# set(LIB_BENCH_DIR ${PROJECT_SOURCE_DIR}/bench)
# set(LIB_BENCH_SOURCES
# ${LIB_BENCH_DIR}/timings.cpp)
Comment on lines +158 to +165
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If not used, should be removed.


set(LIB_SOURCE_DIR ${PROJECT_SOURCE_DIR}/src)
set(LIB_SOURCES)
Expand All @@ -154,6 +175,15 @@ if(ENABLE_TEMPLATE_INSTANTIATION)
list(APPEND LIB_SOURCES ${LIB_TEMPLATE_INSTANTIATION_SOURCES})
endif()

# if(BUILD_WITH_BENCHMARK)
# list(APPEND LIB_SOURCES ${LIB_BENCH_SOURCES})
# endif()

# if(BUILD_WITH_EXTENDED_TESTING)
# list(APPEND LIB_HEADERS ${LIB_EXTENDED_TEST_HEADERS})
# list(APPEND LIB_SOURCES ${LIB_EXTENDED_TEST_SOURCES})
# endif()

Comment on lines +178 to +186
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

function(set_standard_output_directory target)
set_target_properties(
${target}
Expand Down Expand Up @@ -222,6 +252,15 @@ if(BUILD_TESTING)
add_subdirectory(tests)
endif()

if(BUILD_WITH_BENCHMARK)
find_package(benchmark REQUIRED)
add_subdirectory(bench)
endif()

if(BUILD_WITH_EXTENDED_TESTING)
add_subdirectory(problems)
endif()

# --- PACKAGING ----------------------------------------------------------------
macro(EXPORT_VARIABLE var_name var_value)
get_directory_property(has_parent PARENT_DIRECTORY)
Expand Down
25 changes: 25 additions & 0 deletions bench/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#
# Copyright (C) 2024 INRIA
#

add_project_private_dependency(example-robot-data REQUIRED)

function(add_loik_benchmark name)
set(bench_name "${PROJECT_NAME}-bench-cpp-${name}")
set(bench_file ${name}.cpp)

message(STATUS "Adding benchmark ${bench_name}")
add_executable(${bench_name} ${bench_file})
set_standard_output_directory(${bench_name})
set_target_properties(${bench_name} PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(${bench_name} PRIVATE ${PROJECT_NAME} benchmark::benchmark example-robot-data::example-robot-data)

if(${BUILD_WITH_EXTENDED_TESTING})
target_include_directories(${bench_name} PRIVATE ${PROJECT_SOURCE_DIR})
target_link_libraries(${bench_name} PRIVATE problem-utils)
endif()

endfunction()


add_loik_benchmark(timings)
210 changes: 210 additions & 0 deletions bench/timings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
//
// Copyright (c) 2024 INRIA
//

#include "loik/fwd.hpp"
#include "loik/loik-loid-data-optimized.hpp"
#include "loik/loik-loid.hpp"

#ifdef ENABLE_EXTENDED_TESTING
#include "problems/problem-utils.hpp"
#endif

#include <pinocchio/algorithm/joint-configuration.hpp>
#include <pinocchio/parsers/urdf.hpp>
#include <pinocchio/utils/check.hpp>
#include <pinocchio/utils/timer.hpp>

using Scalar = double;
using Model = typename loik::IkIdDataTypeOptimizedTpl<Scalar>::Model;
using IkIdDataOptimized = loik::IkIdDataTypeOptimizedTpl<Scalar>;
using MuUpdateStrat = loik::ADMMPenaltyUpdateStrat;
using FirstOrderLoikOptimized = loik::FirstOrderLoikOptimizedTpl<Scalar>;

IKID_DATA_TYPEDEF_TEMPLATE(IkIdDataOptimized);

struct ProblemSetup
{

ProblemSetup()
{
// solver instantiation quantities
max_iter = 2;
tol_abs = 1e-3;
tol_rel = 1e-3;
tol_primal_inf = 1e-2;
tol_dual_inf = 1e-2;
tol_tail_solve = 1e-1;
rho = 1e-5;
mu = 1e-2;
mu_equality_scale_factor = 1e4;
mu_update_strat = MuUpdateStrat::DEFAULT;
num_eq_c = 1;
eq_c_dim = 6;
warm_start = false;
verbose = false;
logging = false;

// build model and data
// urdf_filename = EXAMPLE_ROBOT_DATA_MODEL_DIR +
// std::string("/panda_description/urdf/panda.urdf");
// urdf_filename =
// EXAMPLE_ROBOT_DATA_MODEL_DIR + std::string("/solo_description/urdf/solo.urdf");
urdf_filename =
EXAMPLE_ROBOT_DATA_MODEL_DIR + std::string("/talos_data/robots/talos_full_v2.urdf");
pinocchio::urdf::buildModel(urdf_filename, robot_model, false);

// solve ik quantitites
q = pinocchio::neutral(robot_model);
// q << -2.79684649, -0.55090374, 0.424806 , -1.21112304, -0.89856966,
// 0.79726132, -0.07125267, 0.13154589, 0.13171856;
H_ref = Mat6x6::Identity();
v_ref = Motion::Zero();
active_task_constraint_ids.push_back(static_cast<Index>(robot_model.njoints - 1));

const Mat6x6 Ai_identity = Mat6x6::Identity();
Vec6 bi = Vec6::Zero();
bi[2] = 0.5;
Ais.push_back(Ai_identity);
bis.push_back(bi);
bound_magnitude = 4.0;
lb = -bound_magnitude * DVec::Ones(robot_model.nv);
ub = bound_magnitude * DVec::Ones(robot_model.nv);
}

int max_iter;
Scalar tol_abs;
Scalar tol_rel;
Scalar tol_primal_inf;
Scalar tol_dual_inf;
Scalar tol_tail_solve;
Scalar rho;
Scalar mu;
Scalar mu_equality_scale_factor;
MuUpdateStrat mu_update_strat;
int num_eq_c = 1;
int eq_c_dim = 6;
bool warm_start = false;
bool verbose = false;
bool logging = false;

Model robot_model;

std::string urdf_filename;

DVec q;

Mat6x6 H_ref;
Motion v_ref;
std::vector<Index> active_task_constraint_ids;
PINOCCHIO_ALIGNED_STD_VECTOR(Mat6x6) Ais;
PINOCCHIO_ALIGNED_STD_VECTOR(Vec6) bis;
Scalar bound_magnitude;
DVec lb;
DVec ub;

}; // struct ProblemSetup


enum SolveType
{
FULL = 0,
REPEAT = 1,
TAILORED = 3
}; // enum SolveType


void test_1st_order_loik_timing(ProblemSetup& problem, const SolveType& solve_type)
{
problem.max_iter = 2;
problem.bound_magnitude = 1.0;
problem.lb = -problem.bound_magnitude * DVec::Ones(problem.robot_model.nv);
problem.ub = problem.bound_magnitude * DVec::Ones(problem.robot_model.nv);

IkIdDataOptimized ikid_data(problem.robot_model, problem.num_eq_c);

FirstOrderLoikOptimized LoikSolver{
problem.max_iter,
problem.tol_abs,
problem.tol_rel,
problem.tol_primal_inf,
problem.tol_dual_inf,
problem.rho,
problem.mu,
problem.mu_equality_scale_factor,
problem.mu_update_strat,
problem.num_eq_c,
problem.eq_c_dim,
problem.robot_model,
ikid_data,
problem.warm_start,
problem.tol_tail_solve,
problem.verbose,
problem.logging};

PinocchioTicToc timer(PinocchioTicToc::US);

#ifdef NDEBUG
const int NBT = 100000;
// const int NBT = 1;
#else
const int NBT = 100000;
std::cout << "(the time score in debug mode is not relevant) " << std::endl;
#endif

LoikSolver.SolveInit(problem.q, problem.H_ref, problem.v_ref, problem.active_task_constraint_ids, problem.Ais, problem.bis, problem.lb, problem.ub);
LoikSolver.Solve();
int iter_took_to_solver = LoikSolver.get_iter();
std::cout << "Timing over " << iter_took_to_solver << " iterations for solver to solve"
<< std::endl;

if (solve_type == SolveType::FULL) {
timer.tic();
SMOOTH(NBT)
{
LoikSolver.Solve(problem.q, problem.H_ref, problem.v_ref, problem.active_task_constraint_ids, problem.Ais, problem.bis, problem.lb, problem.ub);
}
std::cout << "LOIK = \t\t\t\t";
timer.toc(std::cout, NBT);

} else if (solve_type == SolveType::REPEAT) {
timer.tic();
SMOOTH(NBT)
{
LoikSolver.Solve();
}
std::cout << "LOIK = \t\t\t\t";
timer.toc(std::cout, NBT);
} else if (solve_type == SolveType::TAILORED) {
timer.tic();
SMOOTH(NBT)
{
LoikSolver.Solve(problem.q, problem.active_task_constraint_ids[0], problem.Ais[0], problem.bis[0]);
}
std::cout << "LOIK = \t\t\t\t";
timer.toc(std::cout, NBT);
} else {
throw(std::runtime_error("[test_1st_order_loik_timing]: SolveType not supported."));
}

// sanity check, solve iteration should be unchanged
if (LoikSolver.get_iter() != iter_took_to_solver) {
throw(std::runtime_error("[test_1st_order_loik_timing]: number of iterations to `Solve` has changed."));
}

}; // test_1st_order_loik_timing


int main(int argc, char** argv)
{

ProblemSetup problem{};

/// test_1st_order_loik_timing
test_1st_order_loik_timing(problem, SolveType::REPEAT);

/// test_1st_order_loik_tailored_timing
test_1st_order_loik_timing(problem, SolveType::TAILORED);

}

27 changes: 27 additions & 0 deletions include/loik/fwd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,31 @@ namespace loik
template<typename S, int O> class JointCollectionTpl = pinocchio::JointCollectionDefaultTpl>
struct FirstOrderLoikOptimizedTpl;

/// type alias macro
#define IKID_DATA_TYPEDEF_GENERIC(Data,TYPENAME) \
typedef TYPENAME pinocchio::traits<Data>::Scalar Scalar; \
typedef TYPENAME pinocchio::traits<Data>::Model Model; \
typedef TYPENAME pinocchio::traits<Data>::SE3 SE3; \
typedef TYPENAME pinocchio::traits<Data>::Motion Motion; \
typedef TYPENAME pinocchio::traits<Data>::Force Force; \
typedef TYPENAME pinocchio::traits<Data>::Inertia Inertia; \
typedef TYPENAME pinocchio::traits<Data>::Frame Frame; \
typedef TYPENAME pinocchio::traits<Data>::Index Index; \
typedef TYPENAME pinocchio::traits<Data>::JointIndex JointIndex; \
typedef TYPENAME pinocchio::traits<Data>::FrameIndex FrameIndex; \
typedef TYPENAME pinocchio::traits<Data>::IndexVector IndexVector; \
typedef TYPENAME pinocchio::traits<Data>::JointModel JointModel; \
typedef TYPENAME pinocchio::traits<Data>::JointData JointData; \
typedef TYPENAME pinocchio::traits<Data>::JointModelVector JointModelVector; \
typedef TYPENAME pinocchio::traits<Data>::JointDataVector JointDataVector; \
typedef TYPENAME pinocchio::traits<Data>::DMat DMat; \
typedef TYPENAME pinocchio::traits<Data>::DVec DVec; \
typedef TYPENAME pinocchio::traits<Data>::Vec3 Vec3; \
typedef TYPENAME pinocchio::traits<Data>::Vec6 Vec6; \
typedef TYPENAME pinocchio::traits<Data>::Mat6x6 Mat6x6; \
typedef TYPENAME pinocchio::traits<Data>::ConfigVectorType ConfigVectorType; \
typedef TYPENAME pinocchio::traits<Data>::TangentVectorType TangentVectorType

#define IKID_DATA_TYPEDEF_TEMPLATE(Data) IKID_DATA_TYPEDEF_GENERIC(Data,typename)

} // namespace loik
12 changes: 3 additions & 9 deletions include/loik/ik-id-description-optimized.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#pragma once

#include "fwd.hpp"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#include "fwd.hpp"
#include "loik/fwd.hpp"

#include "loik/macros.hpp"
#include "loik/loik-loid-data-optimized.hpp"

Expand All @@ -17,15 +18,8 @@ namespace loik
struct IkProblemFormulationOptimized
{
using IkIdDataOptimized = IkIdDataTypeOptimizedTpl<_Scalar>;
using Motion = typename IkIdDataOptimized::Motion;
using Force = typename IkIdDataOptimized::Force;
using DMat = typename IkIdDataOptimized::DMat;
using DVec = typename IkIdDataOptimized::DVec;
using Vec3 = typename IkIdDataOptimized::Vec3;
using Vec6 = typename IkIdDataOptimized::Vec6;
using Mat6x6 = typename IkIdDataOptimized::Mat6x6;
using Index = typename IkIdDataOptimized::Index;
using IndexVec = typename IkIdDataOptimized::IndexVector;
IKID_DATA_TYPEDEF_TEMPLATE(IkIdDataOptimized);


explicit IkProblemFormulationOptimized(
const int nj, const int nb, const int nc_eq, const int eq_c_dim, const int ineq_c_dim)
Expand Down
Loading
Loading