-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathIntel_MKL.qmd
240 lines (161 loc) · 7.4 KB
/
Intel_MKL.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
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
---
title: "Intel MKL & Open Blas"
format: html
lang: fr
toc: true
author:
- Annaig De Walsche
- Barbara Bricout
- Tristan Mary-Huard
- Armand Favrot
- Félix Cheysson
- Théodore Vanrenterghem
date: 20/08/2023
---
Nous allons d'abord installer les librairies **Intel MKL** (processeur Intel nécessaire) & **Open Blas**. Ces deux librairies d'algèbre linéaire permettent d'optimiser et/ou de paralléliser un certains nombre d'opérations algébriques, notamment le calcul matriciel.
Nous les testons avec un produit matriciel de 10000 x 10000.
```{r}
#| eval: false
size <- 10000
mat <- matrix(rnorm(size**2), size, size)
tic()
get_res <- mat %*% mat
toc()
```
Avant l'installation les librairies utilisées pour du calcul matriciel en R sont `libblas.so.3.10.0` et `liblapack.so.3.10.0` (on peut les voir avec la ligne suivante)
```{r}
#| eval: false
sessionInfo()
```
### Installation sur Windows (seulement Intel MKL)
Le plus simple est de télécharger les librairies Intel - MKL sur le [seafile d'Agroparistech](https://seafile.agroparistech.fr/d/696def33ceb848508cb0/).
#### 1 - Faire une copie de la version actuelle de `BLAS` et `LAPACK`:
Dans le dossier `C:\Program Files\R\Your_R_Version\bin\x64`, copier `Rblas.dll` et `Rlapack.dll` dans un autre dossier à **conserver** pour pouvoir revenir aux librairies de la base `R`.
#### 2 - Télécharger les librairies **Intel-MKL**
En allant sur <https://seafile.agroparistech.fr/d/696def33ceb848508cb0/> et en cliquant sur le boutton vert `ZIP` en haut à droite, vous pouvez télécharger le dossier. Puis le déziper.

#### 3 - Copier les bibliothèques
Lorsque le dossier est décompressé, allez dans `\Intel-MKL-Libs\Intel_MKL` et copiez tous les fichiers dans votre `C:\Program Files\R\Your_R_Version\bin\x64`.
#### 4 - Réouverture de `R`
Vous pouvez fermer votre session `R` et la rouvrir. Maintenant votre session `R` devrait fonctionner avec `Intel-MKL`.
Vérifiez si vous avez gagné en efficacité sur votre ordinateur. Attention, le code déjà parallélisé pourrait être moins efficace car ces bibliothèques parallélisent déjà l'algèbre linéaire.
Concrètement on remplace les deux fichiers faisant appel aux librairies `BLAS` et `LAPACK` par des fichiers du même nom mais qui en pratique font implicitement appel à mkl. Pensez bien à sauver une copie des fichiers initiaux.
Pour retourner à la base `R` il suffit d'opérer à l'opération inverse, copie des fichiers `Rblas.dll`, `Rlapack.dll` et `libiomp5md.dll` du dossier `C:\Program Files\R\Your_R_Version\bin\x64`. Les mettre en sécurité puis copier les librairies des `Rblas.dll` et `Rlapack.dll` depuis votre sauvegarde ou <https://seafile.agroparistech.fr/d/696def33ceb848508cb0/>.
### Installation sur Ubuntu 22.04 (Intel MKL et Open Blas)
#### Intel MKL
`sudo apt install intel-mkl`
#### Open Blas
`sudo apt install libopenblas-base`
#### Changement de librairie
Pour changer la librairie Blas
`sudo update-alternatives --config libblas.so.3-x86_64-linux-gnu`
Pour changer la librairie Lapack
`sudo update-alternatives --config liblapack.so.3-x86_64-linux-gnu`
Dans les deux cas cela ouvre un menu montrant les différentes librairies disponibles.
### Comparaison produit matriciel (`BLAS`)
Une fois installées, vérifier si les librairies sont bien référencées pour le calcul matriciel avec
```{r}
#| eval: false
sessionInfo()
```
```{r}
#| eval: false
tic()
get_res <- mat %*% mat
toc()
```
| Système d'exploitation | Library | CPU | Base R | Intel MKL |
|--------------|--------------|-------------------|--------------|--------------|
| **Windows 10** | [Intel MKL]{style="color:red;"} | Intel Xeon - 16 processeur logiques | 15 min | [7 secondes]{style="color:red;"} |
| Ubuntu 22.04 | Intel MKL | Intel i7 - 8 processeur logiques | 5 min | Moins de 1 min |
| **Ubuntu 22.04** | [Open Blas]{style="color:red;"} | Intel i7 - 8 processeur logiques | 5 min | [9-14 secondes]{style="color:red;"} |
### Benchmark approfondi
Nous allons comparer les performances de toutes ces librairies sur Ubuntu avec un ordinateur à 8 cœurs Intel I7. Pour effectuer ce benchmark nous devons réitérer les fermetures de sessions donc le même code à été lancé séquentiellement.
#### Set-up
##### Packages
```{r}
#| message: false
library(ggplot2)
library(purrr)
library(dplyr)
library(furrr)
library(future)
library(tictoc)
```
##### Fonctions de test
```{r}
test_type <- function(seed, type = 'type'){
res <- data.frame(seed = rep(0,2),
time = rep(0,2),
type = rep(0,2),
matrix_size = rep(0,2))
matrix_size <- c(200, 2000)
for(j in 1:2){
set.seed(seed)
mat = matrix(rnorm(matrix_size[[j]] ^ 2), ncol = matrix_size[[j]])
T1 = Sys.time()
res_tmp = mat %*% mat
T2 = Sys.time()
res$seed[[j]] <- seed
res$time[[j]] <- difftime(T2, T1)
res$type[[j]] <- type
res$matrix_size[[j]] <- matrix_size[[j]]
}
return(res)
}
compare <- function(seeds,type = 'type'){
if(type == "base"){
plan(multisession, workers = availableCores())
future_map_dfr(seeds,~test_type(.x,type = type))
}else{
map_dfr(seeds,~test_type(.x,type = type))
}
}
my_multiplot <- function(data){
ggplot(data = data,
aes(x = time, y = type, fill = type,col = type)) +
geom_boxplot(alpha = 0.5,show.legend = F) +
facet_wrap("matrix_size",scales = "free_x",labeller = label_both)
}
```
##### Paramètres
```{r}
#| eval: false
types <- c("base","openblas","lasy_intel_mkl","intel_mkl_high_perf")
seeds <- 1:20
```
##### Sélection de la librarie active
```{r}
#| eval: false
type <- types[[1]]
```
##### Calculs et sauvegarde
```{r}
#| eval: false
res <- compare(seeds,type)
saveRDS(res, file = paste0('res_algebrica_calculations/res_',type,'.RDS'))
```
##### Chargement des résultats
```{r}
list_of_results <- grep("^res_algebrica_calculations/res_.*.RDS$",
dir(recursive = T),
value=T)
res_table <- map_dfr(list_of_results,readRDS)
```
##### Graph des résultats complets
On peut voir dans ces graphiques que dans l'ensemble **OpenBlas** et **Intel-MKL** sont plus efficaces que la base de R. Cependant d'autres remarques sont à faire :
1. **OpenBlas** est utilise constamment l'ensemble des cœurs disponibles, ce comportement extrême peu devenir un problème lors des longs calculs où lorsque l'on utilise des librairies plus complexes comme par exemple `Rcpp` avec laquelle il obtiens des performances largement plus faible que la base.
1. Nous avons aussi remarqué une certaine variations dans les performances de **Intel-MKL** sur Ubuntu seulement. Bien que toujours observée plus efficace que la base. Il est fréquent que pour un même calcul le temps soit jusqu'à 4 fois plus long que le minimum. Cette variation semble être fixe pour chaque session R ouverte. Dans ces graph nous appelons "lasy intel mkl" les sessions de faible performances.
```{r}
my_multiplot(res_table)
```
##### Sans la base `R`
```{r}
res_table %>%
filter(type != "base") %>%
my_multiplot()
```
### Références
- <https://www.intel.com/content/www/us/en/docs/onemkl/get-started-guide/2023-0/overview.html>
- <https://www.openblas.net/>
- <https://github.com/xianyi/OpenBLAS/wiki/faq>