# PHAS0100 - week 5 ### 2pm-5pm Friday, 11th February 2022 :::info ## :tada: Welcome to the 5th live-class! #### Reminder: both groups are now merged into this Friday class ### Today Today we will ... - Review what you have learnt about libraries - Choose a library for our next project - Install a library using different methods ::: ### Group working - We will be working in groups of 3-5 people in the hands-on exercises. - You will populate this collaborative document with the relevant findings based upon discussions in your group ### Timetable for this afternoon | Start | End | Topic | Room | | -------- | -------- | -------- | ----- | | 14:00 | 14:15 | Intro + [Quiz](#Quiz) | Main | | 14:15 | 14:35 | [Group exercise on choosing a library](#Choosing-an-external-library) | Breakout-1 | | 14:35 | 14:55 | Write each group's inferences about the libraries on this HackMD collaborative doc | Breakout-1 | |14:55 | 15:05 | Break | ---| |15:05 | 15:10 | [Intro to using a library](#Using-an-external-library) | Main | |15:10 | 15:50 | Install a [library from the Ubuntu repos](#Installing-yaml-cpp-from-Ubuntu-20.04-LTS-repositories) and then [directly from developers](#Install-an-updated-version-directly-from-the-project-repository) | Breakout-2| |15:50 | 15:55 | Review | Main | |15:55 | 16:05 | Break | ---| |16:05 | 16:20 | [Adapt to use the library with CMake](#Adapt-to-use-the-library-with-CMake)| Breakout-3| |16:20 | 16:45 | [Using Eigen](#Using-Eigen) | Breakout-4| |16:45 | 16:55 | Summary of libraries, and intro to package managers | Main | ## Quiz :::success Access [menti.com](https://menti.com) and enter the code: **2184 3701** ::: ## Breakout session 1 ### Class Exercise 25 ### Choosing an external library ### Goal :::success :dart: Choose a units library for your next project. ::: :::info :information_source: For our project, we won't need something too complicated, only some speed conversions (m/s, km/h, mph, feet/s,...) and all the libraries mentioned below are able to do so. Therefore, don't focus as much in the technical capabilities of each. However, do consider the [points mentioned on our lesson about choosing a library][lesson-choose]. Each group will, together, analyse one of the following libraries. You have ~35-40 minutes in total. After perusing the library, you may discuss it internally within your group to evaluate it. Afterwards, write an itemised list of your important findings for public visibility in this collaborative document under the library heading that your group considered. ::: Breakout groups and libraries to consider: Group 1. [Units & measures][units-codeproject] Group 2. [Unit Conversion and Dimensional Analysis Library][units-nholthaus] Group 3. [mp-units][units-mp] Group 4. [Lawrence Livermore National Security **The Units** library][units-llns] Group 5. [Boost's units][units-boost] ### Itemised summary of each group's findings #### Group 1. [Units & measures][units-codeproject] - Header only - Code Project Open License (CPOL), very permissive, non-copyleft license - Well documented - Modular and intuitive design - Outdated (2017), multiple communication channels, but auther last responded to comments in 2017 - One person developer who is an enthusiast - Not implemented on GitHub - Not many downloads (~800) - Only 21 revisions (last 2017) #### Group 2. [Unit Conversion and Dimensional Analysis Library][units-nholthaus] - header only - 380 commits on the Github - built on c++14 with no dependencies - A compile-time, dimensional analysis library. - Have fixed compilation error when iostream was disabled. - Continuous Integration did not pass. - Unit tags and containers are split into separate namespaces to avoid conflicting - consists of a single header units.h, and can be included into your project without being built. - The library consists of a single file plus unit tests. To incorporate the library into your project, simply copy the header into a location in your include path or add the included CMake project into your build. - Only one communication channel, should give us more. - Why it takes so long to open it in container??? Over 10 mins passed, still not. That's True. #### Group 3. [mp-units][units-mp] ##### Library condition - 1. [x] The codes are readable. And efficiency. - 2. [x] Latest updates: 3 days ago - 3. [x] Connection with the contributor: Email, issues page on Github. reachable - 4. [x] Licence: MIT - 5. Commits: 1583 - 6. stars: 535 - 7. COntributors: 24 - 8. Issues: 54 - code tested? -> extensive tests in test directory - tutorial | ease of use : external page https://mpusz.github.io/units/introduction.html - - dependencies -> high number of dependencies scattered, not all included in the requirements.txt file ##### Basic functions - 1. Simple numeric operations ```cpp static_assert(10 * km / 2 == 5 * km); ``` - 2. Unit conversions ```cpp static_assert(1 * h == 3600 * s); ``` - 3. Dimension conversions ```cpp static_assert(1000 / (1 * s) == 1 * kHz); ``` #### Group 4. [Lawrence Livermore National Security **The Units** library][units-llns] ##### Strengths - supports a header only mode and a compiled mode - neat and organised documentation - option of static or shared library, installed like typical package - license, can redistribute in source and binary forms if you put the copy right - the warranties and fitness of purpose is displayed - license name bsd3 - provides low level documentation - incude 17 unit tests and several CI systems - the conversion also supports mathematical operations - very active testing on Github, most recent 11 days ago, more than 20 testing histories in recent 3 months - a lot of tests, 98% passing ##### Flaws - some of the test links are broken - "work in progress" so function names can change - string processing available in the compiled mode (to use full functionality need compiled) - cannot use name of copy right holder to endorse products - Azure Pipelines : Never Built - need at least Cpp 11, recommended Cpp 14 though #### Group 5. [Boost's units][units-boost] - Boost is a quasi-standard library, equivalent to the continuation and expansion of STL - No runtime execution cost is introduced - Open Source - Last updated March 2010 ### Online groups #### Group 1. [Units & measures][units-codeproject] - - - #### Group 2. [Unit Conversion and Dimensional Analysis Library][units-nholthaus] - - #### Group 3. [mp-units][units-mp] - - #### Group 4. [Lawrence Livermore National Security **The Units** library][units-llns] - header only (only 3 headers) - two commits on GH - last commit 2020 - Could be complete? - nope, there are two unresolved issues on GH - Detailed README - Has continuous integration with Github Actions - Has BSD3 license - some links in the readme are incorrect - high quality-seeming projects that are using the library: scipp and GridDyn - no compile-time checking of units - 3 contributors that seem very well qualified (SWEs) - tests look extensive (there's lots in test folders) - good code coverage #### Group 5. [Boost's units][units-boost] - - ### Optional extra material to consider outside class: _Relevant conference talk from CppCon2021 (optional material to watch outside of class hours)_: [Units Libraries and Autonomous Vehicles: Lessons from the Trenches](https://www.youtube.com/watch?v=QEBlaaht5cA). Dr Hogg, who has a Physics background, presented an overview of various technical and human factors to consider in developing and using a units library. [units-codeproject]: https://www.codeproject.com/Articles/1088293/Units-and-measures-for-Cplusplus [units-nholthaus]: https://github.com/nholthaus/units [units-mp]: https://github.com/mpusz/units [units-llns]: https://units.readthedocs.io/en/latest/ [units-boost]: https://www.boost.org/doc/libs/1_78_0/doc/html/boost_units.html [lesson-choose]: https://rits.github-pages.ucl.ac.uk/research-computing-with-cpp/05libraries/sec01ChoosingLibraries.html ## Breakout session 2 ### Class Exercise 26 ### Using an external library ### Goal :::success :dart: Use [`yaml-cpp`][yaml-cpp] to read the [given yaml file][yaml-code] for some simulation. 1. Using the yaml-cpp version provided by ubuntu (`apt`) 2. Using a newer release from the yaml-cpp developers ::: [yaml-cpp]: https://github.com/jbeder/yaml-cpp [yaml-code]: https://gist.github.com/krishnakumarg1984/011f259554ecb8f0a96ed735c1ac634b [lesson-library]: https://rits.github-pages.ucl.ac.uk/research-computing-with-cpp/05libraries/sec02LibraryBasics.html ### Setup :::info :information_source: 15-20 minutes to complete. Tutors can assist with install-related issues. ::: Create a new directory on your desktop ```bash mkdir week05 cd week05 git clone --recurse-submodules https://github.com/UCL/CMakeHelloWorld yaml-ex # In the command below, the trailing slash is important! ln -s yaml-ex/.devcontainer/ # Open the current folder on VSCode, via terminal or through VSCode itself code . # In the pop-up menu within VSCode, choose to "Reopen in container" ``` ### Installing yaml-cpp from Ubuntu 20.04 LTS repositories 1. Open a terminal window within the VSCode container instance. You should see ```bash vscode ➜ /workspaces/week05 (master ✗) $ ``` 1. Fetch the latest package update definitions from the Ubuntu repos using the package manager (`apt`). This can take a while. ```bash $ sudo apt update ``` Optionally (but not required for this exercise), you may want to upgrade any upgradable packages with: ```bash $ sudo apt upgrade -y # The optional 'y' (yes) flag in the above command serves to instruct Ubuntu to upgrade the packages without asking for a confirmation dialog. ``` 1. Install `apt-file` to know what files each package we install contains. ```bash $ sudo apt install apt-file ``` and update their list too: ```bash $ sudo apt-file update ``` 1. Search for `yaml-cpp`: ```bash $ apt search yaml-cpp ``` :::info There are two choices ... which one do we need? Use ```bash $ apt-file show <package_name> | less ``` to make the decision. Press `q` to quit `less`. ::: :::danger The `dev` version contains also the header files that we require. ::: 1. Install the relevant `yaml-cpp` package as follows ```bash $ sudo apt install <package_name> ``` :::danger the package name is: `libyaml-cpp-dev` ::: 1. Download/copy the [provided files][yaml-code] (cpp and yaml) to the `yaml-ex` folder and try to build it using `g++` command. From your lesson notes, do you [remember the procedure][lesson-library]? ```bash cd yaml-ex # Download the `config.yaml` and `useyaml.cpp` files in this folder before proceeding with the compilation step given below g++ useyaml.cpp -o useyaml -l yaml-cpp ``` 1. Run the code! ```bash ./useyaml ``` Open the generated output file (`result.yaml`) in the `yaml-ex` directory and inspect the value of metallicity. In particular, note its precision (number of significant digits) in the output file vs the result printed on the console. ### Install an updated version directly from the project repository You may have noticed that the metallicity result in the output file does has a lower precision than that reported on the console. This was a [bug][yaml-cpp-bug] that was reported to the developers which was fixed in [a newer release](https://github.com/jbeder/yaml-cpp/pull/649). Let's install the latest release then. 1. Make sure your version (from the Ubuntu repos) is indeed older than the latest one [in GitHub][yaml-cpp]. ```bash $ apt show <package_name> ``` The version of the library in Ubuntu 20.04.3 LTS repos is `0.6.2`. 2. Download the latest release of the library to the project folder (`week0`5`): ```bash $ cd /workspaces/week05 ``` :::spoiler with git tags ```bash $ git clone https://github.com/jbeder/yaml-cpp $ cd yaml-cpp $ git checkout -b 0.7.0 tags/yaml-cpp-0.7.0 ``` ::: :::spoiler with curl You can get the tar or zip file from the GitHub [releases page][yaml-release] ```bash $ curl -LO https://github.com/jbeder/yaml-cpp/archive/yaml-cpp-0.7.0.tar.gz $ tar zxf yaml-cpp-0.7.0.tar.gz --transform s/yaml-cpp-yaml-cpp-0.7.0/yaml-cpp/ $ cd yaml-cpp ``` ::: [yaml-release]: https://github.com/jbeder/yaml-cpp/releases 3. Build the library as a shared library ```bash $ mkdir build; cd build $ cmake .. -DYAML_BUILD_SHARED_LIBS=ON # In the below step, just using `make` by itself, will build a lot of targets, including the tests, some of which are likely to fail due to various dependency issues and due to warnings being treated as errors in the compile configuration $ make yaml-cpp ``` 4. Go to your code and build it now using the newer yaml-cpp. ```bash $ cd ../../yaml-ex # or: cd /workspaces/week05/yaml-ex $ g++ useyaml.cpp -o useyaml -I ../yaml-cpp/include -L ../yaml-cpp/build/ -l yaml-cpp ``` 5. Run it ```bash $ ./useyaml ``` 6. __Does it work__ if you try to run it? Hint: Use the `ldd` command to verify the exact path to the shared libraries your executable uses. :::spoiler Tell your program where to look for the shared library. There is a variable that your OS looks for when looking for libraries: `LD_LIBRARY_PATH` ```bash $ export LD_LIBRARY_PATH="/workspaces/week05/yaml-cpp/build:${LD_LIBRARY_PATH}" $ ./useyaml ``` ::: 7. Does the updated library result in an improved precision for metallicity in the generated output file? [yaml-cpp-bug]: https://github.com/jbeder/yaml-cpp/issues/469 ## Breakout session 3 ### Class Exercise 27 ### Adapt to use the library with CMake :::success :dart: Use [`yaml-cpp`][yaml-cpp] to read the [given yaml file][yaml-code] for some simulation. Using the new version of yaml-cpp with CMake ::: :::info :watch: 20 minutes ::: 1. Change the `CMakeLists.txt` to include the library. How would you do it? Check that you get the same results as the manual compilation result on the command line. [yaml-cpp]: https://github.com/jbeder/yaml-cpp [yaml-release]: https://github.com/jbeder/yaml-cpp/releases [yaml-code]: https://gist.github.com/dpshelio/259f84836a4ee2759a7edd2ab6d90ee6 [lesson-library]: https://rits.github-pages.ucl.ac.uk/research-computing-with-cpp/05libraries/sec02LibraryBasics.html [yaml-cpp-bug]: https://github.com/jbeder/yaml-cpp/issues/469 [conan-guide]: https://docs.conan.io/en/latest/getting_started.html [hunter-guide]:https://hunter.readthedocs.io/en/latest/quick-start/boost-components.html [hunter-yaml]: https://hunter.readthedocs.io/en/latest/packages/pkg/yaml-cpp.html [cpm-guide]: https://github.com/cpm-cmake/CPM.cmake#adding-cpm ## Breakout session 4 ### Class Exercise 28 ### Using Eigen :::info :information_source: [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) is a C++ template library for linear algebra (matrices, vectors, numerical solvers, etc.) ::: :::success :dart: Add the example provided below that uses Eigen to your project and any other required dependency. ::: 1. Add Eigen to your CMake project using any of the following methods - There is a `FindEigen.cmake` module available if you want to use that. Alternatively, you may use CMake's `find_package` functionality to integrate Eigen into your project as described in the documentation given [here](https://eigen.tuxfamily.org/dox/TopicCMakeGuide.html). - Have a look at the [CMakeCatch2 template repo][cmakecatch2] and see whether you understand how it's included in that project 2. Use this short example which employs `Eigen` :::spoiler Example code using matrix operations ```cpp #include <iostream> #include <Eigen/Dense> int main() { Eigen::Matrix2d m(2,2); m(0,0) = 3; m(1,0) = 2.5; m(0,1) = -1; m(1,1) = m(1,0) + m(0,1); std::cout << "m(2,2) \n" << m << std::endl; Eigen::Vector3d vr(3); vr << 1, 0, 1; Eigen::Matrix3d corners(3, 3); corners << vr * vr.transpose(); std::cout << "corners matrix:\n" << corners << std::endl; Eigen::MatrixXd X = Eigen::MatrixXd::Random(5,5); std::cout << "A random matrix X: \n" << X << "\n Its inversed X^-1: \n" << X.inverse() << "\nis X * X^-1 == I? " << std::boolalpha << (X * X.inverse()).isApprox(Eigen::MatrixXd::Identity(5, 5)) << std::endl; } ``` ::: 3. Include the above code in your project, build and run. [cmakecatch2]: https://github.com/UCL/CMakeCatch2 ### Introduction to C++ Package Managers - [Conan](https://docs.conan.io/en/latest/getting_started.html) - [Hunter](https://hunter.readthedocs.io/en/latest/) - [CMake Package Manager (CPM)](https://github.com/cpm-cmake/CPM.cmake) - [vcpkg](https://vcpkg.io/en/index.html) ## Homework exercise 29 ### Using the Conan package manage :dart: Include [`yaml-cpp`][yaml-cpp] to read the [given yaml file][yaml-code] into your project. 1. Install conan and find the yaml-cpp library ```bash $ sudo apt install python3-pip $ pip3 install conan $ conan search yaml-cpp --remote=conan-center $ conan profile new default --detect $ conan profile update settings.compiler.libcxx=libstdc++11 default ``` 1. Follow the [conan guide][conan-guide] to do the following steps: 1. Create the [`conanfile.txt`][conan-guide] 2. Run the conan install 3. Modify cmake to include the new created files 4. Build and run ## Homework exercise 30 ### Using a json library - Convert the [yaml-code] example to use a json library, for example [nlohmann's json][json-nlohmann]. - Include this JSON library (using one of the many ways i.e. manually, using CMake modules or using a package manager) to your project. Use this [json file][json-data]. [json-nlohmann]: https://json.nlohmann.me/ [json-data]: https://gist.github.com/krishnakumarg1984/f62c9a1df4ac6db3fdc6fab2d69ed1f6 [boost-solarsystem]: https://www.boost.org/doc/libs/1_78_0/libs/numeric/odeint/doc/html/boost_numeric_odeint/tutorial/solar_system.html # Questions Here you can post any question you have while we are going through this document. A summary of the questions and the answers will be posted in moodle after each session. Please, use a new bullet point for each question and sub-bullet points for their answers. For example writing like this: ``` - Example question - [name=student_a] Example answer - [name=TA_1] Example answer ``` produces the following result: - Example question - [name=student_a] Example answer - [name=TA_1] Example answer Write new questions below :point_down: - [name=] - [name=TA_1] Example answer ###### tags: `phas0100` `teaching` `class`