diff --git a/recipes/cmaes/all/conandata.yml b/recipes/cmaes/all/conandata.yml new file mode 100644 index 0000000000000..f63570f08f9fe --- /dev/null +++ b/recipes/cmaes/all/conandata.yml @@ -0,0 +1,7 @@ +sources: + "0.10.0": + url: "https://github.com/CMA-ES/libcmaes/archive/refs/tags/v0.10.tar.gz" + sha256: "a77fb892654356c5657dd677161b7c67b196dc732cfb77eaca6708abc4f6cffc" +patches: + "0.10.0": + - patch_file: "patches/CompilerOptionsEigen.patch" diff --git a/recipes/cmaes/all/conanfile.py b/recipes/cmaes/all/conanfile.py new file mode 100644 index 0000000000000..b38afa1737d5b --- /dev/null +++ b/recipes/cmaes/all/conanfile.py @@ -0,0 +1,103 @@ +from conan import ConanFile +from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout +from conan.tools.files import ( + export_conandata_patches, + get, + rmdir, + rm, + copy, + apply_conandata_patches, +) +from conan.tools.build import check_min_cppstd +import os + + +class CmaesConan(ConanFile): + name = "cmaes" + + generators = "CMakeDeps" + + license = "LGPL-3.0-or-later" + url = "https://github.com/conan-io/conan-center-index" + homepage = "https://github.com/CMA-ES/libcmaes" + description = "libcmaes is a multithreaded C++11 library with Python bindings for high performance blackbox stochastic optimization using the CMA-ES algorithm for Covariance Matrix Adaptation Evolution Strategy" + topics = ("cmaes", "minimization") + package_type = "library" + + settings = "os", "compiler", "build_type", "arch" + options = { + "shared": [True, False], + "fPIC": [True, False], + "surrog": [True, False], + } + default_options = { + "shared": False, + "fPIC": True, + "surrog": True, + } + + short_paths = True + + @property + def _min_cppstd(self): + return 11 + + def config_options(self): + if self.settings.os == "Windows": + del self.options.fPIC + + def configure(self): + if self.options.shared: + self.options.rm_safe("fPIC") + + def export_sources(self): + export_conandata_patches(self) + + def validate(self): + check_min_cppstd(self, self._min_cppstd) + + def source(self): + get(self, **self.conan_data["sources"][self.version], strip_root=True) + apply_conandata_patches(self) + + def requirements(self): + self.requires("eigen/3.4.0", transitive_headers=True) + + def layout(self): + cmake_layout(self, src_folder="src") + + def generate(self): + tc = CMakeToolchain(self) + tc.variables["LIBCMAES_BUILD_EXAMPLES"] = False + tc.variables["LIBCMAES_BUILD_SHARED_LIBS"] = self.options.shared + tc.variables["LIBCMAES_USE_OPENMP"] = False + tc.variables["LIBCMAES_ENABLE_SURROG"] = self.options.surrog + tc.variables["LIBCMAES_BUILD_PYTHON"] = False + tc.variables["LIBCMAES_BUILD_TESTS"] = False + tc.generate() + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def package(self): + cmake = CMake(self) + cmake.install() + + rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig")) + rm( + self, + "*.cmake", + os.path.join(self.package_folder, "lib", "cmake", "libcmaes"), + ) + copy( + self, + "COPYING", + self.source_folder, + os.path.join(self.package_folder, "licenses"), + ) + + def package_info(self): + self.cpp_info.libs = ["cmaes"] + self.cpp_info.set_property("cmake_target_name", "libcmaes::cmaes") diff --git a/recipes/cmaes/all/patches/CompilerOptionsEigen.patch b/recipes/cmaes/all/patches/CompilerOptionsEigen.patch new file mode 100644 index 0000000000000..ba728f3d5d253 --- /dev/null +++ b/recipes/cmaes/all/patches/CompilerOptionsEigen.patch @@ -0,0 +1,142 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 4a38212..dccfea4 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -6,12 +6,10 @@ if (NOT DEFINED CMAKE_BUILD_TYPE) + set (CMAKE_BUILD_TYPE Release CACHE STRING "Build type") + endif () + +-set(CMAKE_CXX_FLAGS "-Wall -Wextra") +-set(CMAKE_CXX_FLAGS_DEBUG "-g") +-set(CMAKE_CXX_FLAGS_RELEASE "-O3") +- + list (APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) + ++include(CompilerOptions) ++ + set (LIBCMAES_TOP_LEVEL NO) + if (${PROJECT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR}) + set (LIBCMAES_TOP_LEVEL YES) +diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake +new file mode 100644 +index 0000000..af4f716 +--- /dev/null ++++ b/cmake/CompilerOptions.cmake +@@ -0,0 +1,91 @@ ++ ++set(CMAKE_CXX_FLAGS_DEBUG ++ "${CMAKE_CXX_FLAGS_DEBUG} -Wall" ++) ++set(CMAKE_CXX_FLAGS_RELEASE ++ "${CMAKE_CXX_FLAGS_RELEASE} -Wall ") ++ ++if(CMAKE_COMPILER_IS_GNUCXX) ++ set(CMAKE_CXX_FLAGS_DEBUG ++ "${CMAKE_CXX_FLAGS_DEBUG} -Wextra") ++ set(CMAKE_CXX_FLAGS_RELEASE ++ "${CMAKE_CXX_FLAGS_RELEASE} -O3 -Wextra") ++endif(CMAKE_COMPILER_IS_GNUCXX) ++ ++if (MSVC) ++ #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_USE_MATH_DEFINES" ) ++ ++ set(CMAKE_CXX_FLAGS_DEBUG ++ "${CMAKE_CXX_FLAGS_DEBUG} /permissive- /bigobj /w44101") ++ ++ set(CMAKE_CXX_FLAGS_RELEASE ++ "${CMAKE_CXX_FLAGS_RELEASE} /permissive- /bigobj /Ox /w44101") ++ ++ set(MSVC_DISABLED_WARNINGS_LIST ++ "C4061" # enumerator 'identifier' in switch of enum 'enumeration' is not ++ # explicitly handled by a case label ++ # Disable this because it flags even when there is a default. ++ "C4068" ++ "C4100" # 'exarg' : unreferenced formal parameter ++ "C4127" # conditional expression is constant ++ "C4200" # nonstandard extension used : zero-sized array in ++ # struct/union. ++ "C4204" # nonstandard extension used: non-constant aggregate initializer ++ "C4221" # nonstandard extension used : 'identifier' : cannot be ++ # initialized using address of automatic variable ++ "C4242" # 'function' : conversion from 'int' to 'uint8_t', ++ # possible loss of data ++ "C4244" # 'function' : conversion from 'int' to 'uint8_t', ++ # possible loss of data ++ "C4245" # 'initializing' : conversion from 'long' to ++ # 'unsigned long', signed/unsigned mismatch ++ "C4251" ++ "C4267" # conversion from 'size_t' to 'int', possible loss of data ++ "C4275" ++ "C4355" ++ "C4371" # layout of class may have changed from a previous version of the ++ # compiler due to better packing of member '...' ++ "C4388" # signed/unsigned mismatch ++ "C4296" # '>=' : expression is always true ++ "C4350" # behavior change: 'std::_Wrap_alloc...' ++ "C4365" # '=' : conversion from 'size_t' to 'int', ++ # signed/unsigned mismatch ++ "C4389" # '!=' : signed/unsigned mismatch ++ "C4464" # relative include path contains '..' ++ "C4510" # 'argument' : default constructor could not be generated ++ "C4571" ++ "C4512" # 'argument' : assignment operator could not be generated ++ "C4514" # 'function': unreferenced inline function has been removed ++ "C4548" # expression before comma has no effect; expected expression with ++ # side-effect" caused by FD_* macros. ++ "C4610" # struct 'argument' can never be instantiated - user defined ++ # constructor required. ++ "C4619" ++ "C4623" # default constructor was implicitly defined as deleted ++ "C4625" # copy constructor could not be generated because a base class ++ # copy constructor is inaccessible or deleted ++ "C4626" # assignment operator could not be generated because a base class ++ # assignment operator is inaccessible or deleted ++ "C4643" ++ "C4668" # 'symbol' is not defined as a preprocessor macro, replacing with ++ # '0' for 'directives' ++ # Disable this because GTest uses it everywhere. ++ "C4706" # assignment within conditional expression ++ "C4710" # 'function': function not inlined ++ "C4711" # function 'function' selected for inline expansion ++ "C4800" # 'int' : forcing value to bool 'true' or 'false' ++ # (performance warning) ++ "C4820" # 'bytes' bytes padding added after construct 'member_name' ++ "C4868" ++ "C4996" ++ "C5026" # move constructor was implicitly defined as deleted ++ "C5027" # move assignment operator was implicitly defined as deleted ++ "C5031" ++ "C5039" ++ "C5045" ++ ) ++ string(REPLACE "C" " -wd" MSVC_DISABLED_WARNINGS_STR ++ ${MSVC_DISABLED_WARNINGS_LIST}) ++ ++ set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} ${MSVC_DISABLED_WARNINGS_STR}") ++ endif() +diff --git a/include/libcmaes/eigenmvn.h b/include/libcmaes/eigenmvn.h +index fb8b11d..6a6943b 100644 +--- a/include/libcmaes/eigenmvn.h ++++ b/include/libcmaes/eigenmvn.h +@@ -58,7 +58,20 @@ public: + static std::mt19937 rng; // The uniform pseudo-random algorithm + mutable std::normal_distribution norm; // gaussian combinator + +- EIGEN_EMPTY_STRUCT_CTOR(scalar_normal_dist_op) ++ scalar_normal_dist_op() = default; ++ scalar_normal_dist_op(const scalar_normal_dist_op& other) ++ : norm{other.norm} ++ { ++ rng = other.rng; ++ }; ++ scalar_normal_dist_op &operator=(const scalar_normal_dist_op &other) { ++ if(this != &other) ++ { ++ scalar_normal_dist_op temp(other); ++ swap(temp); ++ } ++ return *this; ++ }; + + scalar_normal_dist_op &operator=(scalar_normal_dist_op &&other) + { diff --git a/recipes/cmaes/all/test_package/CMakeLists.txt b/recipes/cmaes/all/test_package/CMakeLists.txt new file mode 100644 index 0000000000000..a2f973d357026 --- /dev/null +++ b/recipes/cmaes/all/test_package/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.15) +project(PackageTest CXX) + +find_package(cmaes CONFIG REQUIRED) + +add_executable(example src/example.cpp) +target_link_libraries(example libcmaes::cmaes) +target_compile_features(example PUBLIC cxx_std_11) diff --git a/recipes/cmaes/all/test_package/conanfile.py b/recipes/cmaes/all/test_package/conanfile.py new file mode 100644 index 0000000000000..2037d777edea2 --- /dev/null +++ b/recipes/cmaes/all/test_package/conanfile.py @@ -0,0 +1,27 @@ +import os + +from conan import ConanFile +from conan.tools.cmake import CMake, cmake_layout +from conan.tools.build import can_run + + +class helloTestConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "CMakeDeps", "CMakeToolchain" + + def requirements(self): + self.requires(self.tested_reference_str) + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def layout(self): + cmake_layout(self) + + def test(self): + if can_run(self): + cmd = os.path.join(self.cpp.build.bindir, "example") + self.run(cmd, env="conanrun") + diff --git a/recipes/cmaes/all/test_package/src/example.cpp b/recipes/cmaes/all/test_package/src/example.cpp new file mode 100644 index 0000000000000..e42d6b2f0684b --- /dev/null +++ b/recipes/cmaes/all/test_package/src/example.cpp @@ -0,0 +1,61 @@ +#include +#include + +using namespace libcmaes; + +FitFunc fsphere = [](const double *x, const int N) +{ + double val = 0.0; + for (int i=0;i x0(dim,10.0); + double sigma = 0.1; + //int lambda = 100; // offsprings at each generation. + CMAParameters<> cmaparams(x0,sigma); + //cmaparams._algo = BIPOP_CMAES; + CMASolutions cmasols = cmaes<>(fsphere,cmaparams); + std::cout << "best solution: " << cmasols << std::endl; + std::cout << "optimization took " << cmasols.elapsed_time() / 1000.0 << " seconds\n"; + + Candidate bcand = cmasols.best_candidate(); + + std::vector xsol = bcand.get_x(); + return EXIT_SUCCESS; +} + +int test2() +{ + int dim = 10; // problem dimensions. + std::vector x0(dim,10.0); + double sigma = 0.1; + double ftol = 1e-5; + + CMAParameters<> cmaparams(x0, sigma); + // cmaparams.set_mt_feval(true); + cmaparams.set_algo(aCMAES); + // cmaparams.set_elitism(1); + // cmaparams.set_noisy(); + cmaparams.set_ftolerance(ftol); + CMASolutions cmasols = cmaes<>(fsphere, cmaparams); + + Candidate bcand = cmasols.best_candidate(); + + std::vector xsol = bcand.get_x(); + + std::cout << "best solution: " << cmasols << std::endl; + std::cout << "optimization took " << cmasols.elapsed_time() / 1000.0 << " seconds\n"; + return EXIT_SUCCESS; +} + +int main() +{ + test1(); + test2(); + return EXIT_SUCCESS; +} diff --git a/recipes/cmaes/config.yml b/recipes/cmaes/config.yml new file mode 100644 index 0000000000000..1b582dcf6716b --- /dev/null +++ b/recipes/cmaes/config.yml @@ -0,0 +1,3 @@ +versions: + "0.10.0": + folder: all