Skip to content

Commit

Permalink
[Win32] Merge PR #110
Browse files Browse the repository at this point in the history
  • Loading branch information
bchretien committed May 27, 2016
2 parents 3a6aa9b + 2cde105 commit 97240de
Show file tree
Hide file tree
Showing 26 changed files with 351 additions and 309 deletions.
2 changes: 1 addition & 1 deletion .travis
48 changes: 37 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,20 @@
# You should have received a copy of the GNU Lesser General Public License
# along with roboptim-core. If not, see <http://www.gnu.org/licenses/>.

# Requires at least CMake 2.8 to configure the package.
# Requires at least CMake 2.8.12 to configure the package.
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12)

INCLUDE(cmake/base.cmake)
INCLUDE(cmake/boost.cmake)
INCLUDE(cmake/lapack.cmake)
INCLUDE(cmake/cpack.cmake)
INCLUDE(cmake/eigen.cmake)
INCLUDE(cmake/msvc-specific.cmake)

SET(PROJECT_NAME roboptim-core)
SET(PROJECT_DESCRIPTION "RobOptim Core")
SET(PROJECT_URL "http://github.com/roboptim/roboptim-core")
SET(PROJECT_DEBUG_POSTFIX "_d")

# Use MathJax for Doxygen formulae
SET(DOXYGEN_USE_MATHJAX "YES")
Expand Down Expand Up @@ -167,6 +169,12 @@ IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
ENDIF()
ENDIF()

IF(PROJECT_DEBUG_POSTFIX)
SET(FLAG_POSTFIX -DROBOPTIM_DEBUG_POSTFIX="${PROJECT_DEBUG_POSTFIX}")
ADD_COMPILE_OPTIONS($<$<CONFIG:Debug>:${FLAG_POSTFIX}>)
PKG_CONFIG_APPEND_CFLAGS_DEBUG(${FLAG_POSTFIX})
ENDIF()

SET(USE_CXX11 FALSE CACHE BOOL "Whether to use C++11")

SET(ROBOPTIM_PRECOMPILE_DENSE_SPARSE FALSE CACHE BOOL
Expand Down Expand Up @@ -199,20 +207,32 @@ PKG_CONFIG_APPEND_LIBS(roboptim-core)
# Search for dependencies.
SET(BOOST_COMPONENTS date_time filesystem system unit_test_framework)
SEARCH_FOR_BOOST()
ADD_REQUIRED_DEPENDENCY("eigen3 >= 3.2.0")
ADD_REQUIRED_DEPENDENCY("liblog4cxx >= 0.10.0")
SEARCH_FOR_EIGEN("eigen3 >= 3.2.0")
IF(WIN32)
ADD_REQUIRED_DEPENDENCY("liblog4cxx >= 0.10.0" "liblog4cxx_d >= 0.10.0")
ELSE()
ADD_REQUIRED_DEPENDENCY("liblog4cxx >= 0.10.0")
ENDIF()

# Libtool dynamic loading
# This project does not use Libtool directly but still uses ltdl for
# plug-in loading.
INCLUDE(CheckIncludeFileCXX)
CHECK_INCLUDE_FILE_CXX(ltdl.h LTDL_H_FOUND)
IF (NOT LTDL_H_FOUND)
MESSAGE(FATAL_ERROR
"Failed to find ltdl.h, check that Libtool ltdl is installed.")
ENDIF()
#FIXME: check that libltdl.so is available instead of adding it blindly.
PKG_CONFIG_APPEND_LIBS(ltdl)
IF(WIN32)
ADD_OPTIONAL_DEPENDENCY("ltdl" "ltdl_d")
ENDIF(WIN32)

IF(NOT LTDL_FOUND)
#FIXME: check that libltdl.so is available instead of adding it blindly.
INCLUDE(CheckIncludeFileCXX)
CHECK_INCLUDE_FILE_CXX(ltdl.h LTDL_H_FOUND)
IF (NOT LTDL_H_FOUND)
MESSAGE(FATAL_ERROR
"Failed to find ltdl.h, check that Libtool ltdl is installed.")
ENDIF()

PKG_CONFIG_APPEND_LIBS(ltdl)
ENDIF(NOT LTDL_FOUND)

HEADER_INSTALL("${HEADERS}")

# Set plug-in subdirectory name (can be empty).
Expand Down Expand Up @@ -242,6 +262,12 @@ PKG_CONFIG_APPEND_CFLAGS (-DROBOPTIM_STORAGE_ORDER=${STORAGE_ORDER})

OPTION(DISABLE_TESTS "Disable test programs" OFF)

# For MSVC, set local environment variable to enable finding the built dlls
# of roboptim-core and the plugins when launching ctest with RUN_TESTS
IF(MSVC)
SET(CMAKE_MSVCIDE_RUN_PATH "\$(SolutionDir)/src/\$(Configuration)")
ENDIF(MSVC)

ADD_SUBDIRECTORY(src)

IF(NOT DISABLE_TESTS)
Expand Down
52 changes: 52 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
version: 1.0.{build}
branches:
only:
- dev

configuration:
- Debug

platform:
- x64

os: Visual Studio 2015
clone_folder: C:\devel-src\roboptim-core
environment:
CI_OS_NAME: win32
CI_TOOL: appveyor
# Dependencies should be a list of dependencies separated by spaces
CHOCO_DEPENDENCIES: "doxygen.portable"
GIT_DEPENDENCIES: "gergondet/ltdl-win32"
# Should be the same as clone_folder
PROJECT_SOURCE_DIR: C:\devel-src\roboptim-core
# Do not tinker with the variables below unless you know what you are doing
SOURCE_FOLDER: C:\devel-src
CMAKE_INSTALL_PREFIX: C:/devel
PATH: C:/devel/bin;C:\Libraries\boost_1_60_0\lib64-msvc-14.0;C:\msys64\mingw64\bin;%PATH%
PKG_CONFIG_PATH: C:/devel/lib/pkgconfig
BOOST_ROOT: C:\Libraries\boost_1_60_0
BOOST_LIBRARYDIR: C:\Libraries\boost_1_60_0\lib64-msvc-14.0
MINGW_GFORTRAN: C:\msys64\mingw64\bin\gfortran.exe
# N.B: empty lines here and in test_script are VERY important
build_script:
- ps: >-
Set-PSDebug -Trace 2
iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/aescande/testAppveyor/master/installAsAppveyorDependency.ps1'))
git submodule update --init --recursive
. ./.travis/functions.ps1
setup_build
./.travis/dependencies/eigen-3.2.ps1
install_dependencies
build_project
test_script:
- cmd: >-
cd %PROJECT_SOURCE_DIR%/build
ctest --build-config %CONFIGURATION% --exclude-regex example
2 changes: 1 addition & 1 deletion cmake
183 changes: 144 additions & 39 deletions include/roboptim/core/decorator/cached-function.hh
Original file line number Diff line number Diff line change
Expand Up @@ -99,60 +99,165 @@ namespace roboptim
const boost::shared_ptr<const T> function () const;

protected:

/// \internal
/// The four following pairs function definitions should be put in the .hxx
/// file. However, msvc compilers (at least up to Visual Sutdio 2015 Update
/// 1) fails in this case: it tries to match the definitions with the
/// declarations but since it does so before any substitution of any
///template parameters, it can't distiguish between the two declarations.
template <typename U>
void cachedFunctionGradient (gradient_ref gradient,
const_argument_ref argument,
size_type functionId,
typename detail::CachedFunctionTypes<U>::isDifferentiable_t::type* = 0)
const;
void cachedFunctionGradient(gradient_ref gradient,
const_argument_ref argument,
size_type functionId,
typename detail::CachedFunctionTypes<U>::isDifferentiable_t::type* = 0)
const
{
typename gradientCache_t::const_iterator it = gradientCache_
[static_cast<std::size_t> (functionId)].find(argument);
if (it != gradientCache_[static_cast<std::size_t> (functionId)].end())
{
gradient = *(it->second);
return;
}
function_->gradient(gradient, argument, functionId);

#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
bool cur_malloc_allowed = is_malloc_allowed();
set_is_malloc_allowed(true);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION

gradientCache_[static_cast<std::size_t> (functionId)][argument] = gradient;

#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
set_is_malloc_allowed(cur_malloc_allowed);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
}

template <typename U>
void cachedFunctionGradient (gradient_ref gradient,
const_argument_ref argument,
size_type functionId,
typename detail::CachedFunctionTypes<U>::isNotDifferentiable_t::type* = 0)
const;
void cachedFunctionGradient(gradient_ref,
const_argument_ref,
size_type,
typename detail::CachedFunctionTypes<U>::isNotDifferentiable_t::type* = 0)
const
{
// Not differentiable
assert(0);
}

template <typename U>
void cachedFunctionJacobian (jacobian_ref jacobian,
const_argument_ref argument,
typename detail::CachedFunctionTypes<U>::isDifferentiable_t::type* = 0)
const;
void cachedFunctionJacobian(jacobian_ref jacobian,
const_argument_ref argument,
typename detail::CachedFunctionTypes<U>::isDifferentiable_t::type* = 0)
const
{
typename CachedFunction<T>::jacobianCache_t::
const_iterator it = jacobianCache_.find(argument);
if (it != jacobianCache_.end())
{
jacobian = *(it->second);
return;
}
function_->jacobian(jacobian, argument);

#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
bool cur_malloc_allowed = is_malloc_allowed();
set_is_malloc_allowed(true);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION

jacobianCache_[argument] = jacobian;

#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
set_is_malloc_allowed(cur_malloc_allowed);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
}

template <typename U>
void cachedFunctionJacobian (jacobian_ref jacobian,
const_argument_ref argument,
typename detail::CachedFunctionTypes<U>::isNotDifferentiable_t::type* = 0)
const;
void cachedFunctionJacobian(jacobian_ref,
const_argument_ref,
typename detail::CachedFunctionTypes<U>::isNotDifferentiable_t::type* = 0)
const
{
// Not differentiable
assert(0);
}

template <typename U>
void cachedFunctionHessian (hessian_ref hessian,
const_argument_ref argument,
size_type functionId,
typename detail::CachedFunctionTypes<U>::isTwiceDifferentiable_t::type* = 0)
const;
void cachedFunctionHessian(hessian_ref hessian,
const_argument_ref argument,
size_type functionId,
typename detail::CachedFunctionTypes<U>::isTwiceDifferentiable_t::type* = 0)
const
{
//FIXME: bug detected by Clang. To be fixed.
#ifdef ROBOPTIM_CORE_THIS_DOES_NOT_WORK
typename CachedFunction<T>::functionCache_t::
const_iterator it = hessianCache_
[static_cast<std::size_t> (functionId)].find(argument);
if (it != hessianCache_[functionId].end())
{
hessian = *(it->second);
return;
}
#endif
function_->hessian(hessian, argument, functionId);

#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
bool cur_malloc_allowed = is_malloc_allowed();
set_is_malloc_allowed(true);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION

hessianCache_[static_cast<std::size_t> (functionId)][argument] = hessian;

#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
set_is_malloc_allowed(cur_malloc_allowed);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
}


template <typename U>
void cachedFunctionHessian (hessian_ref hessian,
const_argument_ref argument,
size_type functionId,
typename detail::CachedFunctionTypes<U>::isNotTwiceDifferentiable_t::type* = 0)
const;
void cachedFunctionHessian(hessian_ref,
const_argument_ref,
size_type,
typename detail::CachedFunctionTypes<U>::isNotTwiceDifferentiable_t::type* = 0)
const
{
// Not twice-differentiable
assert(0);
}


template <typename U>
void cachedFunctionDerivative (gradient_ref derivative,
value_type argument,
size_type order,
typename detail::CachedFunctionTypes<U>::isNTimesDerivable_t::type* = 0)
const;
void cachedFunctionDerivative(gradient_ref derivative,
value_type argument,
size_type order,
typename detail::CachedFunctionTypes<U>::isNTimesDerivable_t::type*)
const
{
typename T::vector_t x(1);
x[0] = argument;
typename CachedFunction<T>::functionCache_t::
const_iterator it = cache_[order].find(x);
if (it != cache_[order].end())
{
derivative = *(it->second);
return;
}
function_->derivative(derivative, x, order);
cache_[order][x] = derivative;
}


template <typename U>
void cachedFunctionDerivative (gradient_ref derivative,
value_type argument,
size_type order,
typename detail::CachedFunctionTypes<U>::isNotNTimesDerivable_t::type* = 0)
const;
void cachedFunctionDerivative(gradient_ref,
value_type,
size_type,
typename detail::CachedFunctionTypes<U>::isNotNTimesDerivable_t::type* = 0)
const
{
// Not n-times derivable
assert(0);
}


protected:
virtual void impl_compute (result_ref result, const_argument_ref argument)
Expand Down
Loading

0 comments on commit 97240de

Please sign in to comment.