.. _ch02-fortran-blas-lapack: ============================================================= External Libraries for Scientific Computing ============================================================= Advantages of using external libraries ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Many times, you may find it useful and convenient to install softwares which have been developed and written by others. In this way, you can simply focus more on writing kernel parts of your main algorithms, leaving others to write the rest of numerical subroutines for you. Examples of such routines may vary depending on your needs, but in general, some of the popular choices are numerical linear algebra, I/O, parallel load distributions, mesh generations, etc. This approach not only saves your efforts and time, but also keeps your kernal algorithms computationally efficient and compatible on various platforms as long as the external libraries are continuosly 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, include and link those libraries to compile with your Fortran subroutines. Two most popular examples of external libraries, especially for scientific computing, are the `BLAS `_ (Basic Linear Algebra Subroutines) and `LAPACK `_ (Linear Algebra PACKage) packages. They are both freely-available softwares which allow users to call various linear algebra subroutines in their programs. The BLAS package is originally a *reference* Fortran library. It is a collection of *basic* linear algebra routines that are standard buidling blocks for basic vector and matrix operations. With this reason, many numerical software packages (including LAPACK, LINPACK, OCTAVE, MATLAB, Mathematica, NumPy, and R) adopts the BLAS and develop their linear algebra softwares as BLAS-compatible libraries. LAPACK is an improved version of LINPACK, which provides a standard numerical linear algebra routines using the BLAS library as a buidling block implementation. That is to say, routines in LAPACK perform computations by calling the routines of the BLAS. With BLAS and LAPACK, you can call `routines in LAPACK `_ from your routines to perform mathematical operations in numerical linear algebra such as (see also `the LAPACK name conventions `_): * solving system of linear equations, * least-square problems, * eigenvalue problems, * singular value problems, * random number generations, etc. 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 begining: Where do you want to install and run the packages? If you are a Mac user, there is no need to install them because Mac comes with BLAS and LAPACK since Maverick. You can see an already compiled LAPACK library in:: $ cd /usr/lib/ $ ls -all $ ... $ 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`` in the location. To further check if you have the BLAS and LAPACK properly installed already, go to ``lectureNote/chapters/chapt02/codes/lapack/linear`` and compile ``solve1.f90`` using the LAPACK library flag ``-llapack`` (basically you can check out this flag by compiling *any* Fortran code which doesn't even call any LAPACK routines ):: $ gfortran -llapack solve1.f90 If you see a mesage such as:: ld: library not found for -llapack then you'll need to install the BLAS/LAPACK on your Mac similarly as described below for Linux. On Linux, as just mentioned, you can quickly check out the availability of BLAS/LAPACK by compiling any Fortran routines using the ``-llapack`` flag:: $ gfortran -llapack dummy.f90 Now let's consider that you find BLAS/LAPACK are not installed on your Linux machine, and you need to install them. In what follows, we consider installing both BLAS and LAPACK in a directory ``/packages`` under your home directory, for instance:: $ cd $HOME $ mkdir packages 1. BLAS installation: ######################################### a. You need to first install the BLAS library. You can download a tarball `blas-3.7.1.tgz` directly from `the BLAS website `_ or use a ``wget`` command on your terminal:: $ cd $HOME/packages/ $ wget http://www.netlib.org/blas/blas-3.7.1.tgz On Mac, ``wget`` doesn't come with the general xcode installation. In this case you have two options: (i) use homebrew or macports as your package manager (see :ref:`preparations`); how to use these package managers to install a software is different from wget, or (ii) install ``wget`` manually (see `wget-mac `_) b. Untar it using:: $ tar xvf blas-3.7.1.tgz c. Upon untarring, you will see a BLAS source file directory. Go there and compile the source codes to generate a static library:: $ cd BLAS-3.7.1 $ gfortran -O2 -c *.f # compiles *.f and generates object files $ ar cr libblas.a *.o # archives the object files into a static archive file libblas.a Now you're done with the BLAS installation. Let's now install LAPACK. .. 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 `_. 2. LAPACK installation: ######################################### a. As before, you can download a tarball ``lapack-3.7.1.tgz`` from `the LAPACK website `_ or type:: $ cd $HOME/packages $ wget http://www.netlib.org/lapack/lapack-3.7.1.tgz $ tar xvf lapack-3.7.1.tgz b. Go to the directory:: $ cd lapack-3.7.1 $ cp make.inc.example make.inc c. Edit ``make.inc`` as follows: .. literalinclude:: ./codes/lapack/make.inc :language: make :linenos: d. You're now ready to compile LAPACK by typing:: $ make or you can run make in a parallel mode:: $ make -j N where N = 2, 4, or any number that your machine allows for parallel processings. .. note:: There is a master ``Makefile`` which calls ``make.inc`` in the same directory, ``$HOME/packages/lapack-3.7.1/``. You may want to take a look at the makefile to learn how this ``make`` command compiles the LAPACK source codes. .. note:: Note that ``-lblas`` option does not look for ``blas.o``, but ``libblas.a`` in case with a statically linked library, or ``libblas.so`` in case with a shared library. Therefore, including ``-lblas`` in compilation is equivalente to compiling ``libblas.a``. .. 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, say, in your ``.bashrc`` or ``.bash_profile``. If it's not the case, however, you need to add ``-L`` flags followed by the directory path, in the makefile if you've put libraries in nonstandard places. 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: 1. `article 1 `_ 2. `article 2 `_ 3. `article 3 `_ 3. Testing: ######################################### With these you should be able to run the codes in ``lectureNote/chapters/chapt02/codes/lapack/linear``: .. literalinclude:: ./codes/lapack/linear/solve1.f90 :language: fortran :linenos: .. literalinclude:: ./codes/lapack/linear/makefile :language: make :linenos: and the codes in ``lectureNote/chapters/chapt02/codes/lapack/random``. Note in the above ``makefile``, it is important to include ``$(LFLAGS)`` *after* ``solve1.o`` so that ``solve1.o`` can refer to the libraries. .. literalinclude:: ./codes/lapack/random/init_random_seed.f90 :language: fortran :linenos: .. literalinclude:: ./codes/lapack/random/randomsys1.f90 :language: fortran :linenos: .. literalinclude:: ./codes/lapack/random/randomsys2.f90 :language: fortran :linenos: .. literalinclude:: ./codes/lapack/random/randomsys3.f90 :language: fortran :linenos: .. literalinclude:: ./codes/lapack/random/makefile :language: make :linenos: Some more references: * `LAPACK `_ * `LAPACK User's Guide `_ * `Automatically Tuned Linear Algebra Software (ATLAS) `_ * ``_