Skip to content
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

armadillo/10.7.0 #7334

Merged
merged 20 commits into from
Oct 25, 2021
Merged

Conversation

samuel-emrys
Copy link
Contributor

@samuel-emrys samuel-emrys commented Sep 18, 2021

Specify library name and version: armadillo/10.6.1

Armadillo is a math library that I'd like to use. From a quick survey it's a dependency of the following packages:

It's also on the list of most relevant c++ libraries not already packaged:

This recipe is designed to be as true to the original packaging as it feasibly could. Of note, this means:

By default, this package utilises OpenBLAS to fulfill its BLAS and LAPACK requirements. It uses OpenBLAS by default on Linux and Windows operating systems, and configures it to build with LAPACK support. On Macos, it's configured to use the Accelerate framework by default. This usage of OpenBLAS introduces an upstream system dependency on a fortran compiler in order to provide LAPACK support.

Armadillo is capable of running without LAPACK support, however it only runs with a subset of features and the provided example code will fail with an error indicating LAPACK functionality needs to be provided when attempting to execute a command that requires it.

Of note, this recipe will introduce opaque errors if the usage of LAPACK is not disabled and a fortran compiler is not present on the system. This is because OpenBLAS will continue to build when configured to build with LAPACK, even when it can't find a fortran compiler. In this case, it will build with BLAS support only, and defer this problem downstream to the consumer. Armadillo will also build successfully, however it will have linked against the LAPACK symbols, and so any consumer usage of the resulting library will result in unresolved symbol errors. I've raised #7294 to address this issue and trigger a failure if a fortran compiler is not found.

I'm looking for some feedback on this recipe, specifically:

  • Are we happy to accept the ability to toggle on usage of system libraries?
    • My thoughts are that this will be good in the mid-term until the above libraries can be packaged in conan. The only system requirement imposed currently is fortran, which is really a requirement of the upstream OpenBLAS recipe so it should be possible for users to use this recipe in its default configuration if they have a fortran compiler. If they don't, BLAS or LAPACK functionality can be turned off to provide whatever functionality is required, or augmented with system libraries as required.
  • I've got a number of replace_in_file calls in the recipe - are these better placed as patches?
  • Is there a better way of managing co-dependent/mutually exclusive options than what I've done here?
  • Are there any other improvements that can be made?

I'm not the author of this library.

Closes #6754

  • I've read the guidelines for contributing.
  • I've followed the PEP8 style guides for Python code in the recipes.
  • I've used the latest Conan client version.
  • I've tried at least one configuration locally with the
    conan-center hook activated.

* 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 conan-io#6754.
* 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.
* Set ARMA_USE_ACCELERATE to False instead of deleting it when the
  operating system is not Macos. This facilitates proper option
  dependency testing.
@conan-center-bot

This comment has been minimized.

@samuel-emrys
Copy link
Contributor Author

Does the CI not attempt to build upstream dependencies? Also, as per the description, the success of these CI runs will depend on fortran compiler availability in the CI. This statement leads me to believe that this should be available?

recipes/armadillo/all/conanfile.py Outdated Show resolved Hide resolved
recipes/armadillo/all/conanfile.py Outdated Show resolved Hide resolved
@samuel-emrys samuel-emrys changed the title Recipe/armadillo armadillo/10.6.1 Sep 20, 2021
@conan-center-bot

This comment has been minimized.

* 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.
@conan-center-bot

This comment has been minimized.

* 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.
@conan-center-bot

This comment has been minimized.

* 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.
@conan-center-bot

This comment has been minimized.

Copy link
Contributor

@jgsogo jgsogo left a comment

Choose a reason for hiding this comment

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

I'm a bit concerned about the options and their logic. There is no need to map all the options in CMakeLists.txt to Conan options, sometimes a different approach is more convenient.

Some comments about them:

  • we try to use lowercase names for options

  • sometimes mutually exclusive options can be turned into choice ones:

    "use_blas": [False, "openblas", "system_openblas", "mkl", "flexiblas", "system_blas", "framework_accelerate"]
    
    [...]
    
    self._cmake.definitions["USE_OPENBLAS"] = self.options.blas
    self._cmake.definitions["USE_SYSTEM_BLAS"] = (self.options.blas == "system_blas")
    self._cmake.definitions["USE_OPENBLAS"] = (self.options.blas == "openblas")
    ...

recipes/armadillo/all/test_package/CMakeLists.txt Outdated Show resolved Hide resolved
recipes/armadillo/all/test_package/conanfile.py Outdated Show resolved Hide resolved
* Configure test_package to use targets

Co-authored-by: Javier G. Sogo <jgsogo@gmail.com>
@samuel-emrys
Copy link
Contributor Author

I'm a bit concerned about the options and their logic. There is no need to map all the options in CMakeLists.txt to Conan options, sometimes a different approach is more convenient.

Some comments about them:

* we try to use lowercase names for options

* sometimes mutually exclusive options can be turned into _choice_ ones:
  ```python
  "use_blas": [False, "openblas", "system_openblas", "mkl", "flexiblas", "system_blas", "framework_accelerate"]
  
  [...]
  
  self._cmake.definitions["USE_OPENBLAS"] = self.options.blas
  self._cmake.definitions["USE_SYSTEM_BLAS"] = (self.options.blas == "system_blas")
  self._cmake.definitions["USE_OPENBLAS"] = (self.options.blas == "openblas")
  ...
  ```

I tried to mimic the configuration options that match the documentation as closely as possible to make it easy for users to rely on the documentation as much as possible and less inference about what the recipe requires.
Having said that, I can see the utility in presenting mutually exclusive options this way - much simpler and cleaner. I didn't realise the options could be specified this way, though it makes sense looking back at it now. I'll try to refactor using this principle where i can

@conan-center-bot

This comment has been minimized.

* 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.
@samuel-emrys
Copy link
Contributor Author

samuel-emrys commented Sep 29, 2021

The CI tests here are being affected by the fact that the documentation for apple-clang indicates the default C++ language standard is gnu++14, however the language standard is actually gnu++98 by default. I'm not sure which is what it should be, but Armadillo requires C++11 or higher to compile, so on Macos the tests fail (pass?) with invalid configuration errors.

@conan-center-bot

This comment has been minimized.

@conan-center-bot

This comment has been minimized.

* Update required CMake version from 2.8.11 to 3.4 for CMakeLists
  wrapper. This is a requirement of CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.
@conan-center-bot

This comment has been minimized.

@samuel-emrys
Copy link
Contributor Author

samuel-emrys commented Oct 6, 2021

@samuel-emrys , please, have a look at this PR #7477. We think it can be a good way to handle these close source packages in the future. Of course, Conan will fail if the user tries to activate those options, but there should be a comment clarifying that they should provide the reference themselves. wdty?

Thanks!

@jgsogo Is this something that I should incorporate in to this package now?

* 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.
@conan-center-bot

This comment has been minimized.

* 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.
@conan-center-bot

This comment has been minimized.

* Only conduct cppstd validation logic if passed as a conan setting

Co-authored-by: Uilian Ries <uilianries@gmail.com>
@conan-center-bot
Copy link
Collaborator

All green in build 19 (76c01b99d8187b102a745b019740d5925bb50424):

  • armadillo/10.7.0@:
    All packages built successfully! (All logs)

@samuel-emrys
Copy link
Contributor Author

Is there anything I can do to move this forward?

Copy link
Member

@uilianries uilianries left a comment

Choose a reason for hiding this comment

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

LGTM

Thank you for hard working on this.

Copy link
Contributor

@jgsogo jgsogo left a comment

Choose a reason for hiding this comment

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

Agree, we can try to merge and iterate later.

@darcamo
Copy link
Contributor

darcamo commented Oct 25, 2021

I have created my own armadillo recipe, along with others recipes that I need that are/were not in conan center. I decided to finally investigate how I could include it in conan center when I found this recipe already in a very good shape. This recipe seems well written and I can imagine how much work was put into this. I have just a few pointers that you might consider looking at before merging it.

  • Enabling the option use_wrapper results in link errors when consuming the library. I also have this problem in my own recipe and I didn't find a solution for this. It is worth testing if you have the same problem, in which case it might be better to suppress this option until/if if can be made to work correctly (IMHO).

  • With use_wrapper option set to False, I don't think the use_extern_rng option is having any effect. The reason is that when use_extern_rng is set to True it will set a define in CMake. However, that is only used when you compile the armadillo wrapper library. When the wrapper library is not created, armadillo is used as a header only library and you need to define ARMA_USE_EXTERN_RNG to use the external random generator from C++11. The way I implemented this in my own recipe was adding the code below in the package_info method

    if self.options.use_extern_rng:
        self.cpp_info.defines.append("ARMA_USE_EXTERN_RNG")

    To test that the use_extern_rng currently has no effect (with use_wrapper set to False) you can run the program below with use_extern_rng set to False and later with it set to True. You will get exactly the same values in both cases indicating that the option is not really used.

    #include <armadillo>
    #include <iostream>
    
    int main(int argc, char *argv[])
    {
        arma::vec v{1,2,3,4};
        v.print("v");
    
        arma::arma_rng::set_seed(1237);
        v.randn();
        v.print("v");
    
        return 0;
    }

    Now try adding #define ARMA_USE_EXTERN_RNG before including armadillo and you will get different numbers in the vector.

  • Armadillo's current stable version is 10.7.1

@uilianries
Copy link
Member

@darcamo Thank you for your review! Indeed Armadillo requires a lot of effort to be package. Any PR will be very welcome, you can open a PR directly to Samuel's repository, or wait for this PR be merged (which is very close) and open a PR to Conan Center Index instead.

Copy link
Contributor

@prince-chrismc prince-chrismc left a comment

Choose a reason for hiding this comment

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

Let's improve it in the next PR

@conan-center-bot conan-center-bot merged commit 8e7b69a into conan-io:master Oct 25, 2021
@samuel-emrys
Copy link
Contributor Author

* Enabling the option `use_wrapper` results in link errors when consuming the library. I also have this problem in my own recipe and I didn't find a solution for this. It is worth testing if you have the same problem, in which case it might be better to suppress this option until/if if can be made to work correctly (IMHO).

I've just done some testing and have confirmed that it does fail in some cases, but not all. Specifically, it fails when built with lapack. I remember finding a resolution to this in the past - but the solution is escaping me right now. From memory part of the issue was building armadillo as a static library with dependencies on shared libraries upstream, especially in the context of using the system lapack.

Regardless, I've raised #7840 to discuss and track this issue further.

@darcamo
Copy link
Contributor

darcamo commented Nov 1, 2021

I have created a pull-request (#7919) to add the missing define.

ivanvurbanov pushed a commit to ivanvurbanov/conan-center-index that referenced this pull request Dec 2, 2021
* 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 conan-io#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 <jgsogo@gmail.com>

* [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 <uilianries@gmail.com>

* 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 <uilianries@gmail.com>

* [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
  conan-io/python-patch-ng#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 <uilianries@gmail.com>

Co-authored-by: Javier G. Sogo <jgsogo@gmail.com>
Co-authored-by: Uilian Ries <uilianries@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[request] armadillo/10.6.1
8 participants