diff --git a/src/figs/dispatch_1d.png b/src/figs/dispatch_1d.png
new file mode 100644
index 0000000000000000000000000000000000000000..dbd4f7054c3ad3a6377f8fb76b4e0f897d31a48e
Binary files /dev/null and b/src/figs/dispatch_1d.png differ
diff --git a/src/figs/neighbours.png b/src/figs/neighbours.png
new file mode 100644
index 0000000000000000000000000000000000000000..c573cf6c10ffa813b1379bcc3749f4307aad8419
Binary files /dev/null and b/src/figs/neighbours.png differ
diff --git a/src/text/00-preface.md b/src/text/00-preface.md
index ea184ca3cac048144f935df4ec83d82c9b1e9be7..96ae62dc71b232f667e3fcce4211ebafa4c0ed55 100644
--- a/src/text/00-preface.md
+++ b/src/text/00-preface.md
@@ -9,7 +9,6 @@ I would like to thank the people who helped me during this project:
 
 # Abstract {-}
 
-Today, most computers are equipped with GPUs. They provide more and more computing cores and have become fundamental embedded high-performance computing tools. In this context, the number of applications taking advantage of these tools seems low at first glance. The problem is that the development tools are heterogeneous, complex, and strongly dependent on the GPU running the code. Futhark is an experimental, functional, and architecture agnostic language; that is why it seems relevant to study it.  It allows generating code allowing a standard sequential execution (on a single-core processor), on GPU (with CUDA and OpenCL backends), on several cores of the same processor (shared memory). To make it a tool that could be used on all high-performance platforms, it lacks support for distributed computing. This work aims to develop a library that can port any Futhark code to an MPI library with as little effort as possible.
 
 \begin{figure} \vspace{.1cm} \begin{center} \includegraphics[width=3.72cm,height=2.4cm]{figs/front-logo.png}
 \end{center} \end{figure} \begin{tabular}{ p{3cm} p{1cm} p{1cm} p{6cm} } \multicolumn{1}{l}{Candidate:}& & &
diff --git a/src/text/02-introduction.md b/src/text/02-introduction.md
index 1e887b07ea5ce095d175a39993312b4b2a9f58ff..d3aeb1454e3e526b3b552704efa3ef16be43805c 100644
--- a/src/text/02-introduction.md
+++ b/src/text/02-introduction.md
@@ -4,7 +4,7 @@
 
 Today, most computers are equipped with GPUs. They provide more and more computing cores and have become fundamental embedded high-performance computing tools. In this context, the number of applications taking advantage of these tools seems low at first glance. The problem is that the development tools are heterogeneous, complex, and strongly dependent on the GPU running the code. Futhark is an experimental, functional, and architecture agnostic language; that is why it seems relevant to study it.  It allows generating code allowing a standard sequential execution (on a single-core processor), on GPU (with CUDA and OpenCL backends), on several cores of the same processor (shared memory). To make it a tool that could be used on all high-performance platforms, it lacks support for distributed computing. This work aims to develop a library that can port any Futhark code to an MPI library with as little effort as possible.
 
-To achieve that, we introduce the interest of parallelization by reviewing Amdahl's law and Gustafon-Barsis's law, then what is MPI and Futhark. We decide to implement a library that can parallelize cellular automaton in, one, two or three dimensions. By adding Futhark on top of MPI, the programmer will have the possibilities to compile his code in :
+To achieve that, we introduce the interest of parallelization --, then what is MPI and Futhark. We decide to implement a library that can parallelize cellular automaton in, one, two or three dimensions. By adding Futhark on top of MPI, the programmer will have the possibilities to compile his code in :
 * parallelized-sequential mode,
 * parallelized-multicore mode,
 * parallelized-OpenCL mode,
diff --git a/src/text/03-programmation-parallele.md b/src/text/03-programmation-parallele.md
index bd0c267b5b80bd02a4443c896f92a6e96709b50f..13801dcc50005b9736225e0a0f0a1729fb98ed24 100644
--- a/src/text/03-programmation-parallele.md
+++ b/src/text/03-programmation-parallele.md
@@ -1,3 +1,31 @@
-# La programmation parallèle
+# Distributed computing vs parallel computing vs concurrent computing
 
-La programmation parallèle permet de réaliser des opérations sur des données de manières simultanée dans le but d'augmenter la vitesse de traitement par rapport à la programmation séquentielle. 
+Parallel computing refers to the process of breaking down larger problems into smaller, independent, often similar parts that can be executed simultaneously by multiple processors communicating via shared memory, the results of which are combined upon completion as part of an overall algorithm. The primary goal of parallel computing is to increase available computation power for faster application processing and problem solving.
+
+
+Dans le parallélisme, il existe deux lois importantes :
+
+1. la loi d'Amdahl
+2. la loi de Gustafon-Barsis
+
+\cimg{figs/amdahls-law.png}{scale=0.6}{Loi d'Amdahl}{Source : Tiré de https://commons.wikimedia.org/, ref. URL02}
+
+La loi d'Amdahls affirme que la vitesse globale du programme est limitée par le code qui ne peut être parallélisée. En
+effet, dans un code il y aura presque toujours une partie séquentielle non parallélisable. Il y a donc une relation
+entre le ratio de code parallélisable et la vitesse globale d'exécution du programme.
+
+Dans le graphique ci-dessus, on remarque que si :
+
+* 50 % du code est parallélisé, alors, on obtient une accélération théorique maximale de x2 à partir de 16 processeurs.
+* 75 % du code est parallélisé, alors, on obtient une accélération théorique maximale de x4 à partir de 128 processeurs.
+* 90 % du code est parallélisé, alors, on obtient une accélération théorique maximale de x10 à partir de 512 processeurs.
+* 95 % du code est parallélisé, alors, on obtient une accélération théorique maximale de x20 à partir de 4096 processeurs.
+
+\pagebreak
+
+\cimg{figs/gustafson-law.png}{scale=0.75}{Loi de Gustafon-Barsis}{Source : Tiré de https://commons.wikimedia.org/, ref. URL03}
+
+La loi de Gustafson dit que plus le nombre de données à traiter est grand, plus l'utilisation d'un grand nombre de processeurs sera avantageux. Ainsi, l'accélération est linéaire comme on peut le voir sur le graphique.
+Sur le graphique, on remarque par exemple qu'avec un code qui est 90 % parallélisé, on a un *speedup* d'au moins x100 avec 120 processeurs là où la loi d'Amdahl estimait un *speedup* maximal de x10 avec 512 processeurs. La loi de Gustafson est donc beaucoup plus optimiste en termes de gain de performance.
+
+\pagebreak
diff --git a/src/text/04-mpi.md b/src/text/04-mpi.md
index 989c8c887d5d44e6c3528c9e28d7f989fc3c5b3a..991ceb7a4a0bb4b63f1a04acae0fe771bb27d1d1 100644
--- a/src/text/04-mpi.md
+++ b/src/text/04-mpi.md
@@ -5,7 +5,7 @@ In order to realize parallel programming, the standard (+^MPI) was created in 19
 * MPICH, which support for the moment, MPI 3.1,
 * Open MPI, which support, for the moment, MPI 3.1
 
-I used Open MPI throughout this project, both on my computer and on the cluster of the (+^HES-GE).
+We use Open MPI throughout this project on the cluster of the (+^HES-GE).
 
 \pagebreak
 
diff --git a/src/text/05-futhark.md b/src/text/05-futhark.md
index ba22fa103858580658d531f82c6b04ba266894c0..ef75e4269c0350bbe36018311e4929e870701101 100644
--- a/src/text/05-futhark.md
+++ b/src/text/05-futhark.md
@@ -105,4 +105,30 @@ gcc main.c -o fact fact.o -lOpenCL -lm
 
 The program's execution with the factorial of 12 returns the correct value, i.e. 479 001 600.
 
+## Functional programming
+
+Functional programming is a programming paradigm that considers computation as an evaluation of
+mathematical functions. The origin of functional programming comes from lambda-calculus, a formal system
+invented by Alonzo Church where everything is a function. [@noauthor_programmation_2021]
+
+This paradigm avoids side effects by prohibiting the change of the value of a variable that is not defined in the current scope. Thus, it facilitates concurrent programming because shared variables cannot be modified, which reduces the bugs resulting from concurrent programmings, such as data race conditions.
+
+A functional language is a language that encourages functional programming by providing the features
+necessary to respect this programming paradigm.
+
+### Higher-order functions
+
+In functional programming, a higher-order function is a function with at least one of these characteristics:
+
+* it takes one or more functions as parameters,
+* it returns a function as a result.
+
+Thus, the best known higher-order functions are :
+
+* `map([A], A -> B) -> [B]`, takes as a parameter an array of data of type A and a function that applies to each element of the array to create a new array of data of type B,
+* `filter([A], A -> Boolean) -> [A]`, takes as a parameter an array of type A and a predicate (a function returning a boolean) which applies on each element of the array. Thus, the function returns only those elements that answer true to the predicate.
+* `reduce([A], (A, A) -> A) -> A`, takes as a parameter an array of type A and an accumulator function. This function allows to reduce an array to a single value. For example, to add the elements of an array.
+
+Using these functions becomes faster to write code and understand the code created by a person.
+
 \pagebreak
diff --git a/src/text/06-mpi-x-futhark.md b/src/text/06-mpi-x-futhark.md
index f2ff256cf2422ae224e33b7121a76d086b8d7f45..20fcacbb6e4d0f8637105b81526a81ad8e488cde 100644
--- a/src/text/06-mpi-x-futhark.md
+++ b/src/text/06-mpi-x-futhark.md
@@ -1,19 +1,34 @@
-# MPI x Futhark
+# Automate cellulaire
 
-Notre librairie permet de paralléliser des automates cellulaires automatiquement de sorte que le programmeur n'ai plus qu'à écrire la fonction Futhark permettant de mettre à jour son automate cellulaire. Notre librairie prends en charge les automates cellulaires de, une, deux et trois dimensions.
+A cellular automaton consists of a regular grid of cells, each in one of a finite number of states. The grid can be in any finite number of dimensions. For each cell, a set of cells called its neighborhood is defined relative to the specified cell. An initial state (time $t = 0$) is selected by assigning a state for each cell. A new generation is created (advancing t by 1), according to some fixed rule (generally, a mathematical function) that determines the new state of each cell in terms of the current state of the cell and the states of the cells in its neighborhood. Typically, the rule for updating the state of cells is the same for each cell and does not change over time. // wiki
 
-## Communication
-Afin de faciliter la communication entre les différents rangs, nous créons une topologie cartésienne virtuelle grâce à MPI.
+Le voisinage d'une cellule est défini soit par le voisinage de Moore, soit par le voisinage de Von Neumann. Le premier, défini qu'une cellule dispose dans un automate cellulaire à deux dimensions, huit voisines alors que le deuxième, quatre.
 
-A virtual topology is a mechanism for naming the processes in a communicator in away that fits the communication pattern better. The main aim of this is to makes sub-sequent code simpler. It may also provide hints to the run-time system which allow it to optimise the communication or even hint to the loader how to configure the processes. The  virtual  topology  might  also  gain  us  some  performance  benefit.
+\cimg{figs/neighbours.png}{scale=0.60}{Comparaison entre le voisinage de Von Neumann (à gauche) et de Moore (à droite)}{Source : Created by Baptiste Coudray, ref. URL04}
 
-### One dimension
+La grille de gauche de gauche représente le voisinage de Von Neumann, à savoir, les quatre voisines d'une cellule. Celles-ci sont dénotées par les quatre points cardinaux (nord, ouest, sud, est). 
+La grille de droite représente le voisinage de Moore, à savoir, les huit voisines d'une cellule. Celles-ci sont dénotées par les quatre points cardinaux et les quatre points inter-cardinaux (nord-ouest, sud-ouest, sud-est, nord-est).
+
+## MPI x Futhark
+
+Notre librairie permet de paralléliser des automates cellulaires automatiquement de sorte que le programmeur n'ai plus qu'à écrire la fonction Futhark permettant de mettre à jour son automate cellulaire. Notre librairie prends en charge les automates cellulaires de, une, deux et trois dimensions. L'utilisation du langage Futhark permet de mettre à jour rapidement l'état de l'automate cellulaire grâce aux différents backend disponibles. De ce fait, plusieurs modes sont disponibles :
+* parallalized-sequential, le code Futhark est exécuté de manière séquentielle,
+* parallalized-multicore, le code Futhark est exécuté de façon concurrents grâce aux threads POSIX,
+* parallalized-OpenCL/CUDA, le code Futhark est exécuté sur la carte graphique.
+
+### Communication
+
+Une communication entre les différentes tâches MPI est nécessaire pour récupérer les voisines manquantes ainsi que recréer l'automate cellulaire complet. De ce fait, nous créons une topologie virtuelle cartésienne.
+
+A virtual topology is a mechanism for naming the processes in a communicator in away that fits the communication pattern better. The main aim of this is to makes sub-sequent code simpler. It may also provide hints to the run-time system which allow it to optimise the communication or even hint to the loader how to configure the processes. The  virtual  topology  might  also  gain  us  some  performance benefit.
+
+#### One dimension
 
 \cimg{figs/futhark.png}{scale=0.60}{Futhark}{Source : Taken from https://commons.wikimedia.org/, ref. URL04}
 
-Dans une topologie cartésienne à une dimension, on remarque que les rangs peuvent communiquer directement avec leur voisin de gauche et de droite même s'ils sont aux extrémités du réseau. En effet, le communicateur MPI est défini pour être cyclique ce qui évite de devoir parcourir les $n - 2$ voisins qui les séparent.
+Dans une topologie cartésienne à une dimension, on remarque que les rangs peuvent communiquer directement avec leur voisin de gauche et de droite même s'ils sont aux extrémités du réseau. En effet, le communicateur MPI est défini pour être cyclique ce qui évite de devoir parcourir les $N - 2$ voisins qui les séparent.
 
-### Two dimensions
+#### Two dimensions
 
 \cimg{figs/futhark.png}{scale=0.60}{Futhark}{Source : Taken from https://commons.wikimedia.org/, ref. URL04}
 
@@ -24,17 +39,28 @@ Dans une topologie cartésienne à deux dimensions, on remarque que les rangs pe
 
 \cimg{figs/futhark.png}{scale=0.60}{Futhark}{Source : Taken from https://commons.wikimedia.org/, ref. URL04}
 
-Dans une topologie cartésienne à trois dimensions, on remarque que les rangs ont les mêmes capacités de communication qu'une topologie en deux dimensions, mais, ils peuvent en plus communiquer avec leur voisin de devant et de derrière. 
+Dans une topologie cartésienne à trois dimensions, on remarque que les rangs ont les mêmes capacités de communication qu'une topologie en deux dimensions, mais, ils peuvent en plus communiquer avec leur voisin de devant et de derrière ($z-1$ et $z+1$). Comme pour les autres dimensions, le communicateur de cet dimension est cyclique.
 
-## Data dispatching
+### Data dispatching
 
-L'automate cellulaire est partagé de façon le plus équitable possible entre les rangs disponibles de sorte que chaque rang effectue plus ou moins le même temps de travail. Ainsi chaque rang à un chunk qui est une partie de l'automate celullaire. Ce chunk peut être de dimension un, deux ou trois.
+L'automate cellulaire est partagé de façon la plus équitable possible entre les rangs disponibles de sorte que chaque rang effectue plus ou moins le même temps de travail. Ainsi chaque rang à un chunk qui est une partie de l'automate celullaire. Ce chunk peut être de dimension un, deux ou trois.
 
-### One dimension
-### Two dimensions
-### Three dimensions
+#### One dimension
+
+\cimg{figs/futhark.png}{scale=0.60}{Futhark}{Source : Taken from https://commons.wikimedia.org/, ref. URL04}
+
+Sur cet exemple, un automate cellulaire de dimension un, de taille 8, est partagé entre trois processus. Comme la division de l'automate cellulaire n'est pas entière, le rang deux se voit attribuer seulement deux cellules contrairement aux autres qui en ont trois.
+
+#### Two dimensions
+\cimg{figs/futhark.png}{scale=0.60}{Futhark}{Source : Taken from https://commons.wikimedia.org/, ref. URL04}
+
+Dans cet exemple, l'automate cellulaire est en deux dimensions et de taille $9 \times 9$. Avec quatre rangs à disposition, il peut être séparé en 4 sous-matrices de $3 \times 3$
+
+#### Three dimensions
 
-## Envelope
+Le principe reste le même que pour la deuxième dimension, à l'exception que chaque processus se voit attribuer $x$ 
+
+### Envelope
 
 L'automate cellulaire devra utiliser le voisinage de Moore ce qui veut dire que chaque cellule dispose de :
 
@@ -42,19 +68,26 @@ L'automate cellulaire devra utiliser le voisinage de Moore ce qui veut dire que
 * huit voisines en deux dimensions,
 * 26 voisines en trois dimensions.
 
-Ces valeurs sont valides pour un automate cellulaire de dimension deux et d'une distance de Tchebychev de un. On peut généraliser le nombre de voisines qu'une cellule a via la formule $(2r + 1)^d - 1$, où $r$ est la distance de Tchebychev et $d$ la dimension.
+Ces valeurs sont valides pour un automate cellulaire de dimension deux et d'une distance de Tchebychev de un. On peut généraliser le nombre de voisines qu'une cellule dispose via la formule $(2r + 1)^d - 1$, où $r$ est la distance de Tchebychev et $d$ la dimension.
 
-Ainsi l'enveloppe contient le voisinage de Moore manquant d'une distance de Tchebychev de $r$ des cellules situées aux extremités du chunk.
+Ainsi l'enveloppe contient le voisinage de Moore manquant d'une distance de Tchebychev de $r$ des cellules situées aux extrémités du chunk.
 
-### One dimension
+#### One dimension
 \cimg{figs/futhark.png}{scale=0.60}{Futhark}{Source : Taken from https://commons.wikimedia.org/, ref. URL04}
 
-Le voisinage de Moore en une dimension d'une cellule comprends la voisine de gauche (east-neighbor) et la voisine de droite (west-neighbor). Donc les 
+Le voisinage de Moore en une dimension d'une cellule comprends la voisine de gauche (west-neighbor) et la voisine de droite (east-neighbor).
 
-### Two dimensions
-\cimg{figs/futhark.png}{scale=0.60}{Futhark}{Source : Taken from https://commons.wikimedia.org/, ref. URL04}
+En reprenant l'automate cellulaire décrit précédemment en une dimension, on remarque que l'enveloppe de $R_n$ comprends la dernière cellule de $R_{(n-1) % N}$ et la première cellule de $R_{(n+1) % N}$. Ainsi, les rangs s'échangent les données via MPI en utilisant la topologie virtuelle cartésienne.
+
+#### Two dimensions
 
-### Three dimensions
 \cimg{figs/futhark.png}{scale=0.60}{Futhark}{Source : Taken from https://commons.wikimedia.org/, ref. URL04}
 
+Dans cet exemple, l'enveloppe comprends les voisines 
+
+#### Three dimensions
+
+En troisième dimension, on rajoute la profondeur de devant et la profondeur de derrière 
+
+
 \pagebreak
diff --git a/src/text/07-automate-elementaire.md b/src/text/07-automate-elementaire.md
index 8c92cf760597f3c7fe2f8ef9f28da8b1c4112b27..043c05f4955f2468910aa26145afa66c4b24cfb5 100644
--- a/src/text/07-automate-elementaire.md
+++ b/src/text/07-automate-elementaire.md
@@ -4,7 +4,7 @@ The simplest non-trivial cellular automaton that can be conceived consists of a
 
 There are $2^3 = 8$ possible configurations (or patterns, rules) of such a neighborhood. In order for the cellular automaton to work, it is necessary to define what the state must be, at the next generation, of a cell for each of these patterns. The 8 rules/configurations defined is as follows:
 
-| Rule n° | Neighbour left state | State | Neighbour right state | Next state |
+| Rule n° | East neighbour state | Cell state | West neighbour state | Cell next state |
 |:---:|:---:|:---:|:---:|:---:|
 | 1 | 0 | 0 | 0 | 0
 | 2 | 0 | 0 | 1 | 1
@@ -31,29 +31,26 @@ Iteration 0 is the initial state and only cell two is alive. To perform the next
 Avec la librairie que nous avons créée, nous avons implémenté l'automate cellulaire précédemment décris. Pour ce faire, nous créons un fichier Futhark `elementary.fut` qui sert à calculer le prochain état d'une partie de l'automate cellulaire.
 
 ```
-entry next_chunk_elems [n] (chunk_elems :[n]i8) (envelope: envelope_1d_i8) :[n]i8 =
-    let augmented_elems = augment_chunk_elems chunk_elems envelope
-    let next_elems = compute_next_elems augmented_elems
-    in next_elems[1:n+1] :> [n]i8
+let compute_next_elems [n] (chunk_elems :[n]i8) :[]i8 = ...
+
+entry next_chunk_elems [n] (chunk_elems :[n]i8) :[]i8 =
+    let next_elems = compute_next_elems chunk_elems
+    in next_elems[1:n-1]
 ```
 
-De ce fait, le fichier `elementary.fut` contient une fonction permettant de mettre à jour une partie de l'automate cellulaire.
+De ce fait, le fichier `elementary.fut` contient seulement une fonction qui applique les règles sur une partie de l'automate cellulaire. A noter que la fonction retourne l'automate cellulaire sans l'enveloppe.
 
 ```c
-void compute_next_chunk_elems(struct dispatch_context *dc, struct futhark_context *fc, chunk_info_t *ci) {
-    envelope_t *outer_envelope = get_outer_envelope(dc, fc, 1);
-
-    struct futhark_opaque_envelope_1d_i8 *fut_outer_envelope = futhark_outer_envelope_new(dc, fc, outer_envelope, futhark_restore_opaque_envelope_1d_i8, FUTHARK_I8);
-
-    struct futhark_i8_1d *fut_chunk_elems = futhark_new_i8_1d(fc, ci->data, ci->dimensions[1]);
+void compute_next_chunk_board(struct dispatch_context *dc, struct futhark_context *fc, chunk_info_t *ci) {
+    struct futhark_i8_1d *fut_chunk_with_envelope = get_chunk_with_envelope(dc, fc, 1, futhark_new_i8_1d);
+    
     struct futhark_i8_1d *fut_next_chunk_elems;
-
+    futhark_entry_next_chunk_elems(fc, &fut_next_chunk_elems, fut_chunk_with_envelope);
     futhark_context_sync(fc);
-    futhark_entry_next_chunk_elems(fc, &fut_next_chunk_elems, fut_chunk_elems, fut_outer_envelope);
-    futhark_context_sync(fc);
-
+    
     futhark_values_i8_1d(fc, fut_next_chunk_elems, ci->data);
     futhark_context_sync(fc);
+
     /* ... Free resources ... */
 }
 
@@ -74,41 +71,38 @@ int main(int argc, char *argv[]) {
 }
 ```
 
-Finalement, un fichier C `main.c` est nécessaire pour créer le point d'entrée du programme. Le code est relativement simple, le programmeur doit initialiser environnement MPI et Futhark. Ensuite, il doit initialiser notre librairie via la fonction `dispatch_context_new` en spécifiant la taille de l'automate cellulaire, son type de données et le nombre de dimensions.
+Finalement, un fichier C `main.c` est nécessaire pour créer le point d'entrée du programme. Le code est relativement simple, le programmeur doit initialiser environnement MPI et Futhark. Ensuite, il doit initialiser notre librairie via la fonction `dispatch_context_new` en spécifiant la taille de l'automate cellulaire, son type de données et le nombre de dimensions (un en l'occurrence). Finalement, via la fonction `compute_next_chunk_board` qu'il crée, le programmeur récupère son morceau d'automate cellulaire avec l'envelope et il appelle la fonction Futhark qu'il a créé. 
 
 ## CPU Benchmark
 
-| Number of tasks | Average [s] | Standard Derivation [s] | Speedup | Number of measures |
-|:---:|:---:|:---:|:---:|:---:|
-| 1 | 710.678 [s] | ± 1.689 [s] | x1.0 | 15 |
-| 2 | 390.93 [s] | ± 24.671 [s] | x1.8 | 15 |
-| 4 | 209.194 [s] | ± 0.443 [s] | x3.4 | 15 |
-| 8 | 104.686 [s] | ± 0.273 [s] | x6.8 | 15 |
-| 16 | 51.996 [s] | ± 0.285 [s] | x13.7 | 15 |
-| 32 | 26.201 [s] | ± 0.087 [s] | x27.1 | 15 |
-| 64 | 13.104 [s] | ± 0.049 [s] | x54.2 | 15 |
-| 128 | 6.653 [s] | ± 0.032 [s] | x106.8 | 15 |
+Nous effectuons des benchmarks pour valider la scalabilité de notre parallélisation en une dimension quand on compile en mode séquentiel, multicœurs, OpenCL ou CUDA. Les benchmarks sont effectués sur le cluster HES-GE (Baobab2/Yggdrasil).
+Le benchmark séquentiel et multicœurs sont effectués comme suit :
+* l'automate cellulaire est de taille $900 000 000$ cellules,
+* le nombre de tâches varie entre $2^0$ et $2^7$,
+* 15 mesures sont effectuées,
+* et une mesure correspond à 100 générations.
+
+
 *Array of results for the parallelized-sequential version*
 
-| Number of tasks | Average [s] | Standard Derivation [s] | Speedup | Number of measures |
-|:---:|:---:|:---:|:---:|:---:|
-| 1 | 823.08 [s] | ± 9.366 [s] | x1.0 | 15 |
-| 2 | 417.564 [s] | ± 13.221 [s] | x2.0 | 15 |
-| 4 | 213.967 [s] | ± 9.582 [s] | x3.8 | 15 |
-| 8 | 121.354 [s] | ± 0.037 [s] | x6.8 | 15 |
-| 16 | 56.497 [s] | ± 0.231 [s] | x14.6 | 15 |
-| 32 | 29.848 [s] | ± 0.081 [s] | x27.6 | 15 |
-| 64 | 14.502 [s] | ± 0.064 [s] | x56.8 | 15 |
-| 128 | 7.774 [s] | ± 0.053 [s] | x105.9 | 15 |
+
 *Array of results for the parallelized-multicore version*
 
-On remarque que la version multicoeurs est plus lente que la version séquentielle, cela est dû à la non-optimisation des tableaux à une dimension de la part du backend Multicore. En effet, cette fonctionnalité n'est pas encore implémentée dans le compilateur Futhark.
+On remarque que la version multicœurs est plus lente que la version séquentielle, cela est dû à la non-optimisation des tableaux à une dimension de la part du backend multicore de Futhark. En effet, cette fonctionnalité n'est pas encore implémentée dans le compilateur Futhark.
 
 
-A gauche, le graphique montre le temps de calculs de 100 générations du jeu de la vie pour un automate cellulaire de $30 000^2 = 900 000 000$ cellules de la version sequentielle et multicoeurs. A droite, nous avons le speedup idéal ainsi que le speedup obtenu de la version sequentielle et multicoeurs.
+A gauche, le graphique montre le temps de calculs de 100 générations du jeu de la vie pour un automate cellulaire de $30 000^2 = 900 000 000$ cellules de la version sequentielle et multicœurs. A droite, nous avons le speedup idéal ainsi que le speedup obtenu de la version sequentielle et multicœurs.
 
-Sur le graphique du temps d'exécution, on remarque que celui-ci diminue de l'ordre $\frac{1}{x}$ pour l'éxecution séquentielle et multicore. A noté que la version séquentielle est plus rapide que la version multicœurs.
+Sur le graphique du temps d'exécution, on remarque que celui-ci diminue de l'ordre $\frac{1}{x}$ pour l'exécution séquentielle et multicore. A noté que la version séquentielle est plus rapide que la version multicœurs.
 
 ## GPU Benchmark
 
+Les benchmarks OpenCL et CUDA sont effectués comme suit :
+* l'automate cellulaire est de taille $900 000 000$ cellules,
+* le nombre de tâches varie entre $2^0$ et $2^7$
+* 15 mesures sont effectuées
+* une mesure correspond à 300 générations,
+* de $2^0$ à $2^3$ tâches, une NVIDIA GeForce RTX 3090 est attribuée pour chaque tâche, au-delà, les tâches se partagent
+  de manière équitable les cartes graphiques.
+
 \pagebreak
diff --git a/src/text/08-jeu-de-la-vie.md b/src/text/08-jeu-de-la-vie.md
index aa415731ac5df5d60b01bb7aedb0f6fc8695f074..abc36738bd7b89731f9d336d83ca1bf2f0f566df 100644
--- a/src/text/08-jeu-de-la-vie.md
+++ b/src/text/08-jeu-de-la-vie.md
@@ -29,56 +29,7 @@ Thus, after the application of the rules, the horizontal line becomes a vertical
 
 ## Parallelized version
 
-Avec la librairie que nous avons créée, nous avons implémenté le jeu de la vie. Pour ce faire, nous créons un fichier Futhark `gol.fut` qui sert à calculer le prochain état d'une partie de l'automate cellulaire.
-
-```
-entry next_chunk_board [n][m] (chunk_board :[n][m]i8) (envelope: envelope_2d_i8) :[n][m]i8 =
-    let augmented_board = augment_board chunk_board envelope
-    let next_chunk_board = compute_next_chunk_board augmented_board
-    in next_chunk_board[1:n+1, 1:m+1] :> [n][m]i8
-```
-Dans ce fichier, la fonction `next_chunk_board` prends en paramètres la portion de l'automate cellulaire qui nous est attribuée ainsi que l'enveloppe.
-Ensuite, cette fonction reconstruit l'automate cellulaire en ajoutant les voisins des cellules situés aux extrémités puis une autre fonction calcule le prochain état de chaque cellule. Finalement, le résultat de la fonction est retournée sans l'enveloppe car elle n'est plus nécessaire.
-
-```c
-void compute_next_chunk_board(struct dispatch_context *dc, struct futhark_context *fc, chunk_info_t *ci) {
-    envelope_t *outer_envelope = get_outer_envelope(dc, fc, 1);
-    
-    struct futhark_opaque_envelope_2d_i8 *fut_outer_envelope = futhark_outer_envelope_new(dc, fc, outer_envelope,
-    futhark_restore_opaque_envelope_2d_i8, FUTHARK_I8);
-    
-    struct futhark_i8_2d *fut_chunk_board = futhark_new_i8_2d(fc, ci->data, ci->dimensions[0], ci->dimensions[1]);
-    struct futhark_i8_2d *fut_next_chunk_board;
-    
-    futhark_context_sync(fc);
-    futhark_entry_next_chunk_board(fc, &fut_next_chunk_board, fut_chunk_board, fut_outer_envelope);
-    futhark_context_sync(fc);
-    
-    futhark_values_i8_2d(fc, fut_next_chunk_board, ci->data);
-    futhark_context_sync(fc);
-    
-    /* ... Free resources ... */
-}
-
-int main(int argc, char *argv[]) {
-    /* ... MPI & Futhark Init ... */
-
-    const int N_ITERATIONS = 100;
-    int board_dimensions[2] = {800, 600};
-    struct dispatch_context *dc = dispatch_context_new(board_dimensions, MPI_INT8_T, 2);
-    chunk_info_t ci = get_chunk_info(disp_context);
-    init_chunk_board(&ci);
-
-    for (int i = 0; i < N_ITERATIONS; ++i) {
-        compute_next_chunk_board(dc, fc, &ci);
-    }
-    
-    /* ... Free resources ... */
-}
-```
-
-En plus d'un fichier Futhark, un fichier C `main.c` est nécessaire pour utiliser notre librairie. Ce fichier est le point d'entrée du programme, il s'occupe d'initialiser l'environnement MPI, Futhark et de notre librairie.
-L'initialisation de notre librairie via la fonction `dispatch_context_new` nécessite de spécifier les dimensions de l'automate cellulaire, le type de données contenu et le nombre de dimensions. Ensuite, on récupère le morceau de l'automate cellulaire qui nous est attribué, d'initialiser les valeurs et de calculer le prochain état de l'automate cellulaire via la fonction `compute_next_chunk_board`. Dans cette fonction, il faut récupérer l'enveloppe, convertir en type Futhark et appeler notre fonction Futhark qui met à jour l'état des cellules (`futhark_entry_next_chunk_board`). Finalement, avec la fonction `futhark_values_i8_2d`, on récupère la nouvelle valeur des cellules.
+Avec la librairie que nous avons créée, nous avons implémenté le jeu de la vie. Le code est relativement le même que l'exemple précédemment, par conséquent, il n'est pas expliqué.
 
 ## CPU Benchmarks
 
@@ -89,28 +40,9 @@ Le benchmark séquentiel et multicœurs sont effectués comme suit :
 * 15 mesures sont effectuées
 * une mesure correspond à 100 générations,
 
-| Number of tasks | Average [s] | Standard Derivation [s] | Speedup | Number of measures |
-|:---:|:---:|:---:|:---:|:---:|
-| 1 | 4207.341 [s] | ± 85.994 [s] | x1.0 | 15 |
-| 2 | 1834.217 [s] | ± 53.498 [s] | x2.3 | 15 |
-| 4 | 1015.535 [s] | ± 17.84 [s] | x4.1 | 15 |
-| 8 | 517.61 [s] | ± 7.355 [s] | x8.1 | 15 |
-| 16 | 261.422 [s] | ± 9.078 [s] | x16.1 | 15 |
-| 32 | 116.66 [s] | ± 0.263 [s] | x36.1 | 15 |
-| 64 | 65.678 [s] | ± 0.31 [s] | x64.1 | 15 |
-| 128 | 33.348 [s] | ± 0.208 [s] | x126.2 | 15 |
+
 *Array of results for the parallelized-sequential version*
 
-| Number of tasks | Average [s] | Standard Derivation [s] | Speedup | Number of measures |
-|:---:|:---:|:---:|:---:|:---:|
-| 1 | 3207.645 [s] | ± 55.361 [s] | x1.0 | 15 |
-| 2 | 1354.403 [s] | ± 98.014 [s] | x2.4 | 15 |
-| 4 | 718.864 [s] | ± 23.786 [s] | x4.5 | 15 |
-| 8 | 369.332 [s] | ± 0.098 [s] | x8.7 | 15 |
-| 16 | 184.933 [s] | ± 0.041 [s] | x17.3 | 15 |
-| 32 | 94.574 [s] | ± 0.122 [s] | x33.9 | 15 |
-| 64 | 44.917 [s] | ± 1.667 [s] | x71.4 | 15 |
-| 128 | 23.774 [s] | ± 0.038 [s] | x134.9 | 15 |
 
 *Array of results for the parallelized-multicore version*
 
@@ -135,28 +67,10 @@ Le benchmark OpenCL et CUDA sont effectués comme suit :
   de manière équitable les cartes graphiques.
 
 
-| Number of tasks | Number of GPUs | Average [s] | Standard Derivation [s] | Speedup | Number of measures |
-|:---:|:---:|:---:|:---:|:---:|:---:|
-| 1 | 1 | 107.849 [s] | ± 0.213 [s] | x1.0 | 15 |
-| 2 | 2 | 53.843 [s] | ± 0.085 [s] | x2.0 | 15 |
-| 4 | 4 | 43.714 [s] | ± 0.024 [s] | x2.5 | 15 |
-| 8 | 8 | 43.403 [s] | ± 0.038 [s] | x2.5 | 15 |
-| 16 | 8 | 43.499 [s] | ± 0.257 [s] | x2.5 | 15 |
-| 32 | 8 | 43.777 [s] | ± 0.281 [s] | x2.5 | 15 |
-| 64 | 8 | 20.917 [s] | ± 0.183 [s] | x5.2 | 15 |
-| 128 | 8 | 13.583 [s] | ± 0.112 [s] | x7.9 | 15 |
+
 *Array of results for the parallelized-OpenCL version*
 
-| Number of tasks | Number of GPUs | Average [s] | Standard Derivation [s] | Speedup | Number of measures |
-|:---:|:---:|:---:|:---:|:---:|:---:|
-| 1 | 1 | 107.215 [s] | ± 0.193 [s] | x1.0 | 15 |
-| 2 | 2 | 53.434 [s] | ± 0.041 [s] | x2.0 | 15 |
-| 4 | 4 | 43.609 [s] | ± 0.065 [s] | x2.5 | 15 |
-| 8 | 8 | 43.375 [s] | ± 0.041 [s] | x2.5 | 15 |
-| 16 | 8 | 43.111 [s] | ± 0.088 [s] | x2.5 | 15 |
-| 32 | 8 | 43.525 [s] | ± 0.415 [s] | x2.5 | 15 |
-| 64 | 8 | 20.747 [s] | ± 0.113 [s] | x5.2 | 15 |
-| 128 | 8 | 13.909 [s] | ± 0.118 [s] | x7.7 | 15 |
+
 *Array of results for the parallelized-CUDA version*
 
 \cimg{figs/gol_result_and_speedup_gpu.png}{width=\linewidth}{First state of blinker}{Source : Taken from
diff --git a/src/text/09-lattice-boltzmann.md b/src/text/09-lattice-boltzmann.md
index 2b44c5abf1648c160f8ba816f11a3c51790b9e42..fc6d1b10c297ef9feba1f96edad77a30d471e31d 100644
--- a/src/text/09-lattice-boltzmann.md
+++ b/src/text/09-lattice-boltzmann.md
@@ -1,4 +1,5 @@
 # Lattice-Boltzmann
+
 The lattice Boltzmann method (LBM) has established itself in the past decades as a valuable approach to Computational
 Fluid Dynamics (CFD). It is commonly used to model time-dependent, incompressible or compressible flows in a
 regime of Direct Numerical Simulation (DNS) or Large Eddy Simulation (LES). One of its strengths lies in the ability to easily