rjhogan / Adept-2

Combined array and automatic differentiation library in C++
http://www.met.reading.ac.uk/clouds/adept/
Apache License 2.0
163 stars 29 forks source link

Add cmake build #12

Open kbthomp1 opened 5 years ago

kbthomp1 commented 5 years ago

Useful to for projects that use CMake as their build system. This exports a cmake target for the adept static library, and installs the adept heads along with a cmake config module.

ramcdona commented 3 years ago

I rebased this on top of main and put in some work updating it to the current state of Adept (some files have been added since Feb 2019).

Updates now at https://github.com/ramcdona/Adept-2/tree/add-cmake-build

I tried to replicate the autoconf dependency searches with CMake equivalents. I have not found a FindSACADO.cmake script, everything else should be there (though possibly not used for anything).

I worked to get all but one of the tests set up to build. test_adept_with_and_without_ad is the only one I haven't figured out so far.

I have not worked on the benchmarks or documentation at all. I also have not looked at the install target(s) -- ideally it would be a 1:1 match for the autoconf/automake version -- or any differences would be intentional and understood.

I have not worked to get the create_adept_source_header script to run. There may be a CMake cross-platform way to run this script.

I have not looked at creating config.h or config_platform_independent.h -- are these required for a CMake based system?

I have not added any CMake build documentation yet.

Eventually there should also be a FindAdept2.cmake script that Adept can provide for other projects to use. Ideally it would find an installed Adept whether it was built with autoconf/automake or CMake.

Only tested on MacOS so far.

ramcdona commented 3 years ago

I ported create_adept_source_header over to CMake, so adept_source.h is now created.

rjhogan commented 3 years ago

Thanks! Please tell me how to test this (what cmake command-line options).

Is there a need to recreate the hand-written test/Makefile? This is not touched by autotools. Perhaps it has things that won't work on Windows?

I have an autotools m4 script for other projects to find adept - would this be useful to you to make the cmake equivalent?

Autotools creates config.h and config_platform_independent.h with the settings, e.g. version number, compiler options used, whether lapack is available. Currently config.h is read in by adept/settings.cpp so that the compiled library can be queried or these options can be printed. It is also read in by adept/cppblas.cpp, adept/cpplapack.h and benchmark/differentiator.h to check whether BLAS, LAPACK and some other AD tools are available.

I think config_platform_independent.h is generated specifically to provide settings for adept_source.h, but I don't think it generates enough, e.g. ADEPT_VERSION_STR needed by the adept::version() function. This ought to be fixed, but I don't test adept_source.h regularly.

ramcdona commented 3 years ago

You can certainly wait to test it out -- bits are still in flux.

When Kyle developed this, he used something called 'Modern CMake'. I am much more accustomed to 'Ancient CMake' -- so it is taking me a little bit to figure everything out. In addition, I have some users stuck on RHEL/Centos 7 -- which only supports an archaic version of CMake. I'm debating whether to 'dumb down' to my level, or find some other solution.

In general, CMake works best if you build in a separate directory from your source.

cd ~ mkdir testing_stuff cd testing_stuff git clone https://github.com/ramcdona/Adept-2.git cd Adept-2 git checkout -b add-cmake-build origin/add-cmake-build cd .. mkdir build cd build cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=./fake_install ../Adept-2 make -j4 make test make install

CMAKE_INSTALL_PREFIX will override the default install destination and instead tell it to install in ./fake_install. This is great for avoiding sudo for 'make install', for testing, or for local builds, etc.

Instead of Release, you can use Debug, or RelWithDebInfo. If you don't specify anything, CMake will default to Debug -- which can be really annoying for programs that substantially slow down in Debug mode.

The above command (with no options) will use your OS's default compiler (cc and cxx) and will generate Makefiles.

If you want to specify alternate compilers, you can use -DCMAKE_C_COMPILER=/path/to/c/compiler -DCMAKE_CXX_COMPILER=/path/to/cxx/compiler

If you want to make some other kind of build files, you can use -G "Generator Name"

The available generators will vary based on your OS (MSVC only on Windows, XCode only on MacOS, etc.). To know which ones are available, run 'cmake --help'. The generators available to you will be listed at the bottom of the help. Note, you must match the full and complete generator name (they are long and often have spaces). eg. -G "Eclipse CDT4 - Ninja"

I like using the CLion IDE - which actually uses CMake files natively. When working with the command line, I tell CMake the compiler I want and do not specify a generator. That gives me Makefiles for command line use, but also works well with the CLion IDE. On Mac, I use XCode for the compiler, but Makefiles for the generator. I've never actually used the XCode IDE -- They tell me its nice...

I have already translated the hand-written test/Makefile to CMake. One test remains to get sorted. While you can certainly keep the old Makefiles (and automake, etc) system around, it is best to have a CMake version of everything, so if users are using a build system that is not Makefile based, they will still be able to build the tests, etc.

Thanks for clarifying the relationships for config.h and config_platform_independent.h -- I should be able to set up a CMake system to configure those files as well.

I can look at your autotools Adept helper - that might be interesting. In the Ancient CMake way, I would need/want to write a FindAdept2.cmake script. In the Modern CMake way, the cmake script sets up and builds its own files (placed in the install directory/cmake). When you then build a cmake based application, you find that directory and everything automagically works. I am very much still on the learning curve here...

Right now, I have searches in place for LAPACK and BLAS - but I have not checked if they are setting all the right flags to then be used by default.

There should probably be a mechanism to choose not to use external tools -- even if they are detected. I have not done that yet.

I did add -DBUILD_TESTING=false as an option to skip building the tests. They are quick, but most libraries have a similar option in case you are just building the libraries on a machine that you do not intend to develop them on.

rjhogan commented 3 years ago

Thanks! I had to use cmake with options "-B . -S ../Adept-2", rather than just "../Adept-2", otherwise it built in the ../Adept-2 directory, rather han the current directory. I am using cmake version 3.19.5, so is this because you're using an earlier version. The test files then run except for those using LAPACK and BLAS - e.g. test_minimizer reports that Adept is compiled without linear-algebra support. This is despite cmake telling me it has found them. It means that HAVE_LAPACK was not defined by cmake I guess. I've posted an autotools file for locating the Adept library: https://github.com/rjhogan/Adept-2/blob/master/m4/adept.m4 - perhaps it is useful to you. To be honest I'm not sure if it works if adept is in a system directory because we always compile adept to a local directory and then use "./configure --with-adept=/home/me/apps/adept-2.1".

ramcdona commented 3 years ago

I'm surprised you needed the -B and -S... I'm running 3.20.5 and haven't needed those options. Glad you got that sorted.

You are correct, I added CMake stuff to find auxiliary libraries like LAPACK and BLAS -- but I didn't make any attempt to make Adept actually use them yet. I was keeping it simple at first and mostly doing things that required CMake knowledge rather than Adept knowledge. This is still WIP.

CMake probably defines LAPACK_FOUND -- if your code depends on HAVE_LAPACK, then we'll need to define that when LAPACK_FOUND is true. Then, we may also need to add some include directories and libraries to the targets. It is all pretty straightforward stuff.

I am only working on MacOS right now - but I did have a colleague who ran through it on Windows with MSVC. It all worked smoothly the first try for him. So while still a WIP, things look reasonable.

It looks like my RHEL7 users can (at minimum) install a modern CMake in their local directory downloaded direct from Kitware, so my worry about needing to dumb everything down to CMake 2.8.x is not coming true. I was not charging forward with more changes until this got sorted...

Rob

On Sat, Jul 10, 2021 at 8:53 AM Robin Hogan @.***> wrote:

Thanks! I had to use cmake with options "-B . -S ../Adept-2", rather than just "../Adept-2", otherwise it built in the ../Adept-2 directory, rather han the current directory. I am using cmake version 3.19.5, so is this because you're using an earlier version. The test files then run except for those using LAPACK and BLAS - e.g. test_minimizer reports that Adept is compiled without linear-algebra support. This is despite cmake telling me it has found them. It means that HAVE_LAPACK was not defined by cmake I guess. I've posted an autotools file for locating the Adept library: https://github.com/rjhogan/Adept-2/blob/master/m4/adept.m4 - perhaps it is useful to you. To be honest I'm not sure if it works if adept is in a system directory because we always compile adept to a local directory and then use "./configure --with-adept=/home/me/apps/adept-2.1".

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/rjhogan/Adept-2/pull/12#issuecomment-877659509, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAKETQEJOYWC7U7HIIMNRK3TXBUHVANCNFSM4GZDFNTQ .