.. _ch02-fortran-blas-lapack: ============================================================= External Libraries for Scientific Computing ============================================================= Advantages of using external libraries ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Very rarely will you write software in total isolation, and frequently you will want to rely on existing implementations for some components of your code. This lets you focus on the overall purpose of the code while letting others write and maintain some general purpose routines. Common examples are numerical linear algebra routines, (binary format) I/O, parallel load distribution and communication, etc. This approach not only saves you effort and time, but also keeps your code computationally efficient and compatible across various platforms (as long as the external libraries are continuously supported and maintained). About BLAS and LAPACK ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In this section we learn how to install external software packages. We are going to search for them, compile them to produce libraries, then include and link those libraries so that you may call them from your code. Two of the most popular examples of external libraries, especially for scientific computing, are `BLAS `_ (Basic Linear Algebra Subroutines) and `LAPACK `_ (Linear Algebra PACKage). Linear algebra is a fundamental building block of numerical methods, and hence these libraries are fundamental building blocks for many scientific codes. They are both freely-available and allow users to call various linear algebra subroutines in their programs. Indeed, linear algebra powers a great deal of scientific computing. The BLAS package is a *reference* Fortran library. It is a collection of fundamental linear algebra routines that comprise standard building blocks for vector and matrix operations. These basic operations have been heavily optimized and are incredibly fast. For this reason, many numerical software packages (including LAPACK, LINPACK, OCTAVE, MATLAB, Mathematica, NumPy, and R) adopt BLAS and develop their linear algebra software as BLAS-compatible libraries. LAPACK is an improved version of LINPACK, which provides standard numerical linear algebra routines using BLAS as a building block for its implementation. That is to say, routines in LAPACK perform computations by calling the routines from BLAS. With BLAS and LAPACK installed you will have access to all of the implemented linear algebra routines from your own code, including: * solving systems of linear equations, * solving least squares problems, * eigenvalue decompositions, * singular value decompositions, * random number generation * and more... The naming convention for the subroutines is a little old-school. The `LAPACK name conventions `_) page has more information on the topic. See also: * `BLAS-wiki `_ * `LAPACK-wiki `_ Installing BLAS and LAPACK ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Since LAPACK routines call the BLAS routines, you have to install the BLAS library first before installing LAPACK. There is one important question to ask before beginning: Where do you want to install and run the packages? Do you want to install them system-wide? For only one user? If you are a Linux or MacOS user then there is chance that these libraries are already present on your machine. Otherwise they can easily be obtained from your system's package manager, which might look like: .. code-block:: console $ # On Ubuntu or Debian $ sudo apt install libblas-dev liblapack-dev $ # Or on Arch derivatives $ sudo pacman -S lapack blas **Remark** You can often install the LAPACK documentation directly to your machine. This will provide `man-pages` for the LAPACK routines which can be quite helpful If you are a Mac user, then it is quite likely that BLAS and LAPACK are already present on your machine. Try looking in the ``/usr/lib`` directory for entries containing lapack in their name: .. code-block:: console $ cd /usr/lib/ $ ls -al $ ... $ liblapack.dylib -> ../../System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib The ``->`` means that the default provided library file ``liblapack.dylib`` in ``/usr/lib/`` is a `symbolic link` to the file called ``libLAPACK.dylib`` buried under that long path. To further check if you have the BLAS and LAPACK properly installed already, download the code below: .. literalinclude:: ./codes/lapack/linear/solve1.f90 :language: fortran :linenos: :download:`Download this code <./codes/lapack/linear/solve1.f90>` and compile ``solve1.f90`` using the LAPACK library flag ``-llapack`` (actually you can check out this flag by compiling *any* Fortran code which doesn't even call any LAPACK routines) .. code-block:: console $ gfortran solve1.f90 -o solve1.ex -llapack If you see a message such as .. code-block:: console ld: library not found for -llapack then you'll need to install the BLAS/LAPACK on your machine. .. note:: I *strongly* recommend installing BLAS and LAPACK through your package manager. If you can not install BLAS and LAPACK from your package manager, then proceed below for installing from source. The ubiquity of BLAS and LAPACK make them commonly available, however other libraries that you may want to use will only be available as source. The instructions below for LAPACK illustrate a fairly common procedure for this type of installation. BLAS installation from source: ######################################### .. note:: The current Lapack source distribution includes BLAS. This step is retained in case you need it, but most people should skip ahead to the next section. a. You need to first install the BLAS library. You can download a tarball ``blas-3.10.0.tgz`` directly from `the BLAS website `_. #. Untar it using: .. code-block:: console $ tar -xvf blas-3.10.0.tgz #. Upon untarring, you will see a BLAS source file directory. ``cd`` into it and verify that the contents of ``make.inc`` match your system. Then compile the full library by calling .. code-block:: console $ make all You have now created a static BLAS library that you can link to your code. .. note:: If you wish to learn more about the command ``ar`` on Linux/Unix, please check out the following articles: `article-ar-fortran `_, `article-ar-C `_, `lib-name.a convention `_. Installing LAPACK from source: ######################################### a. As before, you can download a tarball ``lapack-3.10.0.tgz`` from `the LAPACK website `_. .. code-block:: console $ cd $HOME/packages $ tar -xvzf lapack-3.10.0.tar.gz #. Go to the directory .. code-block:: console $ cd lapack-3.10.0 $ cp make.inc.example make.inc #. Edit ``make.inc`` if needed. Here you can specify what compiler to use, what flags to use, and whether or not the included BLAS library should also be built. #. You're now ready to compile LAPACK by typing .. code-block:: console $ make or you can run make in a parallel mode .. code-block:: console $ make -j where N = 2, 4, or any number up to the number of threads that your machine has. .. note:: There is a primary ``Makefile`` which calls ``make.inc`` in the same directory. You may want to take a look at the makefile to see how it works internally. .. note:: Note that ``-lblas`` option does not look for ``blas.o``, but ``libblas.a`` for a statically linked version of the library, or ``libblas.so`` for a shared library. .. note:: As just mentioned, the correct way to link a *static library* (i.e., ``*.a`` files) is using ``-l``, but that only works if the library can be found on the search path, ``$PATH``. On the other hand, you can direct the compiler to correct location by using the ``-L`` flag followed by the directory. On the other hand, if you're interested in linking a *shared library* (i.e., ``*.so`` files), you define an environment variable, ``LD_LIBRARY_PATH`` which include the directory paths to the target shared library (see more `howto-sharedLib `_). Also see an article on their differences `article-shared-static `_. .. note:: Also the order matters. The linker processes its input files in the order in which they appear on the command line -- left to right. See `article `_. Also read: #. `article 1 `_ #. `article 2 `_ #. `article 3 `_ Testing your installation ######################################### With these you should be able to run the codes below: .. literalinclude:: ./codes/lapack/linear/solve1.f90 :language: fortran :linenos: :download:`Download this code <./codes/lapack/linear/solve1.f90>` .. literalinclude:: ./codes/lapack/linear/Makefile :language: make :linenos: :download:`Download this code <./codes/lapack/linear/Makefile>` Note in the above ``Makefile``, it is important to include ``$(LFLAGS)`` *after* ``solve1.o`` so that ``solve1.o`` can refer to the libraries. Not doing so can cause issues on some systems. The following programs construct and solve random linear systems of various sizes. .. literalinclude:: ./codes/lapack/linear/init_random_seed.f90 :language: fortran :linenos: :download:`Download this code <./codes/lapack/linear/init_random_seed.f90>` .. literalinclude:: ./codes/lapack/linear/randomsys1.f90 :language: fortran :linenos: :download:`Download this code <./codes/lapack/linear/randomsys1.f90>` .. literalinclude:: ./codes/lapack/linear/randomsys2.f90 :language: fortran :linenos: :download:`Download this code <./codes/lapack/linear/randomsys2.f90>` .. literalinclude:: ./codes/lapack/linear/randomsys3.f90 :language: fortran :linenos: :download:`Download this code <./codes/lapack/linear/randomsys3.f90>` Some more references: * `LAPACK `_ * `LAPACK User's Guide `_ * `Automatically Tuned Linear Algebra Software (ATLAS) `_ * ``_