GitHub

@@ -470,7 +470,7 @@ Comparez la vitesse avec et sans Numba lorsque la taille de l'échantillon est g

470470

:class: dropdown

471471

```

472472473-

Voici une solution :

473+

Voici une solution :

474474475475

```{code-cell} ipython3

476476

@jit

@@ -487,7 +487,7 @@ def calculate_pi(u_draws, v_draws):

487487

return area_estimate * 4 # division par le rayon**2

488488

```

489489490-

Voyons maintenant à quelle vitesse cela s'exécute :

490+

Voyons maintenant à quelle vitesse cela s'exécute :

491491492492

```{code-cell} ipython3

493493

with qe.Timer():

@@ -504,7 +504,7 @@ considérablement plus de temps sur notre machine.

504504505505

Nous obtenons donc un gain de vitesse important en ajoutant quatre caractères.

506506507-

La solution ci-dessus adopte l'une des deux approches naturelles : elle *tire tous les

507+

La solution ci-dessus adopte l'une des deux approches naturelles : elle *tire tous les

508508

points aléatoires d'abord*, les stocke dans `u_draws` et `v_draws`, puis laisse la

509509

fonction jittée les parcourir en boucle.

510510

@@ -539,7 +539,7 @@ aléatoires sont tirés une seule fois dans le bloc de configuration partagé ci

539539

la seconde approche paie pour ses tirages à l'intérieur de la fonction chronométrée.

540540541541

Pour comparer les deux approches de manière équitable, nous chronométrons la première approche de bout en bout,

542-

en incluant le coût de la génération des tableaux :

542+

en incluant le coût de la génération des tableaux :

543543544544

```{code-cell} ipython3

545545

with qe.Timer():

@@ -657,7 +657,7 @@ print(np.mean(x == 0)) # Fraction du temps où x est dans l'état 0

657657658658

C'est (approximativement) la bonne sortie.

659659660-

Chronométrons-le maintenant :

660+

Chronométrons-le maintenant :

661661662662

```{code-cell} ipython3

663663

with qe.Timer():

@@ -684,7 +684,7 @@ with qe.Timer():

684684

compute_series_numba(n, U)

685685

```

686686687-

C'est une belle amélioration de vitesse pour une ligne de code !

687+

C'est une belle amélioration de vitesse pour une ligne de code !

688688689689

```{solution-end}

690690

```

@@ -716,7 +716,7 @@ Pour la taille de la simulation Monte-Carlo, utilisez quelque chose de substanti

716716

:class: dropdown

717717

```

718718719-

Voici une solution :

719+

Voici une solution :

720720721721

```{code-cell} ipython3

722722

@jit(parallel=True)

@@ -733,7 +733,7 @@ def calculate_pi_parallel(u_draws, v_draws):

733733

return area_estimate * 4 # division par le rayon**2

734734

```

735735736-

Voyons maintenant à quelle vitesse cela s'exécute :

736+

Voyons maintenant à quelle vitesse cela s'exécute :

737737738738

```{code-cell} ipython3

739739

with qe.Timer():

@@ -775,16 +775,16 @@ Dans {ref}`numba_ex3`, nous avons tiré tous les points aléatoires *avant* la b

775775776776

Il est tentant de plutôt tirer chaque point *à l'intérieur* de la boucle `prange`, en passant un générateur `rng` en argument et en appelant `rng.uniform()` dans le corps de la boucle.

777777778-

Essayez-le : le code devrait s'exécuter et renvoyer un nombre proche de $\pi$, pourtant il y a un bug subtil dans cette approche.

778+

Essayez-le : le code devrait s'exécuter et renvoyer un nombre proche de $\pi$, pourtant il y a un bug subtil dans cette approche.

779779780-

Enquêtez comme suit :

780+

Enquêtez comme suit :

781781782782

1. Appelez votre fonction quelques fois avec la *même* graine et vérifiez si le résultat est reproductible.

783783

2. Répétez l'estimation de nombreuses fois sur une gamme de tailles d'échantillon et comparez sa dispersion à celle d'une version parallèle correcte.

784784785785

Expliquez ensuite ce qui ne va pas et donnez une manière correcte de tirer à l'intérieur d'une boucle parallèle.

786786787-

Astuce : essayez d'utiliser une fonction aléatoire ancienne telle que `np.random.uniform()` au lieu d'un `Generator` et voyez ce qui se passe.

787+

Astuce : essayez d'utiliser une fonction aléatoire ancienne telle que `np.random.uniform()` au lieu d'un `Generator` et voyez ce qui se passe.

788788

```

789789790790

```{solution-start} numba_ex_race

@@ -829,7 +829,7 @@ imprévisible.

829829830830

Deux symptômes révèlent le problème.

831831832-

*Symptôme 1 : le résultat n'est plus reproductible.*

832+

*Symptôme 1 : le résultat n'est plus reproductible.*

833833834834

Un générateur correct renvoie la même réponse chaque fois qu'on lui donne la même graine.

835835

@@ -842,7 +842,7 @@ for seed in (1, 1, 1):

842842843843

Chaque appel utilise la même graine, pourtant les réponses diffèrent.

844844845-

*Symptôme 2 : l'estimateur est bien plus bruité qu'il ne devrait l'être.*

845+

*Symptôme 2 : l'estimateur est bien plus bruité qu'il ne devrait l'être.*

846846847847

Les tirages dupliqués et corrélés portent moins d'information que $n$ tirages indépendants, de sorte que la taille d'échantillon *effective* est bien plus petite que $n$.

848848

@@ -889,7 +889,7 @@ plt.show()

889889890890

Les deux bandes sont centrées sur $\pi$, mais la bande associée à la course aux données est bien plus large que l'autre et se rétrécit très lentement à mesure que la taille de l'échantillon augmente.

891891892-

L'autre option sûre est celle de {ref}`numba_ex3` : tirer les points avant la boucle afin que la boucle parallèle ne fasse que lire depuis la mémoire.

892+

L'autre option sûre est celle de {ref}`numba_ex3` : tirer les points avant la boucle afin que la boucle parallèle ne fasse que lire depuis la mémoire.

893893894894

```{solution-end}

895895

```

Read the original on github.com ↗