As you may have gathered, it's often better to link in libraries for certain tasks than to write the code yourself. This is especially true for maths libraries.
Many pre-existing libraries of subroutines and functions exist. You can easily include calls to these libraries in your own code - for example to solve an ordinary differential equation, find the eigenvalues of a matrix, or calculate the value of erfc(x).
The same is true for header files in C - you may have header files from many different locations that you need to include.
However, when it comes to compiling the code, you need to tell the compiler a couple of things:
- what libraries you wish to link in at compile time
- where these libraries reside on the machine you're using to compile the code
- where the header files (if used) reside on the machine you're using to compile the code
You can specify such information on the command line when you compile your code. These specifications are pretty generic - they will work for compiling fortran90 and C code.
Suppose you have a hypothetical library called libscalapack_p4.a, and you have called a function from this library in your own code (called basinhop.f90 - don't worry it would be the same for C). This library is located on your machine at /usr/local/mathlib/. Then you would need to type
ifort basinhop.f90 -L/usr/local/mathlib/ -lscalapack_p4 -o basinhop
so you can see in the example above, you need to use the -l flag to link in a library, and when you use the -l flat, the argument that follows is the library name stripped of the "lib" prefix and the ".a" suffix. The location of this library is provided with the -L flag. Immediately following the -L flag, you must provide a path to the library.
|Say you have a code called genetic.c which makes calls to a function in a library called libmisc.a, and this library is found in the directory /usr/local/cmathlib/|
|To link this library in to your program at compile time, you would type|
gcc genetic.c -L/usr/local/cmathlib/ -lmisc -o genetic
If your chosen library is in your current working directory, you must still provide a -L flag, such that you indicate the current working directory as your path (with a "."), eg you would include -L. in your compile line.
A very similar situation exists for include files. In this case you must use the -I flag, and follow this with the path to this header file.
|Say you have a code called hello.c which uses a header file called hello.h, and this header file is found in your current working directory|
|To include this header file in to your program at compile time, you would type|
gcc hello.c -I. -o hello
There are many, many more compiler options available for both C and fortran compilers. So far, you will have either used gcc (or icc) as a C-programmer or ifort as a f90 programmer. Many different compilers are available for use, and each compiler will come with its own set of flags and options that can be set (the flags mentioned above are pretty generic).
The gcc compiler is part of the gnu compiler collection that is free to use and open-source. The fortran90 counterpart to gcc is gfortran. Sometimes gfortarn is not available and one may be able to use a gnu compiler for fortran77 called g77. Have a look for these compilers on the CSC machines when you get an account.
The ifort compiler is part of the intel compiler range. These compilers have to be purchased, and you can't view the source of these compilers. A C counterpart to ifort is the icc compiler. You should be aware that on some other platforms, ifort is referred to as ifc. The CSC machines will also have these compilers.
Another compiler available at the CSC are the Portland compilers. Again, Portland compilers are proprietary. The fortran90 compiler is referred to as pgf90 and the C compiler is referred to as pgc.
More explicit instructions for using these compilers on the various CSC facilities are given on the Local CSC website, in the HPC section. You should consult these pages when you're ready to seriously compile and optimise some code. In particular, you should read the documentation for your chosen compiler to find out exactly what flags you can use to optimise your program at runtime.
One final point to bear in mind - all compilers are different. Some will be very strict (this is a good thing) and some will let through some very sloppy errors. Just because your code compiles and runs for one given compiler doesn't mean that your code doesn't contain any bugs!