From 8e7b69a239ea2b77a9fd0b7453c4e58ecb1e1d1e Mon Sep 17 00:00:00 2001 From: Samuel Dowling Date: Tue, 26 Oct 2021 05:05:41 +1030 Subject: [PATCH] (#7334) armadillo/10.7.0 * Add recipe for armadillo 10.6.1 * Add recipe for armadillo to reflect as closely as possible the intended usage of the library. This includes the ability to use system libraries as backends if manually configured. Default behaviour will be to use OpenBLAS as a backend with the wrapper disabled, though this can be manually modified. * Add test program using example code provided by the armadillo project * Patch armadillo CMakeLists.txt to enable switching between system libraries and conan dependencies. Closes #6754. * [armadillo] Improve comments wrt fortran requirements * [armadillo] Add Macos compatability * Add ARMA_USE_ACCELERATE option, which is set as the default option on Macos systems. This removes the dependency on a fortran compiler as this provides a BLAS and LAPACK implementation. * Move opt_dependencies to use a dictionary ordered by the operating system. This allows optional dependencies unique to each operating system to be managed. * Ensure that OpenBLAS can only be used when ALLOW_OPENBLAS_MACOS is set on Macos * Ensure that system LAPACK and BLAS libraries can only be used when ALLOW_BLAS_LAPACK_MACOS is set on Macos. * [armadillo] Set ARMA_USE_ACCELERATE to false instead of deleting * Set ARMA_USE_ACCELERATE to False instead of deleting it when the operating system is not Macos. This facilitates proper option dependency testing. * [armadillo] Build without lapack support by default * Remove default LAPACK support. This will allow armadillo to be made available on CCI without waiting for gfortran to be made available as a compiler on CI runners. * Remove version ranges from openblas and hdf5 dependencies. * Add define guards around logic in example.cpp that requires lapack, so those tests aren't run when ARMA_USE_LAPACK isn't defined. * [armadillo] Build with lapack by default on macos * Build with lapack by default on macos. Macos ships with the accelerate framework which has an implementation of LAPACK, and thus doesn't require a fortran compiler to build. This should be used by default where available. * [armadillo] Add MSVC shared library compatability * Add MSVC shared library compatability by exporting all symbols. This enables the creation of a static import library that can be used with the resulting .dll. * Apply suggestions from code review * Configure test_package to use targets Co-authored-by: Javier G. Sogo * [armadillo] Simplify validation logic * Condense multiple mutually exclusive options with complex validation logic to multiple values for a single option where appropriate. This enforces mutual exclusivity by virtue of the fact that an option can only have a single value. This will make interpreting valid option combinations easier to understand. * Convert options to lowercase for consistency with other recipes in the conan center index. * Update recipes/armadillo/all/test_package/CMakeLists.txt * Force C++ language standard to be C++11 to address the insufficient default language standard present with apple-clang Co-authored-by: Uilian Ries * Apply suggestions from code review * Make co_dependencies protected to avoid name clashes with conan * Add TODO statements to optional dependencies Co-authored-by: Uilian Ries * [armadillo] Move source modifications to patch file * Move source modifications from using replace_in_file to using a patch file. This will make the recipe more maintainable. * Remove openblas and hdf5 variable assignment to use the string directly when requiring these libraries. * Move patching process to build() function to preserve downloaded source code. * [armadillo] Add support for versions 10.6.2 and 10.7.0 * Add download links and hashes for versions 10.6.2 and 10.7.0. * Add patch modification for CMakeLists.txt for version 10.7.0. This patch is essentially the same as what's provided for 10.6.x, however v10.7.0 introduced a number of additional lines at the beginning of this file which cannot be parsed by the patching library used, patch_ng.py. This is documented in https://github.com/conan-io/python-patch-ng/issues/19. * [armadillo] Export all symbols on windows * Export all symbols on shared windows builds so that a static library can be generated. * Remove system_openblas and system_hdf as options to force the conan counterparts to be used. * [armadillo] Remove references to system_openblas and system_hdf5 * Remove lingering references to system_openblas and system_hdf5 as they have been removed as options and break the build. * [armadillo] Remove old versions and clean up * Remove old versions of armadillo from the recipe * Move CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS definition to the CMake wrapper to avoid polluting library sources * Add deprecation notice for system library usage * Remove statements that manually modify the shared option of upstream dependencies. This will mean upstream dependencies will always be static libraries unless manually specified as shared libraries. * Clean up CMakeLists patch to remove references to system openblas and system hdf5 after removal of these options. * [armadillo] Update required version for CMake in CMake wrapper * Update required CMake version from 2.8.11 to 3.4 for CMakeLists wrapper. This is a requirement of CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS. * [armadillo] Add dummy intel_mkl option to be overridden by consumer * Add intel_mkl option to allow intel-mkl requirement to be overridden with a user specified recipe. This addresses the issue where CCI won't package closed source libraries. * [armadillo] Remove system_mkl as an option * Remove system_mkl as an option as intel_mkl has been added and users now have an ability to add their own recipes for closed source projects. * Add validation logic for cppstd * Only conduct cppstd validation logic if passed as a conan setting Co-authored-by: Uilian Ries Co-authored-by: Javier G. Sogo Co-authored-by: Uilian Ries --- recipes/armadillo/all/CMakeLists.txt | 8 + recipes/armadillo/all/conandata.yml | 9 + recipes/armadillo/all/conanfile.py | 321 ++++++++++++++++++ ...01-Guard-dependency-discovery-10.7.x.patch | 134 ++++++++ .../armadillo/all/test_package/CMakeLists.txt | 11 + .../armadillo/all/test_package/conanfile.py | 18 + .../armadillo/all/test_package/example.cpp | 159 +++++++++ recipes/armadillo/config.yml | 3 + 8 files changed, 663 insertions(+) create mode 100644 recipes/armadillo/all/CMakeLists.txt create mode 100644 recipes/armadillo/all/conandata.yml create mode 100644 recipes/armadillo/all/conanfile.py create mode 100644 recipes/armadillo/all/patches/0001-Guard-dependency-discovery-10.7.x.patch create mode 100644 recipes/armadillo/all/test_package/CMakeLists.txt create mode 100644 recipes/armadillo/all/test_package/conanfile.py create mode 100644 recipes/armadillo/all/test_package/example.cpp create mode 100644 recipes/armadillo/config.yml diff --git a/recipes/armadillo/all/CMakeLists.txt b/recipes/armadillo/all/CMakeLists.txt new file mode 100644 index 0000000000000..ec859e0f118e0 --- /dev/null +++ b/recipes/armadillo/all/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.4) +project(cmake_wrapper) + +include(conanbuildinfo.cmake) +conan_basic_setup() +set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS on) + +add_subdirectory("source_subfolder") diff --git a/recipes/armadillo/all/conandata.yml b/recipes/armadillo/all/conandata.yml new file mode 100644 index 0000000000000..dc9bed2fc2822 --- /dev/null +++ b/recipes/armadillo/all/conandata.yml @@ -0,0 +1,9 @@ +sources: + "10.7.0": + url: "http://sourceforge.net/projects/arma/files/armadillo-10.7.0.tar.xz" + sha256: "9bf60db6fd237721908747a0e56797b97b7ceae3603f2cca0b012a3b88265d3f" + +patches: + "10.7.0": + - patch_file: "patches/0001-Guard-dependency-discovery-10.7.x.patch" + base_path: "source_subfolder" diff --git a/recipes/armadillo/all/conanfile.py b/recipes/armadillo/all/conanfile.py new file mode 100644 index 0000000000000..8f4d9daa70616 --- /dev/null +++ b/recipes/armadillo/all/conanfile.py @@ -0,0 +1,321 @@ +from conans import ConanFile, CMake, tools +from conans.errors import ConanInvalidConfiguration +import os + + +class ArmadilloConan(ConanFile): + name = "armadillo" + license = "Apache-2.0" + url = "https://github.com/conan-io/conan-center-index" + homepage = "http://arma.sourceforge.net" + description = "Armadillo is a high quality C++ library for linear algebra and scientific computing, aiming towards a good balance between speed and ease of use." + topics = ( + "linear algebra", + "scientific computing", + "matrix", + "vector", + "math", + "blas", + "lapack", + "mkl", + "hdf5", + ) + settings = "os", "compiler", "build_type", "arch" + options = { + "shared": [True, False], + "fPIC": [True, False], + "use_blas": [ + False, + "openblas", + "intel_mkl", + "system_blas", + "system_flexiblas", + "framework_accelerate", + ], + "use_lapack": [ + False, + "openblas", + "intel_mkl", + "system_lapack", + "system_atlas", + "framework_accelerate", + ], + "use_hdf5": [True, False], + "use_superlu": [False, "system_superlu"], + "use_extern_rng": [True, False], + "use_arpack": [False, "system_arpack"], + "use_wrapper": [True, False], + } + default_options = { + "shared": False, + "fPIC": True, + "use_blas": "openblas", + "use_lapack": False, + "use_hdf5": True, + "use_superlu": False, + "use_extern_rng": False, + "use_arpack": False, + "use_wrapper": False, + } + # Values that must be set for multiple options to be valid + _co_dependencies = { + "intel_mkl": [ + "use_blas", + "use_lapack", + ], + "framework_accelerate": [ + "use_blas", + "use_lapack", + ], + } + exports_sources = ["CMakeLists.txt", "patches/*"] + generators = ( + "cmake", + "cmake_find_package", + ) + _cmake = None + + @property + def _source_subfolder(self): + return "source_subfolder" + + @property + def _build_subfolder(self): + return "build_subfolder" + + def config_options(self): + if self.settings.os == "Windows": + del self.options.fPIC + if self.settings.os == "Macos": + # Macos will default to Accelerate framework + self.options.use_blas = "framework_accelerate" + self.options.use_lapack = "framework_accelerate" + + def configure(self): + if self.options.shared: + del self.options.fPIC + + def validate(self): + if self.settings.compiler.cppstd: + tools.check_min_cppstd(self, "11") + + if self.settings.os != "Macos" and ( + self.options.use_blas == "framework_accelerate" + or self.options.use_lapack == "framework_accelerate" + ): + raise ConanInvalidConfiguration( + "framework_accelerate can only be used on Macos" + ) + + for value, options in self._co_dependencies.items(): + options_without_value = [ + x for x in options if getattr(self.options, x) != value + ] + if options_without_value and (len(options) != len(options_without_value)): + raise ConanInvalidConfiguration( + "Options {} must all be set to '{}' to use this feature. To fix this, set option {} to '{}'.".format( + ", ".join(options), + value, + ", ".join(options_without_value), + value, + ) + ) + + if ( + self.options.use_lapack == "openblas" + and self.options.use_blas != "openblas" + ): + raise ConanInvalidConfiguration( + "OpenBLAS can only provide LAPACK functionality when also providing BLAS functionality. Set use_blas=openblas and try again." + ) + + deprecated_opts = list( + set( + [ + opt + for opt in [ + str(self.options.use_blas), + str(self.options.use_lapack), + ] + if "system" in opt + ] + ) + ) + + for opt in deprecated_opts: + self.output.warn( + f"DEPRECATION NOTICE: Value {opt} uses armadillo's default dependency search and will be replaced when this package becomes available in ConanCenter" + ) + + def requirements(self): + # Optional requirements + # TODO: "atlas/3.10.3" # Pending https://github.com/conan-io/conan-center-index/issues/6757 + # TODO: "superlu/5.2.2" # Pending https://github.com/conan-io/conan-center-index/issues/6756 + # TODO: "arpack/1.0" # Pending https://github.com/conan-io/conan-center-index/issues/6755 + # TODO: "flexiblas/3.0.4" # Pending https://github.com/conan-io/conan-center-index/issues/6827 + + if self.options.use_hdf5: + # Use the conan dependency if the system lib isn't being used + self.requires("hdf5/1.12.0") + + if self.options.use_blas == "openblas": + self.requires("openblas/0.3.15") + # Note that if you're relying on this to build LAPACK, you _must_ have + # a fortran compiler installed. If you don't, OpenBLAS will build successfully but + # without LAPACK support, which isn't obvious. + # This can be achieved by setting the FC environment variable in your conan profile + self.options["openblas"].build_lapack = ( + self.options.use_lapack == "openblas" + ) + if ( + self.options.use_blas == "intel_mkl" + and self.options.use_lapack == "intel_mkl" + ): + # Consumers can override this requirement with their own by using + # self.requires("intel-mkl/version@user/channel, override=True) in their consumer + # conanfile.py + if ( + self.options.use_blas == "intel_mkl" + or self.options.use_lapack == "intel_mkl" + ): + self.output.warn( + "The intel-mkl package does not exist in CCI. To use an Intel MKL package, override this requirement with your own recipe." + ) + self.requires("intel-mkl/2021.4") + + def _configure_cmake(self): + if self._cmake: + return self._cmake + self._cmake = CMake(self) + self._cmake.definitions["ARMA_USE_LAPACK"] = self.options.use_lapack + self._cmake.definitions["ARMA_USE_BLAS"] = self.options.use_blas + self._cmake.definitions["ARMA_USE_ATLAS"] = ( + self.options.use_lapack == "system_atlas" + ) + self._cmake.definitions["ARMA_USE_HDF5"] = self.options.use_hdf5 + self._cmake.definitions["ARMA_USE_ARPACK"] = self.options.use_arpack + self._cmake.definitions["ARMA_USE_EXTERN_RNG"] = self.options.use_extern_rng + self._cmake.definitions["ARMA_USE_SUPERLU"] = self.options.use_superlu + self._cmake.definitions["ARMA_USE_WRAPPER"] = self.options.use_wrapper + self._cmake.definitions["ARMA_USE_ACCELERATE"] = ( + self.options.use_blas == "framework_accelerate" + or self.options.use_lapack == "framework_accelerate" + ) and self.settings.os == "Macos" + self._cmake.definitions["DETECT_HDF5"] = self.options.use_hdf5 + self._cmake.definitions["USE_OPENBLAS"] = self.options.use_blas == "openblas" + self._cmake.definitions["USE_MKL"] = ( + self.options.use_blas == "intel_mkl" + and self.options.use_lapack == "intel_mkl" + ) + self._cmake.definitions["USE_SYSTEM_LAPACK"] = ( + self.options.use_lapack == "system_lapack" + ) + self._cmake.definitions["USE_SYSTEM_BLAS"] = ( + self.options.use_blas == "system_blas" + ) + self._cmake.definitions["USE_SYSTEM_ATLAS"] = ( + self.options.use_lapack == "system_atlas" + ) + self._cmake.definitions["USE_SYSTEM_HDF5"] = False + self._cmake.definitions["USE_SYSTEM_ARPACK"] = self.options.use_arpack + self._cmake.definitions["USE_SYSTEM_SUPERLU"] = self.options.use_superlu + self._cmake.definitions["USE_SYSTEM_OPENBLAS"] = False + self._cmake.definitions["USE_SYSTEM_FLEXIBLAS"] = ( + self.options.use_blas == "system_flexiblas" + ) + self._cmake.definitions["ALLOW_FLEXIBLAS_LINUX"] = ( + self.options.use_blas == "system_flexiblas" and self.settings.os == "Linux" + ) + self._cmake.definitions["ALLOW_OPENBLAS_MACOS"] = ( + self.options.use_blas == "openblas" + ) and self.settings.os == "Macos" + self._cmake.definitions["ALLOW_BLAS_LAPACK_MACOS"] = ( + self.options.use_blas != "framework_accelerate" + ) + self._cmake.definitions["BUILD_SHARED_LIBS"] = self.options.shared + self._cmake.configure(build_folder=self._build_subfolder) + return self._cmake + + def source(self): + tools.get( + **self.conan_data["sources"][self.version], + strip_root=True, + destination=self._source_subfolder, + filename="{name}-{version}.tar.xz".format( + name=self.name, version=self.version + ), + ) + + def _patch_sources(self): + for patch in self.conan_data.get("patches", {}).get(self.version, []): + tools.patch(**patch) + + def build(self): + self._patch_sources() + cmake = self._configure_cmake() + cmake.build() + + def package(self): + self.copy("LICENSE.txt", dst="licenses", src=self._source_subfolder) + self.copy("NOTICE.txt", dst="licenses", src=self._source_subfolder) + cmake = self._configure_cmake() + cmake.install() + tools.rmdir(os.path.join(self.package_folder, "lib", "pkgconfig")) + tools.rmdir(os.path.join(self.package_folder, "share")) + + def package_info(self): + self.cpp_info.libs = ["armadillo"] + self.cpp_info.names["pkg_config"] = "armadillo" + + if self.settings.build_type == "Release": + self.cpp_info.defines.append("ARMA_NO_DEBUG") + + # The wrapper library links everything together. If disabled, system libs must be + # linked manually + if not self.options.use_wrapper: + self.cpp_info.defines.append("ARMA_DONT_USE_WRAPPER") + if self.options.use_blas == "framework_accelerate": + self.cpp_info.frameworks.append("Accelerate") + + if self.options.use_hdf5: + self.cpp_info.defines.append("ARMA_USE_HDF5") + else: + self.cpp_info.defines.append("ARMA_DONT_USE_HDF5") + + if self.options.use_blas: + self.cpp_info.defines.append("ARMA_USE_BLAS") + if self.options.use_blas == "system_blas" and not self.options.use_wrapper: + self.cpp_info.system_libs.extend(["blas"]) + else: + self.cpp_info.defines.append("ARMA_DONT_USE_BLAS") + + if self.options.use_lapack: + self.cpp_info.defines.append("ARMA_USE_LAPACK") + if ( + self.options.use_lapack == "system_lapack" + and not self.options.use_wrapper + ): + self.cpp_info.system_libs.extend(["lapack"]) + else: + self.cpp_info.defines.append("ARMA_DONT_USE_LAPACK") + + if self.options.use_arpack: + self.cpp_info.defines.append("ARMA_USE_ARPACK") + if not self.options.use_wrapper: + self.cpp_info.system_libs.extend(["arpack"]) + else: + self.cpp_info.defines.append("ARMA_DONT_USE_ARPACK") + + if self.options.use_superlu: + self.cpp_info.defines.append("ARMA_USE_SUPERLU") + if not self.options.use_wrapper: + self.cpp_info.system_libs.extend(["superlu"]) + else: + self.cpp_info.defines.append("ARMA_DONT_USE_SUPERLU") + + if self.options.use_lapack == "system_atlas": + self.cpp_info.defines.append("ARMA_USE_ATLAS") + if not self.options.use_wrapper: + self.cpp_info.system_libs.extend(["atlas"]) + else: + self.cpp_info.defines.append("ARMA_DONT_USE_ATLAS") diff --git a/recipes/armadillo/all/patches/0001-Guard-dependency-discovery-10.7.x.patch b/recipes/armadillo/all/patches/0001-Guard-dependency-discovery-10.7.x.patch new file mode 100644 index 0000000000000..340d746fc0c0b --- /dev/null +++ b/recipes/armadillo/all/patches/0001-Guard-dependency-discovery-10.7.x.patch @@ -0,0 +1,134 @@ +From d446f8cf36cf9e1232210038ec09a8590e8ab79e Mon Sep 17 00:00:00 2001 +From: Samuel Dowling +Date: Sun, 10 Oct 2021 16:35:30 +1030 +Subject: [PATCH] Guard dependency discovery + +* Add guards to prevent usage of custom cmake find package scripts. +--- + CMakeLists.txt | 73 +++++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 61 insertions(+), 12 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 7857f8c..77e2d46 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -274,7 +274,11 @@ if(APPLE) + set(ARMA_USE_ACCELERATE true) + + if(ALLOW_OPENBLAS_MACOS) +- include(ARMA_FindOpenBLAS) ++ if(USE_OPENBLAS) ++ find_package(OpenBLAS) ++ else() ++ set(OpenBLAS_FOUND NO) ++ endif() + message(STATUS "OpenBLAS_FOUND = ${OpenBLAS_FOUND}") + message(STATUS "") + message(STATUS "*** If use of OpenBLAS is causing problems,") +@@ -289,8 +293,16 @@ if(APPLE) + endif() + + if(ALLOW_BLAS_LAPACK_MACOS) +- include(ARMA_FindBLAS) +- include(ARMA_FindLAPACK) ++ if(USE_SYSTEM_BLAS) ++ include(ARMA_FindBLAS) ++ else() ++ set(BLAS_FOUND NO) ++ endif() ++ if(USE_SYSTEM_LAPACK) ++ include(ARMA_FindLAPACK) ++ else() ++ set(LAPACK_FOUND NO) ++ endif() + message(STATUS " BLAS_FOUND = ${BLAS_FOUND}" ) + message(STATUS "LAPACK_FOUND = ${LAPACK_FOUND}") + message(STATUS "") +@@ -329,14 +341,42 @@ if(APPLE) + + else() + +- include(ARMA_FindMKL) +- include(ARMA_FindOpenBLAS) +- include(ARMA_FindATLAS) +- include(ARMA_FindBLAS) +- include(ARMA_FindLAPACK) ++ if(USE_MKL) ++ find_package(MKL) ++ else() ++ set(MKL_FOUND NO) ++ endif() ++ ++ if(USE_OPENBLAS) ++ find_package(OpenBLAS) ++ else() ++ set(OpenBLAS_FOUND NO) ++ endif() ++ ++ if(USE_SYSTEM_ATLAS) ++ include(ARMA_FindATLAS) ++ else() ++ set(ATLAS_FOUND NO) ++ endif() ++ ++ if(USE_SYSTEM_BLAS) ++ include(ARMA_FindBLAS) ++ else() ++ set(BLAS_FOUND NO) ++ endif() ++ ++ if(USE_SYSTEM_LAPACK) ++ include(ARMA_FindLAPACK) ++ else() ++ set(LAPACK_FOUND NO) ++ endif() + + if(ALLOW_FLEXIBLAS_LINUX AND (${CMAKE_SYSTEM_NAME} MATCHES "Linux")) +- include(ARMA_FindFlexiBLAS) ++ if(USE_SYSTEM_FLEXIBLAS) ++ include(ARMA_FindFlexiBLAS) ++ else() ++ set(FlexiBLAS_FOUND NO) ++ endif() + endif() + + message(STATUS " MKL_FOUND = ${MKL_FOUND}" ) +@@ -470,7 +510,8 @@ if(DETECT_HDF5) + # HDF5_INCLUDE_DIRS is the correct include directory. So, in either case we + # can use the first element in the list. Issue a status message, too, just + # for good measure. +- list(GET HDF5_INCLUDE_DIRS 0 ARMA_HDF5_INCLUDE_DIR) ++ list(GET HDF5_INCLUDE_DIRS 1 ARMA_HDF5_INCLUDE_DIR) ++ + message(STATUS "ARMA_HDF5_INCLUDE_DIR = ${ARMA_HDF5_INCLUDE_DIR}") + message(STATUS "") + message(STATUS "*** If use of HDF5 is causing problems,") +@@ -480,7 +521,11 @@ if(DETECT_HDF5) + endif() + endif() + +-include(ARMA_FindARPACK) ++if(USE_SYSTEM_ARPACK) ++ include(ARMA_FindARPACK) ++else() ++ set(ARPACK_FOUND NO) ++endif() + message(STATUS "ARPACK_FOUND = ${ARPACK_FOUND}") + + if(ARPACK_FOUND) +@@ -488,7 +533,11 @@ if(ARPACK_FOUND) + set(ARMA_LIBS ${ARMA_LIBS} ${ARPACK_LIBRARY}) + endif() + +-include(ARMA_FindSuperLU5) ++if(USE_SYSTEM_SUPERLU) ++ include(ARMA_FindSuperLU5) ++else() ++ set(SuperLU_FOUND NO) ++endif() + message(STATUS "SuperLU_FOUND = ${SuperLU_FOUND}") + + if(SuperLU_FOUND) +-- +2.33.0 + diff --git a/recipes/armadillo/all/test_package/CMakeLists.txt b/recipes/armadillo/all/test_package/CMakeLists.txt new file mode 100644 index 0000000000000..708a6618b6043 --- /dev/null +++ b/recipes/armadillo/all/test_package/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.6) +project(PackageTest CXX) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup(TARGETS) + +find_package(armadillo REQUIRED) + +add_executable(example example.cpp) +target_link_libraries(example armadillo::armadillo) +set_property(TARGET example PROPERTY CXX_STANDARD 11) diff --git a/recipes/armadillo/all/test_package/conanfile.py b/recipes/armadillo/all/test_package/conanfile.py new file mode 100644 index 0000000000000..5eba7cbe1bb9c --- /dev/null +++ b/recipes/armadillo/all/test_package/conanfile.py @@ -0,0 +1,18 @@ +import os + +from conans import ConanFile, CMake, tools + + +class ArmadilloTestConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "cmake", "cmake_find_package" + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + if not tools.cross_building(self): + bin_path = os.path.join("bin", "example") + self.run(bin_path, run_environment=True) diff --git a/recipes/armadillo/all/test_package/example.cpp b/recipes/armadillo/all/test_package/example.cpp new file mode 100644 index 0000000000000..e3aad9e11dcb5 --- /dev/null +++ b/recipes/armadillo/all/test_package/example.cpp @@ -0,0 +1,159 @@ +#include +#include + +using namespace std; +using namespace arma; + +// Armadillo documentation is available at: +// http://arma.sourceforge.net/docs.html + +// NOTE: the C++11 "auto" keyword is not recommended for use with Armadillo objects and functions + +int +main(int argc, char** argv) + { + cout << "Armadillo version: " << arma_version::as_string() << endl; + + // construct a matrix according to given size and form of element initialisation + mat A(2,3,fill::zeros); + + // .n_rows and .n_cols are read only + cout << "A.n_rows: " << A.n_rows << endl; + cout << "A.n_cols: " << A.n_cols << endl; + + A(1,2) = 456.0; // access an element (indexing starts at 0) + A.print("A:"); + + A = 5.0; // scalars are treated as a 1x1 matrix + A.print("A:"); + + A.set_size(4,5); // change the size (data is not preserved) + + A.fill(5.0); // set all elements to a specific value + A.print("A:"); + + A = { { 0.165300, 0.454037, 0.995795, 0.124098, 0.047084 }, + { 0.688782, 0.036549, 0.552848, 0.937664, 0.866401 }, + { 0.348740, 0.479388, 0.506228, 0.145673, 0.491547 }, + { 0.148678, 0.682258, 0.571154, 0.874724, 0.444632 }, + { 0.245726, 0.595218, 0.409327, 0.367827, 0.385736 } }; + + A.print("A:"); + +#ifdef ARMA_USE_LAPACK + // determinant + cout << "det(A): " << det(A) << endl; + + // inverse + cout << "inv(A): " << endl << inv(A) << endl; +#else + cout << "LAPACK not available. Skipping calls to functions det() and inv()" << endl; +#endif + + // save matrix as a text file + A.save("A.txt", raw_ascii); + + // load from file + mat B; + B.load("A.txt"); + + // submatrices + cout << "B( span(0,2), span(3,4) ):" << endl << B( span(0,2), span(3,4) ) << endl; + + cout << "B( 0,3, size(3,2) ):" << endl << B( 0,3, size(3,2) ) << endl; + + cout << "B.row(0): " << endl << B.row(0) << endl; + + cout << "B.col(1): " << endl << B.col(1) << endl; + + // transpose + cout << "B.t(): " << endl << B.t() << endl; + + // maximum from each column (traverse along rows) + cout << "max(B): " << endl << max(B) << endl; + + // maximum from each row (traverse along columns) + cout << "max(B,1): " << endl << max(B,1) << endl; + + // maximum value in B + cout << "max(max(B)) = " << max(max(B)) << endl; + + // sum of each column (traverse along rows) + cout << "sum(B): " << endl << sum(B) << endl; + + // sum of each row (traverse along columns) + cout << "sum(B,1) =" << endl << sum(B,1) << endl; + + // sum of all elements + cout << "accu(B): " << accu(B) << endl; + + // trace = sum along diagonal + cout << "trace(B): " << trace(B) << endl; + + // generate the identity matrix + mat C = eye(4,4); + + // random matrix with values uniformly distributed in the [0,1] interval + mat D = randu(4,4); + D.print("D:"); + + // row vectors are treated like a matrix with one row + rowvec r = { 0.59119, 0.77321, 0.60275, 0.35887, 0.51683 }; + r.print("r:"); + + // column vectors are treated like a matrix with one column + vec q = { 0.14333, 0.59478, 0.14481, 0.58558, 0.60809 }; + q.print("q:"); + + // convert matrix to vector; data in matrices is stored column-by-column + vec v = vectorise(A); + v.print("v:"); + + // dot or inner product + cout << "as_scalar(r*q): " << as_scalar(r*q) << endl; + + // outer product + cout << "q*r: " << endl << q*r << endl; + + // multiply-and-accumulate operation (no temporary matrices are created) + cout << "accu(A % B) = " << accu(A % B) << endl; + + // example of a compound operation + B += 2.0 * A.t(); + B.print("B:"); + + // imat specifies an integer matrix + imat AA = { { 1, 2, 3 }, + { 4, 5, 6 }, + { 7, 8, 9 } }; + + imat BB = { { 3, 2, 1 }, + { 6, 5, 4 }, + { 9, 8, 7 } }; + + // comparison of matrices (element-wise); output of a relational operator is a umat + umat ZZ = (AA >= BB); + ZZ.print("ZZ:"); + + // cubes ("3D matrices") + cube Q( B.n_rows, B.n_cols, 2 ); + + Q.slice(0) = B; + Q.slice(1) = 2.0 * B; + + Q.print("Q:"); + + // 2D field of matrices; 3D fields are also supported + field F(4,3); + + for(uword col=0; col < F.n_cols; ++col) + for(uword row=0; row < F.n_rows; ++row) + { + F(row,col) = randu(2,3); // each element in field is a matrix + } + + F.print("F:"); + + return 0; + } + diff --git a/recipes/armadillo/config.yml b/recipes/armadillo/config.yml new file mode 100644 index 0000000000000..d1bb96966dc5f --- /dev/null +++ b/recipes/armadillo/config.yml @@ -0,0 +1,3 @@ +versions: + "10.7.0": + folder: all