Skip to content

Commit

Permalink
Merge pull request #3233 from rcurtin/util-header-only
Browse files Browse the repository at this point in the history
Adapt virtually everything else in mlpack to header-only
  • Loading branch information
rcurtin committed Jul 31, 2022
2 parents 2abbdb8 + 8e8b7fd commit 19be49c
Show file tree
Hide file tree
Showing 125 changed files with 1,053 additions and 1,012 deletions.
24 changes: 6 additions & 18 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,11 @@ option(BUILD_MARKDOWN_BINDINGS "Build Markdown bindings for website documentatio

option(MATHJAX
"Use MathJax for HTML Doxygen output (disabled by default)." OFF)
option(FORCE_CXX11
"Don't check that the compiler supports C++11, just assume it. Make sure to specify any necessary flag to enable C++11 as part of CXXFLAGS." OFF)
option(USE_OPENMP "If available, use OpenMP for parallelization." ON)
enable_testing()

# Set required standard to C++11.
set(CMAKE_CXX_STANDARD 11)
# Set required standard to C++14.
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Ensure that GCC is new enough, if the compiler is GCC.
Expand Down Expand Up @@ -375,26 +373,16 @@ endif()
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${CEREAL_INCLUDE_DIR})

# Detect OpenMP support in a compiler. If the compiler supports OpenMP, flags
# to compile with OpenMP are returned and added and the HAS_OPENMP definition
# is added for compilation.
#
# This way we can skip calls to functions defined in omp.h with code like:
# #ifdef HAS_OPENMP
# {
# ... openMP code here ...
# }
# #endif
# to compile with OpenMP are returned and added. Note that MSVC does not
# support a new-enough version of OpenMP to be useful.
if (USE_OPENMP)
find_package(OpenMP)
endif ()

if (OPENMP_FOUND)
add_definitions(-DHAS_OPENMP)
if (OpenMP_FOUND AND OpenMP_CXX_VERSION VERSION_GREATER_EQUAL 3.0.0)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
if (OpenMP_CXX_FOUND)
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} ${OpenMP_CXX_LIBRARIES})
endif ()
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} ${OpenMP_CXX_LIBRARIES})
else ()
# Disable warnings for all the unknown OpenMP pragmas.
if (NOT MSVC)
Expand Down
2 changes: 2 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
### mlpack ?.?.?
###### ????-??-??
* Bump C++ standard requirement to C++14 (#3233).

* Fix `Perceptron` to work with cross-validation framework (#3190).

* Migrate from boost tests to Catch2 framework (#2523), (#2584).
Expand Down
3 changes: 0 additions & 3 deletions doc/guide/build.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,6 @@ The full list of options mlpack allows:
(default ON)
- MATHJAX=(ON/OFF): use MathJax for generated Doxygen documentation (default
OFF)
- FORCE_CXX11=(ON/OFF): assume that the compiler supports C++11 instead of
checking; be sure to specify any necessary flag to enable C++11 as part
of CXXFLAGS (default OFF)
- USE_OPENMP=(ON/OFF): if ON, then use OpenMP if the compiler supports it; if
OFF, OpenMP support is manually disabled (default ON)
Expand Down
32 changes: 14 additions & 18 deletions src/mlpack/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,20 @@ endforeach()
# are set in the root CMakeLists.txt.
add_library(mlpack ${MLPACK_SRCS})

# If we are not forcing C++11 support, check that the compiler supports C++11
# and enable it.
if (NOT FORCE_CXX11)
target_compile_features(mlpack PUBLIC
cxx_decltype
cxx_alias_templates
cxx_auto_type
cxx_lambdas
cxx_constexpr
cxx_rvalue_references
cxx_static_assert
cxx_template_template_parameters
cxx_delegating_constructors
cxx_variadic_templates
cxx_nullptr
cxx_noexcept
)
endif ()
target_compile_features(mlpack PUBLIC
cxx_decltype
cxx_alias_templates
cxx_auto_type
cxx_lambdas
cxx_constexpr
cxx_rvalue_references
cxx_static_assert
cxx_template_template_parameters
cxx_delegating_constructors
cxx_variadic_templates
cxx_nullptr
cxx_noexcept
)

# Generate export symbols for Windows, instead of adding __declspec(dllimport)
# and __declspec(dllexport) everywhere. However, those modifiers are still
Expand Down
111 changes: 111 additions & 0 deletions src/mlpack/base.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/**
* @file base.hpp
*
* The most basic core includes that mlpack expects; standard C++ includes and
* Armadillo only
*
* mlpack is free software; you may redistribute it and/or modify it under the
* terms of the 3-clause BSD license. You should have received a copy of the
* 3-clause BSD license along with mlpack. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef MLPACK_BASE_HPP
#define MLPACK_BASE_HPP

// First, check if Armadillo was included before, warning if so.
#ifdef ARMA_INCLUDES
#pragma message "Armadillo was included before mlpack; this can sometimes cause\
problems. It should only be necessary to include <mlpack/core.hpp> and not \
<armadillo>."
#endif
// Defining _USE_MATH_DEFINES should set M_PI.
#define _USE_MATH_DEFINES
#include <cmath>
// Next, standard includes.
#include <cctype>
#include <cfloat>
#include <climits>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <stdexcept>
#include <tuple>
#include <utility>
#include <numeric>
#include <vector>
#include <queue>
// But if it's not defined, we'll do it.
#ifndef M_PI
#define M_PI 3.141592653589793238462643383279
#endif
// MLPACK_COUT_STREAM is used to change the default stream for printing
// purpose.
#if !defined(MLPACK_COUT_STREAM)
#define MLPACK_COUT_STREAM std::cout
#endif
// MLPACK_CERR_STREAM is used to change the stream for printing warnings
// and errors.
#if !defined(MLPACK_CERR_STREAM)
#define MLPACK_CERR_STREAM std::cerr
#endif
// Give ourselves a nice way to force functions to be inline if we need.
#undef mlpack_force_inline
#define mlpack_force_inline
#if defined(__GNUG__) && !defined(DEBUG)
#undef mlpack_force_inline
#define mlpack_force_inline __attribute__((always_inline))
#elif defined(_MSC_VER) && !defined(DEBUG)
#undef mlpack_force_inline
#define mlpack_force_inline __forceinline
#endif
// Backport std::any from C+17 to C++11 to replace boost::any.
// Use mnmlstc backport implementation only if compiler does not
// support C++17.
#if __cplusplus < 201703L
#include <mlpack/core/std_backport/any.hpp>
#include <mlpack/core/std_backport/string_view.hpp>
#define MLPACK_ANY core::v2::any
#define MLPACK_ANY_CAST core::v2::any_cast
#define MLPACK_STRING_VIEW core::v2::string_view
#else
#include <any>
#include <string_view>
#define MLPACK_ANY std::any
#define MLPACK_ANY_CAST std::any_cast
#define MLPACK_STRING_VIEW std::string_view
#endif
// Now include Armadillo through the special mlpack extensions.
#include <mlpack/core/arma_extend/arma_extend.hpp>
#include <mlpack/core/util/arma_traits.hpp>
// On Visual Studio, disable C4519 (default arguments for function templates)
// since it's by default an error, which doesn't even make any sense because
// it's part of the C++11 standard.
#ifdef _MSC_VER
#pragma warning(disable : 4519)
#endif
// Ensure that the user isn't doing something stupid with their Armadillo
// defines.
#include <mlpack/core/util/arma_config_check.hpp>
// This can be removed when Visual Studio supports an OpenMP version with
// unsigned loop variables.
#if (defined(_OPENMP) && (_OPENMP >= 201107))
#undef MLPACK_USE_OPENMP
#define MLPACK_USE_OPENMP
#endif
// We need to be able to mark functions deprecated.
#include <mlpack/core/util/deprecated.hpp>
#endif
1 change: 1 addition & 0 deletions src/mlpack/bindings/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ endforeach()

set(MARKDOWN_CATEGORIES ${MARKDOWN_CATEGORIES} PARENT_SCOPE)
set(MLPACK_SRCS ${MLPACK_SRCS} PARENT_SCOPE)
set(MLPACK_TEST_SRCS ${MLPACK_TEST_SRCS} PARENT_SCOPE)
set(MLPACK_PYXS ${MLPACK_PYXS} PARENT_SCOPE)
set(DISABLE_CFLAGS ${DISABLE_CFLAGS} PARENT_SCOPE)
set(BUILDING_PYTHON_BINDINGS ${BUILDING_PYTHON_BINDINGS} PARENT_SCOPE)
Expand Down
1 change: 1 addition & 0 deletions src/mlpack/bindings/R/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ macro (post_r_setup)
# Then copy each of the header and source files over to that directory.
set(MLPACK_SOURCES
"${CMAKE_BINARY_DIR}/src/mlpack/mlpack_export.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/base.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/prereqs.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/core.hpp"
)
Expand Down
2 changes: 1 addition & 1 deletion src/mlpack/bindings/R/R_option.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class ROption
data.cppType = cppName;

// Every parameter we'll get from R will have the correct type.
data.value = ANY(defaultValue);
data.value = defaultValue;

// Set the function pointers that we'll need. All of these function
// pointers will be used by both the program that generates the R, and
Expand Down
6 changes: 3 additions & 3 deletions src/mlpack/bindings/R/default_param_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ std::string DefaultParamImpl(
if (std::is_same<T, bool>::value)
oss << "FALSE";
else
oss << ANY_CAST<T>(data.value);
oss << MLPACK_ANY_CAST<T>(data.value);

return oss.str();
}
Expand All @@ -51,7 +51,7 @@ std::string DefaultParamImpl(
{
// Print each element in an array delimited by square brackets.
std::ostringstream oss;
const T& vector = ANY_CAST<T>(data.value);
const T& vector = MLPACK_ANY_CAST<T>(data.value);
oss << "c(";
if (std::is_same<T, std::vector<std::string>>::value)
{
Expand Down Expand Up @@ -92,7 +92,7 @@ std::string DefaultParamImpl(
util::ParamData& data,
const typename std::enable_if<std::is_same<T, std::string>::value>::type*)
{
const std::string& s = *ANY_CAST<std::string>(&data.value);
const std::string& s = *MLPACK_ANY_CAST<std::string>(&data.value);
return "\"" + s + "\"";
}

Expand Down
2 changes: 1 addition & 1 deletion src/mlpack/bindings/R/get_param.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ void GetParam(util::ParamData& d,
const void* /* input */,
void* output)
{
*((T**) output) = const_cast<T*>(ANY_CAST<T>(&d.value));
*((T**) output) = const_cast<T*>(MLPACK_ANY_CAST<T>(&d.value));
}

} // namespace r
Expand Down
10 changes: 5 additions & 5 deletions src/mlpack/bindings/R/get_printable_param.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ std::string GetPrintableParam(
std::tuple<data::DatasetInfo, arma::mat>>::value>::type* = 0)
{
std::ostringstream oss;
oss << ANY_CAST<T>(data.value);
oss << MLPACK_ANY_CAST<T>(data.value);
return oss.str();
}

Expand All @@ -44,7 +44,7 @@ std::string GetPrintableParam(
util::ParamData& data,
const typename std::enable_if<util::IsStdVector<T>::value>::type* = 0)
{
const T& t = ANY_CAST<T>(data.value);
const T& t = MLPACK_ANY_CAST<T>(data.value);

std::ostringstream oss;
for (size_t i = 0; i < t.size(); ++i)
Expand All @@ -61,7 +61,7 @@ std::string GetPrintableParam(
const typename std::enable_if<arma::is_arma_type<T>::value>::type* = 0)
{
// Get the matrix.
const T& matrix = ANY_CAST<T>(data.value);
const T& matrix = MLPACK_ANY_CAST<T>(data.value);

std::ostringstream oss;
oss << matrix.n_rows << "x" << matrix.n_cols << " matrix";
Expand All @@ -78,7 +78,7 @@ std::string GetPrintableParam(
const typename std::enable_if<data::HasSerialize<T>::value>::type* = 0)
{
std::ostringstream oss;
oss << data.cppType << " model at " << ANY_CAST<T*>(data.value);
oss << data.cppType << " model at " << MLPACK_ANY_CAST<T*>(data.value);
return oss.str();
}

Expand All @@ -92,7 +92,7 @@ std::string GetPrintableParam(
std::tuple<data::DatasetInfo, arma::mat>>::value>::type* = 0)
{
// Get the matrix.
const T& tuple = ANY_CAST<T>(data.value);
const T& tuple = MLPACK_ANY_CAST<T>(data.value);
const arma::mat& matrix = std::get<1>(tuple);

std::ostringstream oss;
Expand Down
3 changes: 1 addition & 2 deletions src/mlpack/bindings/R/mlpack/DESCRIPTION.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ Description: A fast, flexible machine learning library, written in C++, that
aims to provide fast, extensible implementations of cutting-edge
machine learning algorithms. See also Curtin et al. (2018)
<doi:10.21105/joss.00726>.
SystemRequirements: A C++11 compiler. Versions 4.8.*, 4.9.* or later of GCC
will be fine.
SystemRequirements: A C++14 compiler. Version 5 or later of GCC will be fine.
License: BSD_3_clause + file LICENSE
Depends: R (>= 4.0.0)
Imports: Rcpp (>= 0.12.12)
Expand Down
2 changes: 1 addition & 1 deletion src/mlpack/bindings/R/mlpack/src/Makevars
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
PKG_CXXFLAGS = -DBOOST_MATH_PROMOTE_DOUBLE_POLICY=false -I. $(SHLIB_OPENMP_CXXFLAGS)
PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
CXX_STD = CXX11
CXX_STD = CXX14
2 changes: 1 addition & 1 deletion src/mlpack/bindings/R/mlpack/src/Makevars.win
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
PKG_CXXFLAGS = -DBOOST_MATH_PROMOTE_DOUBLE_POLICY=false -I. $(SHLIB_OPENMP_CXXFLAGS) -ftrack-macro-expansion=0 -pipe --param ggc-min-expand=10 --param ggc-min-heapsize=8192
PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
CXX_STD = CXX11
CXX_STD = CXX14
8 changes: 4 additions & 4 deletions src/mlpack/bindings/R/print_doc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,19 @@ void PrintDoc(util::ParamData& d,
oss << ". Default value \"";
if (d.cppType == "std::string")
{
oss << ANY_CAST<std::string>(d.value);
oss << MLPACK_ANY_CAST<std::string>(d.value);
}
else if (d.cppType == "double")
{
oss << ANY_CAST<double>(d.value);
oss << MLPACK_ANY_CAST<double>(d.value);
}
else if (d.cppType == "int")
{
oss << ANY_CAST<int>(d.value);
oss << MLPACK_ANY_CAST<int>(d.value);
}
else if (d.cppType == "bool")
{
oss << (ANY_CAST<bool>(d.value) ? "TRUE" : "FALSE");
oss << (MLPACK_ANY_CAST<bool>(d.value) ? "TRUE" : "FALSE");
}
oss << "\"";
}
Expand Down
12 changes: 6 additions & 6 deletions src/mlpack/bindings/cli/add_to_cli11.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ void AddToCLI11(const std::string& cliName,
[&param](const std::string& value)
{
using TupleType = std::tuple<T, typename ParameterType<T>::type>;
TupleType& tuple = *ANY_CAST<TupleType>(&param.value);
std::get<0>(std::get<1>(tuple)) = ANY_CAST<std::string>(value);
TupleType& tuple = *MLPACK_ANY_CAST<TupleType>(&param.value);
std::get<0>(std::get<1>(tuple)) = MLPACK_ANY_CAST<std::string>(value);
param.wasPassed = true;
},
param.desc.c_str());
Expand Down Expand Up @@ -79,8 +79,8 @@ void AddToCLI11(const std::string& cliName,
[&param](const std::string& value)
{
using TupleType = std::tuple<T*, typename ParameterType<T>::type>;
TupleType& tuple = *ANY_CAST<TupleType>(&param.value);
std::get<1>(tuple) = ANY_CAST<std::string>(value);
TupleType& tuple = *MLPACK_ANY_CAST<TupleType>(&param.value);
std::get<1>(tuple) = MLPACK_ANY_CAST<std::string>(value);
param.wasPassed = true;
},
param.desc.c_str());
Expand Down Expand Up @@ -109,8 +109,8 @@ void AddToCLI11(const std::string& cliName,
[&param](const std::string& value)
{
using TupleType = std::tuple<T, typename ParameterType<T>::type>;
TupleType& tuple = *ANY_CAST<TupleType>(&param.value);
std::get<0>(std::get<1>(tuple)) = ANY_CAST<std::string>(value);
TupleType& tuple = *MLPACK_ANY_CAST<TupleType>(&param.value);
std::get<0>(std::get<1>(tuple)) = MLPACK_ANY_CAST<std::string>(value);
param.wasPassed = true;
},
param.desc.c_str());
Expand Down

0 comments on commit 19be49c

Please sign in to comment.