Newer
Older
\renewcommand{\FIGREP}{src/serial/figures}
\section{Basics of compilation}
\label{sec:basics}
\frametitle{Compilation}
\framesubtitle{0100101110101001010...}
\item A computer only understands ON and OFF states (1 and 0)
\item It would be very inconvenient for us to code in binary
\item We therefore use different levels of abstraction (languages), e.g. C, C++, Fortran
\item We need a translator!
\begin{frame}
\frametitle{Compilation}
\framesubtitle{The four compilation steps}
\item Translation is made by a compiler in 4 steps
\begin{description}
\item[Preprocessing] Format source code to make it ready for compilation (remove comments, execute preprocessing directives such as \cmd{\#include}, etc.)
\item[Compiling] Translate the source code (C, C++, Fortran, etc) into assembly, a very basic CPU-dependent language
\item[Assembly] Translate the assembly into machine code and store it in object files
\item[Linking] Link all the object files into one executable
\end{description}
\item In practice, the first three steps are combined together and simply
called ``compiling''
\begin{frame}[t,fragile]
\frametitle{Compilation}
\framesubtitle{The four compilation steps (visually)}
\hspace{6cm}
\begin{minipage}{0.5\textwidth}
\begin{itemize}
\item<5> Note that in reality, everything is done transparently
\begin{bashcode}
$> gcc -c file_1.c
$> gcc -c file_2.c
$> gcc file_1.o file_2.o -lexample -o exec
\end{bashcode}%$
\end{itemize}
\end{minipage}
\onslide<1>\addimage[width=12cm]{\FIGREP/compilation_steps_0.pdf}{2cm}{1cm}
\onslide<2>\addimage[width=12cm]{\FIGREP/compilation_steps_1.pdf}{2cm}{1cm}
\onslide<3>\addimage[width=12cm]{\FIGREP/compilation_steps_2.pdf}{2cm}{1cm}
\onslide<4>\addimage[width=12cm]{\FIGREP/compilation_steps_3.pdf}{2cm}{1cm}
\onslide<5>\addimage[width=12cm]{\FIGREP/compilation_steps_4.pdf}{2cm}{1cm}
\begin{frame}
\frametitle{Compilation}
\framesubtitle{Compilation options}
Many compilation options can be used to manipulate, optimize or debug such as:
\begin{itemize}
\item "Manipulation": \cmd{-o}, \cmd{-c}, etc.
\item "Optimization": \cmd{-On}, \cmd{-fastmath}, etc.
\item "Debug": \cmd{-g}, \cmd{-traceback} (gcc), etc.
\item Option summary for GNU: \url{https://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html\#Option-Summary}
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{Compilation}
\framesubtitle{Exercise simpleCompilation}
\begin{itemize}
\item Go to the directory \cmd{simpleCompilation}
\item Compile the code \cmd{saxpy.F90}
\item Modify \cmd{saxpy.F90} in order to suppress warnings
\item Execute the code
\item Try different compilation options for optimization, and compare the timing displayed from the corresponding runs
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{Compilation}
\framesubtitle{Exercise compilationWith2Files}
\begin{itemize}
\item Go to the directory \cmd{compilationWith2Files}
\item The previous code has been splitted into two files: \cmd{main.F90} and \cmd{saxpy.F90}
\item compile and execute the code
\item Check the results compared to the \cmd{simpleCompilation} exercise
\end{itemize}
\end{frame}
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
\begin{frame}[t,fragile]
\frametitle{Compilation}
\framesubtitle{Link to libraries}
\begin{itemize}
\item Description
\begin{description}
\item[Static libraries] Using static libraries means including the definition of the library functions in your executable file, during the link editing stage (i.e. during compilation and before launching the program)
\item[Shared libraries] Using shared libraries means telling your program where it can load these definitions into memory after the program is launched
\end{description}
\item Examples
\begin{description}
\item Static libraries are generally named in the form \cmd{lib***.a}; for example, \cmd{libc.a} is the standard \cmd{C} library (functions \cxxinline{malloc}, \cxxinline{exit}, etc.) launching the program)
\item Shared libraries are generally named in the form \cmd{lib***.so}
\end{description}
\item Use
\begin{description}
\item Let the library \cmd{libXXX.a} (or \cmd{libXXX.so}) be located in a directory whose absolute path is \cmd{path}. To compile a source \cmd{file.c} file calling functions of this library, you must type the following command line:
\begin{consoleoutput}
$ gcc file.c -Lpath -lXXX -o file
\end{consoleoutput}
\end{description}
\end{itemize}
\end{frame}
\note{
\begin{itemize}
\item The advantage of static libraries is that the resulting executable file contains, before execution, everything that is necessary for it to work
\item On the other hand, a program compiled with a static library has an executable file that is much larger than the same program compiled with a dynamic library, since the definition of the library's functions is not in the executable file
\item Finally, if a static library is updated, any program that uses it will have to be recompiled so that it can take into account the modification. In the case of a dynamic library, this update does not need to be recompiled.
\item If both static and shared libraries are found, the linker gives preference to linking with the shared library unless the -static option is used.
\item To mix static and shared libraries gcc foo.c -Wl,-Bstatic -lbar -lbaz -lqux -Wl,-Bdynamic -lcorge -o foo.exe
\begin{frame}
\frametitle{Compilation}
\framesubtitle{Exercise compilationWithLibrary}
\begin{itemize}
\item Go to the directory \cmd{compilationWithLibrary}
\item Compile the code \cmd{main.F90} with shared library \cmd{libsaxpy.so}
\item Execute the code
\item Check the results according to the solution of exercise \cmd{simpleCompilation}
\end{itemize}
\end{frame}
\begin{frame}[t,fragile]
\frametitle{Compilation}
\framesubtitle{Use of library path through modules}
When using shared librairies at runtime we need to set \cmd{LD LIBRARY PATH} so the system knows where to find the library
\begin{itemize}
\item This variable tells the program where to look for dynamic libraries; if this location is changed, it is enough to modify the variable, without changing the program
\item To tell the system to look in the directory \cmd{/path/to/the/library}, the variable \cmd{LD_LIBRARY_PATH} must be initialized as follows:
\end{consoleoutput}
\item In practice, you will never define this variable but you will add files to its definition:
\begin{consoleoutput}
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/the/library
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
\end{consoleoutput}
\end{itemize}
\end{frame}
\begin{frame}[t,fragile]
\frametitle{Compilation}
\framesubtitle{bilan and header files}
To sum up, to compile we need typically the following informations:
\begin{itemize}
\item The name of the source code file(s)
\item The libraries to link against
\item Where to find these libraries
\item Where to find the header files
\item A nice name for the executable
\end{itemize}
Putting this together, we get something like
\begin{consoleoutput}
$ compiler -l libraries -L <path to libraries> -I <path to header files> -o <name of executable> file.c
\end{consoleoutput}
\begin{itemize}
\item \cmd{-I <path to header files>} allows to set the location of header files
\item Compilers available: gcc/g++/gfortran, icc/icpc/ifort, nvcc/nvc++/nvfortran (only on Izar cluster)
\end{itemize}
\end{frame}
\begin{frame}[t,fragile]
\frametitle{Compilation}
\framesubtitle{Modules on the SCITAS clusters}
Modules are hidden until the dependencies are loaded:
\begin{itemize}
\item module load compiler
\item module load library
\end{itemize}
Example on Helvetios
\begin{itemize}
\item Before loading module gcc
\begin{consoleoutput}
$ echo $LD_LIBRARY_PATH
\end{consoleoutput}
\item After loading module gcc
\begin{consoleoutput}
$ module load gcc
$ echo $LD_LIBRARY_PATH
/ssoft/spack/arvine/v1/opt/spack/linux-rhel7-haswell/gcc-4.8.5/gcc-8.4.0-fgpbrrd26pxv56imea5tnqj67vxh3a64/lib64:/ssoft/spack/arvine/v1/opt/spack/linux-rhel7-haswell/gcc-4.8.5/gcc-8.4.0-fgpbrrd26pxv56imea5tnqj67vxh3a64/lib
\end{consoleoutput}
\end{itemize}
\end{frame}
\begin{frame}[t,fragile]
\frametitle{Compilation}
\framesubtitle{Modules on the SCITAS clusters}
\begin{consoleoutput}
$ module load gcc openblas
$ module show openblas
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/ssoft/spack/arvine/v1/share/spack/lmod/gacrux/linux-rhel7-x86_64/gcc/8.4.0/openblas/0.3.10.lua:
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
prepend_path("PATH","/ssoft/spack/arvine/v1/opt/spack/linux-rhel7-skylake_avx512/gcc-8.4.0/openblas-0.3.10-imybullwemvq3ukf5tsu7kqdf4de52bw/bin")
prepend_path("LD_LIBRARY_PATH","/ssoft/spack/arvine/v1/opt/spack/linux-rhel7-skylake_avx512/gcc-8.4.0/openblas-0.3.10-imybullwemvq3ukf5tsu7kqdf4de52bw/lib")
prepend_path("C_INCLUDE_PATH","/ssoft/spack/arvine/v1/opt/spack/linux-rhel7-skylake_avx512/gcc-8.4.0/openblas-0.3.10-imybullwemvq3ukf5tsu7kqdf4de52bw/include")
prepend_path("CPLUS_INCLUDE_PATH","/ssoft/spack/arvine/v1/opt/spack/linux-rhel7-skylake_avx512/gcc-8.4.0/openblas-0.3.10-imybullwemvq3ukf5tsu7kqdf4de52bw/include")
prepend_path("INCLUDE","/ssoft/spack/arvine/v1/opt/spack/linux-rhel7-skylake_avx512/gcc-8.4.0/openblas-0.3.10-imybullwemvq3ukf5tsu7kqdf4de52bw/include")
...
\end{consoleoutput}
Other environment variables are set such as paths for executables in \cmd{PATH}, header files in \cmd{INCLUDE}, etc.
\end{frame}
\begin{frame}[t,fragile]
\frametitle{Compilation}
\framesubtitle{Libraries to make your life better}
\begin{itemize}
\item Openblas
\item MKL
\item OpenBLAS
\item FFTW
\item Eigen
\item ...
\end{itemize}
\end{frame}
\begin{frame}[t,fragile]
\frametitle{Compilation}
\framesubtitle{Making your own library}
\begin{itemize}
\item Creating static library \cmd{libmylib.a} from different object files \cmd{prog*.o}
\begin{consoleoutput}
$ gcc -c prog1.c prog2.c prog3.c ... progn.c
$ ar -rv libmylib.a prog1.o prog2.o prog3.o ... progn.o
\end{consoleoutput}
\item Creating shared library \cmd{libmylib.so} from different object files \cmd{prog*.o}
\begin{consoleoutput}
$ gcc -fPIC -c prog1.c prog2.c prog3.c ... progn.c
$ gcc -o libmylib.so -shared prog1.o prog2.o prog3.o ... progn.o
\end{consoleoutput}
\item Example
\begin{consoleoutput}
$ ldd ....
\end{consoleoutput}
\end{itemize}
\end{frame}
\begin{frame}[t,fragile]
\frametitle{Compilation}
\framesubtitle{Use a build system}
\begin{itemize}
\item Makefile
\item Cmake
\end{itemize}
\end{frame}
\begin{frame}[t,fragile]
\frametitle{Compilation}
\framesubtitle{Makefile example}
\bashfile[title={examples/compilationWithMakefile/Makefile}]{examples/compilationWithMakefile/Makefile}
% minted options app={firstline=1,
% lastline=40}]{examples/compilationWithMakefile}
\end{frame}
%%% TeX-master: "../../SCM_slides"