{"id":1240,"date":"2026-08-21T14:28:35","date_gmt":"2026-08-21T14:28:35","guid":{"rendered":"https:\/\/matforge.org\/?p=1240","raw":"https:\/\/matforge.org\/?p=1240"},"modified":"2026-08-21T14:28:35","modified_gmt":"2026-08-21T14:28:35","slug":"gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide","status":"publish","type":"post","link":"https:\/\/matforge.org\/fr\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\/","title":{"rendered":"Acc\u00e9l\u00e9ration GPU pour les simulations FIPY : Guide d&rsquo;int\u00e9gration CUPY et NUMBA","raw":"Acc\u00e9l\u00e9ration GPU pour les simulations FIPY : Guide d'int\u00e9gration CUPY et NUMBA"},"content":{"rendered":"<span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\"> 13<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span><p>Les simulations FIPY peuvent atteindre <strong>10x \u00e0 100x acc\u00e9l\u00e9rations<\/strong> en d\u00e9pla\u00e7ant des op\u00e9rations de calcul sur le GPU \u00e0 l&rsquo;aide de CUPY (remplacement NumPy) ou NUMBA (compilation JIT). CUPY excelle dans les op\u00e9rations de tableau et n\u00e9cessite des modifications de code minimales, tandis que Numba acc\u00e9l\u00e8re les boucles Python et les fonctions personnalis\u00e9es. Cependant, l&rsquo;acc\u00e9l\u00e9ration du GPU n&rsquo;est pas toujours b\u00e9n\u00e9fique : de petits probl\u00e8mes, des op\u00e9rations li\u00e9es \u00e0 la m\u00e9moire et des structures de donn\u00e9es complexes peuvent annuler les gains. Ce guide couvre la mise en \u0153uvre pratique, les comparaisons de performances, les contraintes de m\u00e9moire et le moment de choisir chaque approche pour vos simulations PDE.<\/p>\n<h2>Introduction&nbsp;: Pourquoi l&rsquo;acc\u00e9l\u00e9ration du GPU est-elle importante pour FIPY&nbsp;?<\/h2>\n<p>FIPY est un puissant solveur d&rsquo;\u00e9quations aux d\u00e9riv\u00e9es partielles (PDE) bas\u00e9 sur Python qui utilise la m\u00e9thode du volume fini (FVM). Alors que la conception orient\u00e9e objet de Fipy le rend accessible, les simulations 3D \u00e0 grande \u00e9chelle avec des maillages fins peuvent devenir co\u00fbteuses en termes de calcul, avec des temps d&rsquo;ex\u00e9cution allant de quelques heures \u00e0 quelques jours.<\/p>\n<p>La m\u00e9thode du volume fini est naturellement adapt\u00e9e \u00e0 l&rsquo;acc\u00e9l\u00e9ration du GPU, car les calculs de flux \u00e0 travers les interfaces de cellules peuvent \u00eatre calcul\u00e9s ind\u00e9pendamment et en parall\u00e8le. En mappant ces calculs centr\u00e9s sur les cellules \u00e0 des milliers de c\u0153urs de GPU, les chercheurs peuvent obtenir des am\u00e9liorations spectaculaires des performances. Cependant, la r\u00e9alisation de ces gains n\u00e9cessite une attention particuli\u00e8re aux d\u00e9tails de la mise en \u0153uvre et une compr\u00e9hension du moment o\u00f9 l&rsquo;acc\u00e9l\u00e9ration du GPU aide r\u00e9ellement.<\/p>\n<p>Ce guide fournit un cadre pratique pour int\u00e9grer l&rsquo;acc\u00e9l\u00e9ration du GPU dans vos flux de travail Fipy \u00e0 l&rsquo;aide de Cupy et Numba, les deux principales biblioth\u00e8ques de calcul GPU Python.<\/p>\n<h2>Comprendre CUPY et NUMBA&nbsp;: diff\u00e9rences cl\u00e9s<\/h2>\n<p>Avant de plonger dans la mise en \u0153uvre, il est essentiel de comprendre en quoi CUPY et NUMBA diff\u00e8rent dans leur approche de l&rsquo;acc\u00e9l\u00e9ration des GPU.<\/p>\n<h3>Cupy : Remplacement de NumPy Drop-in<\/h3>\n<p>Cupy est une biblioth\u00e8que open-source qui impl\u00e9mente un sous-ensemble d&rsquo;API Nvidia et Scipy sur les GPU Nvidia \u00e0 l&rsquo;aide de CUDA et sur les GPU AMD utilisant ROCM. La proposition de valeur fondamentale est la simplicit\u00e9&nbsp;: <strong>Vous pouvez souvent acc\u00e9l\u00e9rer le code existant en rempla\u00e7ant simplement <code>import numpy as np<\/code> par <code>import cupy as cp<\/code><\/strong>.<\/p>\n<h3>Comment fonctionne Cupie&nbsp;:<\/h3>\n<ul>\n<li>Les baies CUPY (<code>cupy.ndarray<\/code>) sont stock\u00e9es dans la m\u00e9moire du GPU, tandis que les baies de NumPy vivent dans la RAM du syst\u00e8me<\/li>\n<li>La plupart des op\u00e9rations Numpy ont des \u00e9quivalents CUPY qui s&rsquo;ex\u00e9cutent sur le GPU<\/li>\n<li>Le transfert de donn\u00e9es entre CPU et GPU est explicite via <code>cp.asnumpy()<\/code> (GPU\u2192CPU) et <code>cp.asarray()<\/code> (CPU\u2192GPU)<\/li>\n<\/ul>\n<h3>Caract\u00e9ristiques de performance :<\/h3>\n<ul>\n<li>Les op\u00e9rations de la baie peuvent \u00eatre <strong>100x+ plus rapides<\/strong> que NumPy pour les grands ensembles de donn\u00e9es en raison du parall\u00e9lisme GPU<\/li>\n<li>Les frais g\u00e9n\u00e9raux des transferts de donn\u00e9es entre le processeur et le GPU peuvent dominer s&rsquo;ils ne sont pas minimis\u00e9s<\/li>\n<li>Id\u00e9al pour les op\u00e9rations en masse : multiplication matricielle, FFT, op\u00e9rations \u00e9l\u00e9mentaires, r\u00e9ductions<\/li>\n<\/ul>\n<h3>Numba : compilation juste \u00e0 temps<\/h3>\n<p>NUMBA est un compilateur JIT open source qui traduit les fonctions Python en code machine optimis\u00e9 lors de l&rsquo;ex\u00e9cution \u00e0 l&rsquo;aide de LLVM. Contrairement \u00e0 Cupy, qui se concentre sur les op\u00e9rations de la baie, Numba acc\u00e9l\u00e8re les <strong>boucles de Python, les fonctions arithm\u00e9tiques et num\u00e9riques<\/strong> en les compilant vers un code machine efficace qui peut s&rsquo;ex\u00e9cuter \u00e0 la fois sur le processeur et sur le GPU.<\/p>\n<h3>Comment fonctionne Numba&nbsp;:<\/h3>\n<ul>\n<li>Utilisez le d\u00e9corateur <code>@jit<\/code> pour marquer les fonctions pour la compilation<\/li>\n<li><code>@njit<\/code> (pas de mode Python) garantit des performances maximales en \u00e9vitant les frais g\u00e9n\u00e9raux de l&rsquo;interpr\u00e9teur Python<\/li>\n<li><code>@cuda.jit<\/code> Pour \u00e9crire des noyaux CUDA personnalis\u00e9s qui s&rsquo;ex\u00e9cutent directement sur le GPU<\/li>\n<li><code>parallel=True<\/code> Active la parall\u00e9lisation automatique des boucles sur les CPU multi-c\u0153urs<\/li>\n<\/ul>\n<h3>Caract\u00e9ristiques de performance :<\/h3>\n<ul>\n<li>Les boucles qui sont lentes en Python pur peuvent approcher des vitesses <strong>C ou Fortran<\/strong><\/li>\n<li>La compilation JIT ajoute une surcharge de d\u00e9marrage (g\u00e9n\u00e9ralement quelques secondes en minutes)<\/li>\n<li>Fonctionne avec le flux de contr\u00f4le Python, les op\u00e9rations NumPy et les types de donn\u00e9es de base<\/li>\n<li>Le mode GPU (<code>@cuda.jit<\/code>) n\u00e9cessite l&rsquo;\u00e9criture de noyaux CUDA explicites, qui a une courbe d&rsquo;apprentissage plus raide<\/li>\n<\/ul>\n<h2>CUPY VS NUMBA&nbsp;: Lequel choisir&nbsp;?<\/h2>\n<p>Le choix entre CUPY et NUMBA d\u00e9pend de votre charge de travail sp\u00e9cifique, de votre structure de code et de votre volont\u00e9 de refactoriser.<\/p>\n<h3>Utilisez CUPY lorsque&nbsp;:<\/h3>\n<ul>\n<li>Vous avez <strong>code de NumPy-Heavy existant<\/strong> et souhaitez des modifications minimes<\/li>\n<li>Votre goulot d&rsquo;\u00e9tranglement est <strong>op\u00e9rations de r\u00e9seau<\/strong> (matrix math\u00e9matiques, fonctions \u00e9l\u00e9mentaires, agr\u00e9gations)<\/li>\n<li>Vous travaillez avec des <strong>grands tableaux contigus<\/strong> qui s&rsquo;int\u00e8grent confortablement dans la m\u00e9moire GPU<\/li>\n<li>Vous pr\u00e9f\u00e9rez une approche de remplacement <strong>drop-in<\/strong> \u00e0 l&rsquo;apprentissage de nouveaux mod\u00e8les de programmation<\/li>\n<\/ul>\n<p><strong>Sc\u00e9nario d&rsquo;exemple&nbsp;:<\/strong> Vous r\u00e9solvez une \u00e9quation de diffusion avec un grand maillage 3D et le co\u00fbt dominant est dans les op\u00e9rations matricielles et les math\u00e9matiques vectorielles&nbsp;: le passage \u00e0 CUPY peut entra\u00eener des acc\u00e9l\u00e9rations imm\u00e9diates avec seulement quelques lignes de code modifi\u00e9es.<\/p>\n<h3>Utilisez NUMBA lorsque&nbsp;:<\/h3>\n<ul>\n<li>Votre goulot d&rsquo;\u00e9tranglement est <strong>boucles Python<\/strong> qui it\u00e8rent sur des tableaux ou des cellules<\/li>\n<li>Vous avez <strong>fonctions num\u00e9riques personnalis\u00e9es<\/strong> qui ne correspondent pas proprement aux op\u00e9rations NumPy<\/li>\n<li>Vous avez besoin d&rsquo;un <strong>contr\u00f4le \u00e0 grain fin<\/strong> sur le parall\u00e9lisme et les mod\u00e8les d&rsquo;acc\u00e8s \u00e0 la m\u00e9moire<\/li>\n<li>Vous impl\u00e9mentez <strong>Nouveaux algorithmes<\/strong> \u00e0 partir de z\u00e9ro et pouvez concevoir des GPU d\u00e8s le d\u00e9part<\/li>\n<\/ul>\n<p><strong>Exemple de sc\u00e9nario&nbsp;:<\/strong> Vous impl\u00e9mentez un limiteur de flux ou un terme source qui implique une logique conditionnelle complexe et des mises \u00e0 jour it\u00e9ratives par cellule\u2014numba <code>@njit<\/code> avec <code>prange<\/code> peut parall\u00e9liser efficacement.<\/p>\n<h3>Pouvez-vous utiliser les deux&nbsp;?<\/h3>\n<p>Oui. CUPY et NUMBA peuvent \u00eatre combin\u00e9s :<\/p>\n<ul>\n<li>Utilisez CUPY pour les op\u00e9rations et les transferts de tableaux<\/li>\n<li>Utilisez Numba pour \u00e9crire des noyaux CUDA personnalis\u00e9s qui fonctionnent sur des tableaux CUPY<\/li>\n<li>Le support CUDA de Numba peut lancer des noyaux qui traitent directement les donn\u00e9es CUPY<\/li>\n<\/ul>\n<p>Pour les utilisateurs de FIPY, une approche pratique consiste d&rsquo;abord \u00e0 profiler, puis \u00e0 appliquer CUPY aux sections lourdes en r\u00e9seau et \u00e0 Numba aux sections lourdes de boucles, selon les besoins.<\/p>\n<h2>Mise en \u0153uvre pratique : Acc\u00e9l\u00e9rer Fipy avec Cupy<\/h2>\n<h3>\u00c9tape&nbsp;1&nbsp;: Installez CUPY<\/h3>\n<p>CUPY n\u00e9cessite CUDA Toolkit (NVIDIA) ou ROCM (AMD). Installez avec :<\/p>\n<pre><code class=\"language-bash\"># For CUDA 11.x\npip install cupy-cuda11x\n\n# For CUDA 12.x\npip install cupy-cuda12x\n\n# Or from source for custom builds\n<\/code><\/pre>\n<p>V\u00e9rifier l&rsquo;installation&nbsp;:<\/p>\n<pre><code class=\"language-python\">import cupy as cp\nprint(cp.cuda.runtime.getDeviceCount())  # Should print number of GPUs\n<\/code><\/pre>\n<h3>\u00c9tape&nbsp;2&nbsp;: Remplacez les importations NumPy<\/h3>\n<p>La forme d&rsquo;int\u00e9gration la plus simple consiste \u00e0 remplacer NumPy par Cupy dans tout votre code de solveur :<\/p>\n<pre><code class=\"language-python\"># Before\nimport numpy as np\n\n# After\nimport cupy as cp\n<\/code><\/pre>\n<p><strong>Important&nbsp;:<\/strong> \u00e0 lui seul, ce changement n&rsquo;acc\u00e9l\u00e9rera pas comme par magie Fipy car Fipy lui-m\u00eame utilise Numpy en interne. Pour gagner en performances, vous devez vous assurer que les <strong>grands tableaux<\/strong> (coordonn\u00e9es maill\u00e9es, vecteurs de solution, matrices de coefficients) sont d\u00e9plac\u00e9s vers le GPU et que les <strong>noyaux de calcul<\/strong> fonctionnent sur des baies de GPU.<\/p>\n<h3>\u00c9tape&nbsp;3&nbsp;: Transf\u00e9rez les donn\u00e9es vers le GPU<\/h3>\n<p>Les variables FIPY sont g\u00e9n\u00e9ralement <code>numpy.ndarray<\/code>. Vous devez les d\u00e9placer explicitement vers la m\u00e9moire GPU&nbsp;:<\/p>\n<pre><code class=\"language-python\"># Example: FiPy solution variable\nphi = CellVariable(name=\"phi\", mesh=mesh)  # Uses NumPy internally\n\n# To use CuPy, you'd need to override the array storage:\nphi._array = cp.asarray(phi._array)  # Move to GPU\n<\/code><\/pre>\n<p><strong>Attention&nbsp;:<\/strong> Il s&rsquo;agit d&rsquo;une technique avanc\u00e9e et peut briser les hypoth\u00e8ses internes de Fipy. Une approche plus pratique consiste \u00e0 utiliser CUPY pour les <strong>pr\u00e9traitement<\/strong>, les <strong>post-traitement<\/strong> et les <strong>op\u00e9rations autonomes<\/strong> en dehors de la boucle de solveur de base de FIPY, ou pour impl\u00e9menter des termes personnalis\u00e9s qui utilisent des tableaux CUPY.<\/p>\n<h3>\u00c9tape&nbsp;4&nbsp;: Impl\u00e9mentez les termes GPU personnalis\u00e9s<\/h3>\n<p>FIPY autorise les termes personnalis\u00e9s via les objets <code>Term<\/code>. Vous pouvez cr\u00e9er un terme qui utilise Cupy pour son calcul :<\/p>\n<pre><code class=\"language-python\">import cupy as cp\nfrom fipy import Term, CellVariable, Mesh\n\nclass CuPyConvectionTerm(Term):\n    \"\"\"Convection term implemented with CuPy for GPU acceleration.\"\"\"\n    \n    def __init__(self, velocity):\n        self.velocity = velocity  # Should be a CuPy array\n    \n    def _buildMatrix(self, var, solver, boundaryConditions=(), dt=1.0):\n        # This method would construct the discretized matrix using CuPy\n        # Implementation requires deep FiPy knowledge\n        pass\n    \n    def _compute(var, velocity):\n        # Use CuPy for the actual computation\n        # var should be a CuPy array\n        flux = velocity * var\n        return flux\n<\/code><\/pre>\n<p>Cette approche est avanc\u00e9e et n\u00e9cessite de comprendre les internes de discr\u00e9tisation de Fipy.<\/p>\n<h3>\u00c9tape&nbsp;5&nbsp;: Profiler et valider<\/h3>\n<p>Toujours profiler pour confirmer l&rsquo;acc\u00e9l\u00e9ration&nbsp;:<\/p>\n<pre><code class=\"language-python\">import time\nimport cupy as cp\n\n# CPU version\nstart = time.time()\nresult_cpu = heavy_numpy_operation(data)\ncp.cuda.Stream.null.synchronize()\ncpu_time = time.time() - start\n\n# GPU version\nstart = time.time()\nresult_gpu = cp.asnumpy(heavy_cupy_operation(cp.asarray(data)))\ncp.cuda.Stream.null.synchronize()\ngpu_time = time.time() - start\n\nprint(f\"CPU: {cpu_time:.3f}s, GPU: {gpu_time:.3f}s, Speedup: {cpu_time\/gpu_time:.1f}x\")\n<\/code><\/pre>\n<h2>Mise en \u0153uvre pratique : Acc\u00e9l\u00e9rer Fipy avec Numba<\/h2>\n<h3>\u00c9tape&nbsp;1&nbsp;: Installer Numba<\/h3>\n<p>Numba fonctionne avec les GPU CPU et NVIDIA (CUDA). Pour la prise en charge du GPU, assurez-vous d&rsquo;avoir install\u00e9 CUDA Toolkit.<\/p>\n<pre><code class=\"language-bash\">pip install numba\n<\/code><\/pre>\n<h3>\u00c9tape&nbsp;2&nbsp;: Identifier les goulots d&rsquo;\u00e9tranglement<\/h3>\n<p>Utilisez les outils de profilage de Python pour trouver les fonctions les plus lentes :<\/p>\n<pre><code class=\"language-bash\">python -m cProfile -s cumulative your_solver.py\n<\/code><\/pre>\n<p>Recherchez des fonctions avec des boucles serr\u00e9es qui traitent les valeurs des cellules ou effectuent l&rsquo;arithm\u00e9tique sur les tableaux.<\/p>\n<h3>\u00c9tape&nbsp;3&nbsp;: Appliquer <code>@njit<\/code> D\u00e9corateur<\/h3>\n<p>Pour une fonction qui traite les valeurs des variables FIPY&nbsp;:<\/p>\n<pre><code class=\"language-python\">from numba import njit\nimport numpy as np\n\n@njit  # Compile to machine code\ndef compute_fluxes(phi_values, velocities, mesh_shape):\n    \"\"\"Compute convective fluxes for all cells.\"\"\"\n    fluxes = np.zeros(mesh_shape)\n    for i in range(mesh_shape[0]):\n        for j in range(mesh_shape[1]):\n            fluxes[i, j] = velocities[i, j] * phi_values[i, j]\n    return fluxes\n\n# Usage with FiPy\nphi_array = phi.value  # NumPy array from FiPy variable\nfluxes = compute_fluxes(phi_array, velocity_field, mesh.shape)\n<\/code><\/pre>\n<h3>\u00c9tape&nbsp;4&nbsp;: Parall\u00e8lement avec <code>parallel=True<\/code><\/h3>\n<p>Pour les op\u00e9rations bas\u00e9es sur la boucle qui peuvent s&rsquo;ex\u00e9cuter ind\u00e9pendamment&nbsp;:<\/p>\n<pre><code class=\"language-python\">from numba import njit, prange\n\n@njit(parallel=True)\ndef compute_source_terms(phi_values, source_coeff, result):\n    \"\"\"Compute source terms in parallel across all cells.\"\"\"\n    for i in prange(phi_values.shape[0]):\n        # Each iteration independent\n        result[i] = source_coeff[i] * phi_values[i]**2\n    return result\n<\/code><\/pre>\n<p><strong>Important&nbsp;:<\/strong> Utilisez uniquement <code>prange<\/code> lorsque les it\u00e9rations sont <strong>ind\u00e9pendantes<\/strong>. Les d\u00e9pendances de donn\u00e9es entra\u00eeneront des conditions de course et des r\u00e9sultats incorrects.<\/p>\n<h3>\u00c9tape 5 : Acc\u00e9l\u00e9ration du GPU avec Numba CUDA<\/h3>\n<p>Pour les noyaux CUDA personnalis\u00e9s&nbsp;:<\/p>\n<pre><code class=\"language-python\">from numba import cuda\nimport numpy as np\n\n@cuda.jit\ndef flux_kernel(phi, velocity, flux, nx, ny):\n    \"\"\"CUDA kernel computing fluxes in parallel.\"\"\"\n    i, j = cuda.grid(2)\n    if i &lt; nx and j &lt; ny:\n        idx = i * ny + j\n        flux[idx] = velocity[idx] * phi[idx]\n\n# Configure grid and block sizes\nthreads_per_block = (16, 16)\nblocks_per_grid = ((nx + threads_per_block[0] - 1) \/\/ threads_per_block[0],\n                  (ny + threads_per_block[1] - 1) \/\/ threads_per_block[1])\n\n# Launch kernel\nflux_kernel[blocks_per_grid, threads_per_block](phi_gpu, velocity_guy, flux_guy, nx, ny)\n<\/code><\/pre>\n<p>Les noyaux CUDA n\u00e9cessitent une gestion de la m\u00e9moire et une configuration de grille explicites, ce qui les rend plus complexes que les op\u00e9rations Array de Cupy.<\/p>\n<h2>Contraintes de m\u00e9moire et solutions de contournement<\/h2>\n<p>La m\u00e9moire GPU est souvent le facteur limitant pour les simulations FIPY de grande taille. Un maillage 3D avec des cellules 1000\u00b3 peut facilement d\u00e9passer 32 Go de m\u00e9moire GPU lors du stockage des champs de solution, des coefficients et des tableaux temporaires.<\/p>\n<h3>Reconna\u00eetre les limites de m\u00e9moire<\/h3>\n<p>Empreintes typiques de la m\u00e9moire GPU&nbsp;:<\/p>\n<ul>\n<li>Tableau unique <code>float64<\/code> de taille 1&nbsp;000&nbsp;\u00b3&nbsp;: ~&nbsp;8&nbsp;Go<\/li>\n<li>Plusieurs champs (vitesse, pression, scalaire) : 32+ Go<\/li>\n<li>Tableaux temporaires lors de l&rsquo;assemblage matriciel : 10 \u00e0 20&nbsp;Go suppl\u00e9mentaires<\/li>\n<\/ul>\n<p>Si votre simulation plante avec <code>cupy.cuda.memory.OutOfMemoryError<\/code>, vous avez atteint la limite.<\/p>\n<h3>Solution 1 : Pr\u00e9cision r\u00e9duite<\/h3>\n<p>Utilisation de <code>float32<\/code> au lieu de <code>float64<\/code> <strong>Mise en moiti\u00e9 de l&rsquo;utilisation de la m\u00e9moire<\/strong>&nbsp;:<\/p>\n<pre><code class=\"language-python\">import cupy as cp\n\n# Create arrays in single precision\nphi_f32 = cp.array(phi_values, dtype=cp.float32)\n<\/code><\/pre>\n<p>La plupart des simulations scientifiques tol\u00e8rent <code>float32<\/code> avec une perte de pr\u00e9cision acceptable, bien que certains PDE (en particulier des probl\u00e8mes s\u00e9v\u00e8res) puissent n\u00e9cessiter <code>float64<\/code> pour la stabilit\u00e9.<\/p>\n<h3>Solution de contournement&nbsp;2&nbsp;: d\u00e9composition du domaine avec multi-GPU<\/h3>\n<p>Pour les probl\u00e8mes tr\u00e8s importants, divisez le maillage sur plusieurs GPU&nbsp;:<\/p>\n<pre><code class=\"language-python\"># Pseudocode: split mesh into subdomains\nsubdomains = split_mesh(mesh, num_gpus=4)\n\nfor i, subdomain in enumerate(subdomains):\n    with cp.cuda.Device(i):\n        solve_subdomain(subdomain)  # Each GPU handles one piece\n<\/code><\/pre>\n<p>Cela n\u00e9cessite une manipulation minutieuse des cellules fant\u00f4mes et une communication de limite entre les sous-domaines. Des biblioth\u00e8ques comme <code>mpi4py<\/code> combin\u00e9es \u00e0 CUPY peuvent faciliter la coordination multi-GPU.<\/p>\n<h3>Solution&nbsp;3&nbsp;: \u00c9change de m\u00e9moire et de donn\u00e9es unifi\u00e9e<\/h3>\n<p>CUDA Unified Memory permet au GPU de d\u00e9passer la m\u00e9moire physique en t\u00e9l\u00e9chargeant automatiquement les donn\u00e9es entre le GPU et le CPU :<\/p>\n<pre><code class=\"language-python\">import cupy as cp\n\n# Allocate managed memory (Unified Memory)\nphi_managed = cp.cuda.managed_array(shape=(1000, 1000, 1000), dtype=cp.float64)\n\n# Use like regular CuPy array\nphi_managed[:] = initial_conditions\n\n# Kernel accesses will trigger page faults and data migration\nmy_kernel(phi_managed)\n<\/code><\/pre>\n<p><strong>Trade-off&nbsp;:<\/strong> La m\u00e9moire unifi\u00e9e simplifie la programmation, mais peut \u00eatre <strong>consid\u00e9rablement plus lente<\/strong> en raison de la surcharge de transfert PCIe lorsque les pages migrent.<\/p>\n<h3>Solution&nbsp;4&nbsp;: R\u00e9duisez la taille du lot \/ les pas de temps<\/h3>\n<p>Pour les simulations en fonction du temps, traitez des pas de temps plus petits ou des r\u00e9gions spatiales plus petites&nbsp;:<\/p>\n<pre><code class=\"language-python\"># Instead of solving entire domain at once\nfor t in range(0, total_steps, step_chunk):\n    solve_chunk(t, t + step_chunk)  # Smaller chunks use less memory\n<\/code><\/pre>\n<h3>Solution de contournement&nbsp;5&nbsp;: regroupement et r\u00e9utilisation de la m\u00e9moire<\/h3>\n<p>\u00c9vitez d&rsquo;allouer de nouveaux tableaux \u00e0 l&rsquo;int\u00e9rieur des boucles chaudes. Pr\u00e9-allouer et r\u00e9utiliser&nbsp;:<\/p>\n<pre><code class=\"language-python\"># Bad: allocates new array each iteration\nfor step in range(steps):\n    temp = cp.zeros_like(phi)  # Repeated allocation\n    temp[:] = compute(phi)\n\n# Good: reuse pre-allocated buffer\ntemp_buffer = cp.zeros_like(phi)\nfor step in range(steps):\n    temp_buffer[:] = compute(phi)\n<\/code><\/pre>\n<p>CUPY et NUMBA prennent tous deux en charge les pools de m\u00e9moire qui r\u00e9duisent les frais g\u00e9n\u00e9raux d&rsquo;allocation.<\/p>\n<h2>Erreurs et \u00e9cueils courants<\/h2>\n<p>L&rsquo;acc\u00e9l\u00e9ration du GPU peut se retourner contre lui si elle est mal appliqu\u00e9e. Voici les probl\u00e8mes les plus fr\u00e9quents que nous voyons dans les projets de calcul scientifique.<\/p>\n<h3>Erreur&nbsp;1&nbsp;: petites tailles de probl\u00e8mes<\/h3>\n<p><strong>Probl\u00e8me&nbsp;:<\/strong> Le surcharge de transfert de donn\u00e9es vers\/depuis le GPU et le lancement de noyaux dominent le temps r\u00e9el de calcul pour les petits tableaux (&lt;&nbsp;; 10&nbsp;\u2074&nbsp;\u00e9l\u00e9ments).<\/p>\n<p><strong>Solution&nbsp;:<\/strong> n&rsquo;utilisez que le GPU pour les probl\u00e8mes vraiment importants. Profilez les versions CPU et GPU avec des tailles de donn\u00e9es r\u00e9alistes avant de valider.<\/p>\n<h3>Erreur&nbsp;2&nbsp;: Transferts fr\u00e9quents de CPU-GPU<\/h3>\n<p><strong>Probl\u00e8me&nbsp;:<\/strong> Le d\u00e9placement des donn\u00e9es d&rsquo;un processeur \u00e0 l&rsquo;autre pour chaque petite op\u00e9ration tue les performances en raison de la latence PCIe (~&nbsp;10&nbsp;\u03bcs par transfert, ce qui s&rsquo;additionne).<\/p>\n<p><strong>Solution&nbsp;:<\/strong> Conservez les donn\u00e9es sur le GPU pour l&rsquo;ensemble du pipeline de calcul. Transf\u00e9rer les r\u00e9sultats uniquement lorsque cela est n\u00e9cessaire pour la sortie ou les E\/S.<\/p>\n<pre><code class=\"language-python\"># Bad: Transfer every iteration\nfor i in range(1000):\n    result_gpu = compute_gpu(input_gpu)\n    result_cpu = cp.asnumpy(result_gpu)  # Transfer each iteration\n    process(result_cpu)\n\n# Good: Minimize transfers\nfor i in range(1000):\n    result_gpu = compute_gpu(input_gpu)  # Stay on GPU\nfinal_result = cp.asnumpy(result_gpu)    # Single transfer at end\n<\/code><\/pre>\n<h3>Erreur&nbsp;3&nbsp;: op\u00e9rations li\u00e9es \u00e0 la m\u00e9moire<\/h3>\n<p><strong>Probl\u00e8me&nbsp;:<\/strong> Certaines op\u00e9rations sont limit\u00e9es par la bande passante de m\u00e9moire, et non par la puissance de calcul. L&rsquo;ajout de deux grands vecteurs, par exemple, ne peut pas \u00eatre acc\u00e9l\u00e9r\u00e9 par le GPU, car le goulot d&rsquo;\u00e9tranglement est en mouvement et non en calcul.<\/p>\n<p><strong>Solution&nbsp;:<\/strong> Profil pour d\u00e9terminer si votre code est li\u00e9 \u00e0 un calcul ou li\u00e9 \u00e0 la m\u00e9moire. Si la m\u00e9moire est li\u00e9e \u00e0 la m\u00e9moire, le GPU peut ne pas \u00eatre tr\u00e8s utile. Consid\u00e9rez plut\u00f4t les am\u00e9liorations algorithmiques (par exemple, la fusion, la pr\u00e9cision r\u00e9duite).<\/p>\n<h3>Erreur&nbsp;4&nbsp;: structures de donn\u00e9es inefficaces<\/h3>\n<p><strong>Probl\u00e8me&nbsp;:<\/strong> \u00e0 l&rsquo;aide de listes Python, de dictionnaires ou de mod\u00e8les orient\u00e9s objet avec NUMBA\/CUPY.<\/p>\n<p><strong>Solution&nbsp;:<\/strong> Respectez les tableaux NumPy\/Cupy et les types primitifs. Le mode <code>@njit<\/code> de Numba fonctionne mieux avec des tableaux num\u00e9riques, et non avec des objets Python.<\/p>\n<pre><code class=\"language-python\"># Bad: List of dicts\ndata = [{'value': i} for i in range(1000)]\n\n# Good: Structured array or separate arrays\nvalues = np.arange(1000)\n<\/code><\/pre>\n<h3>Erreur&nbsp;5&nbsp;: ignorer la synchronisation des fils<\/h3>\n<p><strong>Probl\u00e8me&nbsp;:<\/strong> Utiliser <code>parallel=True<\/code> avec des boucles qui ont des d\u00e9pendances entre les it\u00e9rations provoque des conditions de course et des r\u00e9sultats erron\u00e9s.<\/p>\n<p><strong>Solution&nbsp;:<\/strong> Assurez-vous que les it\u00e9rations de boucle sont <strong>ind\u00e9pendantes<\/strong> avant de parall\u00e9liser&nbsp;:<\/p>\n<pre><code class=\"language-python\"># Bad: Dependency on previous iteration\n@njit(parallel=True)\ndef cumulative_sum(arr):\n    total = 0\n    for i in prange(len(arr)):  # RACE CONDITION!\n        total += arr[i]        # Multiple threads modify same variable\n    return total\n\n# Good: Sequential or use reduction pattern\n@njit\ndef cumulative_sum(arr):\n    total = 0\n    for i in range(len(arr)):\n        total += arr[i]  # Sequential is correct\n    return total\n<\/code><\/pre>\n<h3>Erreur&nbsp;6&nbsp;: oubli de synchroniser le timing<\/h3>\n<p><strong>Probl\u00e8me&nbsp;:<\/strong> Les op\u00e9rations GPU sont asynchrones. Le code de synchronisation sans synchronisation donne des r\u00e9sultats trompeurs.<\/p>\n<p><strong>Solution&nbsp;:<\/strong> Appelez <code>cp.cuda.Stream.null.synchronize()<\/code> avant d&rsquo;arr\u00eater la minuterie&nbsp;:<\/p>\n<pre><code class=\"language-python\">import time\nimport cupy as cp\n\nstart = time.time()\nresult = heavy_computation_gpu(data)\ncp.cuda.Stream.null.synchronize()  # Wait for GPU to finish\nelapsed = time.time() - start\n<\/code><\/pre>\n<h3>Erreur&nbsp;7&nbsp;: ne pas v\u00e9rifier le mode de compilation<\/h3>\n<p><strong>Probl\u00e8me&nbsp;:<\/strong> Numba revient en \u00ab\u00a0mode objet\u00a0\u00bb (lent) si votre code utilise des fonctionnalit\u00e9s non prises en charge, mais vous n&rsquo;obtenez pas d&rsquo;erreur.<\/p>\n<p><strong>Solution&nbsp;:<\/strong> Utilisez <code>@njit<\/code> au lieu de <code>@jit<\/code> pour forcer le mode NoPython, ce qui d\u00e9clenchera une erreur en cas d&rsquo;\u00e9chec de la compilation&nbsp;:<\/p>\n<pre><code class=\"language-python\">from numba import njit\n\n@njit  # Will error if can't compile\ndef fast_func(arr):\n    return arr * 2\n\n# @jit would fall back to slow interpreter mode silently\n<\/code><\/pre>\n<p>V\u00e9rifiez l&rsquo;\u00e9tat de la compilation&nbsp;:<\/p>\n<pre><code class=\"language-python\">signature = fast_func.signatures  # Empty list means fallback to object mode\n<\/code><\/pre>\n<h2>Comparaison des performances&nbsp;: \u00e0 quelles acc\u00e9l\u00e9rations pouvez-vous vous attendre&nbsp;?<\/h2>\n<p>Les performances du monde r\u00e9el d\u00e9pendent fortement de votre probl\u00e8me sp\u00e9cifique, mais voici les r\u00e9f\u00e9rences de la litt\u00e9rature sur le calcul scientifique&nbsp;:<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"8\">\n<thead>\n<tr>\n<th>Type d&rsquo;op\u00e9ration<\/th>\n<th>Acc\u00e9l\u00e9ration typique du GPU (vs CPU Numpy)<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Grande multiplication matricielle (n &gt; 2000)<\/td>\n<td>50x \u2013 100x<\/td>\n<\/tr>\n<tr>\n<td>Arithm\u00e9tique \u00e9l\u00e9mentaire<\/td>\n<td>10x \u2013 50x<\/td>\n<\/tr>\n<tr>\n<td>FFT<\/td>\n<td>20x \u2013 80x<\/td>\n<\/tr>\n<tr>\n<td>Noyaux personnalis\u00e9s (bien optimis\u00e9s)<\/td>\n<td>100x \u2013 500x<\/td>\n<\/tr>\n<tr>\n<td>Petits tableaux (&lt; \u00e9l\u00e9ments 10\u2074)<\/td>\n<td>0,5&nbsp;x&nbsp;&#8211;&nbsp;2&nbsp;x (domine des frais g\u00e9n\u00e9raux)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Pour les simulations FIPY, qui impliquent des op\u00e9rations matricielles clairsem\u00e9es et des calculs de pochoir, les gains sont g\u00e9n\u00e9ralement plus modestes&nbsp;:<\/p>\n<ul>\n<li><strong>Pr\u00e9traitement\/post-traitement lourds&nbsp;:<\/strong>&nbsp;10&nbsp;x&nbsp;\u2013&nbsp;30&nbsp;x<\/li>\n<li><strong>Calculs personnalis\u00e9s de terme de flux\/source (numba)&nbsp;:<\/strong>&nbsp;5&nbsp;x&nbsp;\u2013&nbsp;20&nbsp;x<\/li>\n<li><strong>Solveur complet avec interne Fipy&nbsp;:<\/strong>&nbsp;1&nbsp;x&nbsp;\u2013&nbsp;3&nbsp;x&nbsp;(Fipy lui-m\u00eame n&rsquo;est pas un GPU-natif)<\/li>\n<\/ul>\n<p><strong>Informations cl\u00e9s&nbsp;:<\/strong> Les victoires les plus importantes proviennent de l&rsquo;acc\u00e9l\u00e9ration de votre propre code personnalis\u00e9, et non de FIPY lui-m\u00eame. Si les solveurs int\u00e9gr\u00e9s de Fipy dominent le temps d&rsquo;ex\u00e9cution, vous devrez peut-\u00eatre passer \u00e0 un solveur GPU-natif (par exemple, envisager des biblioth\u00e8ques sp\u00e9cialis\u00e9es telles que PYFR ou des impl\u00e9mentations CUDA personnalis\u00e9es).<\/p>\n<h2>Cadre de d\u00e9cision&nbsp;: quand choisir l&rsquo;acc\u00e9l\u00e9ration du GPU<\/h2>\n<p>Utilisez cet organigramme pour d\u00e9cider si l&rsquo;acc\u00e9l\u00e9ration GPU vaut l&rsquo;effort pour votre projet FIPY&nbsp;:<\/p>\n<pre><code>START: Is your simulation slow (&gt; hours per run)?\n  \u2514\u2500 No \u2192 Don't optimize prematurely. Profile first.\n  \u2514\u2500 Yes \u2192 What is the bottleneck?\n      \u251c\u2500 FiPy built-in solvers (matrix assembly\/solve)\n      \u2502   \u2514\u2500 GPU may not help much. Consider:\n      \u2502       \u2022 Different linear solver (e.g., PETSc with GPU support)\n      \u2502       \u2022 Coarser mesh\n      \u2502       \u2022 Alternative PDE solver library\n      \u2502\n      \u251c\u2500 Custom Python loops (pre\/post-processing, custom terms)\n      \u2502   \u2514\u2500 Use Numba @njit(parallel=True)\n      \u2502       \u2022 Small to medium loops: CPU Numba\n      \u2502       \u2022 Very large loops: Numba CUDA or CuPy\n      \u2502\n      \u251c\u2500 Large NumPy array operations\n      \u2502   \u2514\u2500 Use CuPy drop-in replacement\n      \u2502       \u2022 Ensure arrays &gt; 10\u2076 elements\n      \u2502       \u2022 Minimize CPU-GPU transfers\n      \u2502\n      \u2514\u2500 Mixed workload\n          \u2514\u2500 Profile both CuPy and Numba approaches\n              \u2022 Try CuPy first (easier)\n              \u2022 Add Numba for remaining hotspots\n              \u2022 Consider hybrid: CuPy arrays + Numba kernels\n<\/code><\/pre>\n<p><strong>Quand ignorer enti\u00e8rement le GPU&nbsp;:<\/strong><\/p>\n<ul>\n<li>La taille du probl\u00e8me est trop petite pour surmonter les frais g\u00e9n\u00e9raux<\/li>\n<li>Le code est d\u00e9j\u00e0 optimis\u00e9 et le goulot d&rsquo;\u00e9tranglement est I\/O ou bande passante de m\u00e9moire<\/li>\n<li>Vous manquez de mat\u00e9riel GPU ou d&rsquo;expertise en configuration CUDA\/ROCM<\/li>\n<li>Le calendrier du projet ne justifie pas l&rsquo;effort d&rsquo;optimisation<\/li>\n<\/ul>\n<h2>Int\u00e9gration de l&rsquo;acc\u00e9l\u00e9ration du GPU dans votre flux de travail Fipy<\/h2>\n<p>Une approche pragmatique qui donne des r\u00e9sultats sans refactorisation majeure :<\/p>\n<h3>Phase 1 : Profiler et identifier les points chauds<\/h3>\n<p>Ex\u00e9cutez votre simulation avec un profileur pour trouver o\u00f9 le temps est pass\u00e9&nbsp;:<\/p>\n<pre><code class=\"language-bash\">python -m cProfile -o profile.out your_solver.py\nsnakeviz profile.out  # Visualize with SnakeViz\n<\/code><\/pre>\n<p>Concentrez-vous sur les fonctions qui :<\/p>\n<ul>\n<li>sont appel\u00e9s plusieurs fois (boucles serr\u00e9es)<\/li>\n<li>Traiter de grandes tableaux<\/li>\n<li>Contient de l&rsquo;arithm\u00e9tique pure avec une surcharge minimale de python<\/li>\n<\/ul>\n<h3>Phase 2 : Acc\u00e9l\u00e9rer le code non-Fipy en premier<\/h3>\n<p>Si votre workflow comprend :<\/p>\n<ul>\n<li>Chargement et pr\u00e9traitement des donn\u00e9es<\/li>\n<li>Post-traitement et visualisation<\/li>\n<li>Conditions de source personnalis\u00e9es ou conditions aux limites<\/li>\n<li>Balayages de param\u00e8tres ou boucles d&rsquo;optimisation<\/li>\n<\/ul>\n<p>Appliquez d&rsquo;abord CUPY ou NUMBA \u00e0 ces sections. Ils sont plus faciles \u00e0 modifier et peuvent fournir des gains imm\u00e9diats sans toucher les internes de Fipy.<\/p>\n<h3>Phase 3 : Envisager des solveurs alternatifs<\/h3>\n<p>Si le solveur de Fipy est le goulot d&rsquo;\u00e9tranglement et que vous avez \u00e9puis\u00e9 les optimisations du processeur (mesures parcimonieuses, meilleurs solveurs lin\u00e9aires, pr\u00e9conditionneurs), vous devrez peut-\u00eatre \u00e9valuer si un solveur natif GPU est appropri\u00e9 pour votre probl\u00e8me. Il s&rsquo;agit d&rsquo;un changement architectural important et ne doit \u00eatre pris en compte que lorsque toutes les autres optimisations ont \u00e9t\u00e9 \u00e9puis\u00e9es.<\/p>\n<h2>Guides connexes<\/h2>\n<ul>\n<li><strong><a href=\"https:\/\/matforge.org\/what-is-fipy-and-when-should-you-use-it\/\">Qu&rsquo;est-ce que FIPY et quand devriez-vous l&rsquo;utiliser&nbsp;?<\/a><\/strong> &#8211; Comprendre les capacit\u00e9s de Fipy et si c&rsquo;est le bon outil pour Vos probl\u00e8mes d&rsquo;AED.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/introduction-to-materials-modeling-for-beginners\/\">Introduction \u00e0 la mod\u00e9lisation des mat\u00e9riaux pour les d\u00e9butants<\/a><\/strong> &#8211; Apprenez les principes fondamentaux de la simulation des mat\u00e9riaux qui sous-tendent les applications FIPY.<\/li>\n<li><strong>Profilage et optimisation des performances des solveurs PDE Python<\/strong> (\u00e0 venir) \u2013 Techniques avanc\u00e9es pour identifier et r\u00e9soudre les goulots d&rsquo;\u00e9tranglement des performances.<\/li>\n<\/ul>\n<h2>Conclusion et prochaines \u00e9tapes<\/h2>\n<p>L&rsquo;acc\u00e9l\u00e9ration des GPU \u00e0 l&rsquo;aide de CUPY et de Numba peut transformer les simulations FIPY d&rsquo;affaires d&rsquo;une heure ou d&rsquo;une minute, <strong>pourvu que vous l&rsquo;appliquiez aux bons probl\u00e8mes<\/strong>. Les principaux points \u00e0 retenir :<\/p>\n<ol>\n<li><strong>Profil avant d&rsquo;optimiser.<\/strong> Ne devinez pas o\u00f9 se trouve le goulot d&rsquo;\u00e9tranglement&nbsp;; Mesurez-le.<\/li>\n<li><strong>Le cupy est le plus simple pour le code \u00e0 forte densit\u00e9 de matrice.<\/strong> Remplacez <code>numpy<\/code> par <code>cupy<\/code> et le benchmark.<\/li>\n<li><strong>Numba excelle \u00e0 acc\u00e9l\u00e9rer les boucles.<\/strong> Utilisez <code>@njit(parallel=True)<\/code> pour des it\u00e9rations ind\u00e9pendantes.<\/li>\n<li><strong>GPU n&rsquo;est pas magique.<\/strong> Les petits probl\u00e8mes, les op\u00e9rations li\u00e9es \u00e0 la m\u00e9moire et le code Python complexe peuvent ne pas b\u00e9n\u00e9ficier.<\/li>\n<li><strong>Mindez la m\u00e9moire.<\/strong> Les grands maillages 3D peuvent d\u00e9passer la m\u00e9moire GPU ; Utilisez la r\u00e9duction de pr\u00e9cision, la d\u00e9composition du domaine ou la m\u00e9moire unifi\u00e9e si n\u00e9cessaire.<\/li>\n<li><strong>\u00c9vitez les pi\u00e8ges courants.<\/strong> Minimisez les transferts, pr\u00e9-allouez les tampons, v\u00e9rifiez le mode nodython et ne parall\u00e9liez jamais les boucles d\u00e9pendantes.<\/li>\n<\/ol>\n<h3>Plan d&rsquo;action recommand\u00e9<\/h3>\n<ol>\n<li><strong>Installez CUPY<\/strong> sur une machine avec un GPU NVIDIA et ex\u00e9cutez un benchmark simple sur vos op\u00e9rations de la plus grande gamme.<\/li>\n<li><strong>Profilez votre solveur FIPY actuel<\/strong> pour identifier les 2-3 meilleurs points d&rsquo;acc\u00e8s.<\/li>\n<li><strong>R\u00e9crivez un point d&rsquo;acc\u00e8s<\/strong> \u00e0 l&rsquo;aide de CUPY (op\u00e9rations de tableau) ou NUMBA (boucles) et mesurez la vitesse.<\/li>\n<li><strong>It\u00e9rer&nbsp;:<\/strong> si acc\u00e9l\u00e9rer &gt;&nbsp;; 2x, appliquez la m\u00eame approche \u00e0 d&rsquo;autres points chauds. Si acc\u00e9l\u00e9rer &lt; 1,5x, reconsid\u00e9rez si le GPU en vaut la peine pour ce composant.<\/li>\n<li><strong>Documentez votre processus<\/strong> pour de futurs projets : les techniques d&rsquo;acc\u00e9l\u00e9ration des GPU sont r\u00e9utilisables dans de nombreux codes de simulation.<\/li>\n<\/ol>\n<p>L&rsquo;acc\u00e9l\u00e9ration GPU est un outil puissant dans la bo\u00eete \u00e0 outils de calcul scientifique, mais comme tout outil, il doit \u00eatre appliqu\u00e9 judicieusement. Avec les strat\u00e9gies d\u00e9crites dans ce guide, vous \u00eates \u00e9quip\u00e9 pour prendre des d\u00e9cisions \u00e9clair\u00e9es et acc\u00e9l\u00e9rer efficacement vos simulations FIPY.<\/p>\n","protected":false,"raw":"<p>Les simulations FIPY peuvent atteindre <strong>10x \u00e0 100x acc\u00e9l\u00e9rations<\/strong> en d\u00e9pla\u00e7ant des op\u00e9rations de calcul sur le GPU \u00e0 l'aide de CUPY (remplacement NumPy) ou NUMBA (compilation JIT). CUPY excelle dans les op\u00e9rations de tableau et n\u00e9cessite des modifications de code minimales, tandis que Numba acc\u00e9l\u00e8re les boucles Python et les fonctions personnalis\u00e9es. Cependant, l'acc\u00e9l\u00e9ration du GPU n'est pas toujours b\u00e9n\u00e9fique : de petits probl\u00e8mes, des op\u00e9rations li\u00e9es \u00e0 la m\u00e9moire et des structures de donn\u00e9es complexes peuvent annuler les gains. Ce guide couvre la mise en \u0153uvre pratique, les comparaisons de performances, les contraintes de m\u00e9moire et le moment de choisir chaque approche pour vos simulations PDE.<\/p>\n<h2>Introduction&nbsp;: Pourquoi l'acc\u00e9l\u00e9ration du GPU est-elle importante pour FIPY&nbsp;?<\/h2>\n<p>FIPY est un puissant solveur d'\u00e9quations aux d\u00e9riv\u00e9es partielles (PDE) bas\u00e9 sur Python qui utilise la m\u00e9thode du volume fini (FVM). Alors que la conception orient\u00e9e objet de Fipy le rend accessible, les simulations 3D \u00e0 grande \u00e9chelle avec des maillages fins peuvent devenir co\u00fbteuses en termes de calcul, avec des temps d'ex\u00e9cution allant de quelques heures \u00e0 quelques jours.<\/p>\n<p>La m\u00e9thode du volume fini est naturellement adapt\u00e9e \u00e0 l'acc\u00e9l\u00e9ration du GPU, car les calculs de flux \u00e0 travers les interfaces de cellules peuvent \u00eatre calcul\u00e9s ind\u00e9pendamment et en parall\u00e8le. En mappant ces calculs centr\u00e9s sur les cellules \u00e0 des milliers de c\u0153urs de GPU, les chercheurs peuvent obtenir des am\u00e9liorations spectaculaires des performances. Cependant, la r\u00e9alisation de ces gains n\u00e9cessite une attention particuli\u00e8re aux d\u00e9tails de la mise en \u0153uvre et une compr\u00e9hension du moment o\u00f9 l'acc\u00e9l\u00e9ration du GPU aide r\u00e9ellement.<\/p>\n<p>Ce guide fournit un cadre pratique pour int\u00e9grer l'acc\u00e9l\u00e9ration du GPU dans vos flux de travail Fipy \u00e0 l'aide de Cupy et Numba, les deux principales biblioth\u00e8ques de calcul GPU Python.<\/p>\n<h2>Comprendre CUPY et NUMBA&nbsp;: diff\u00e9rences cl\u00e9s<\/h2>\n<p>Avant de plonger dans la mise en \u0153uvre, il est essentiel de comprendre en quoi CUPY et NUMBA diff\u00e8rent dans leur approche de l'acc\u00e9l\u00e9ration des GPU.<\/p>\n<h3>Cupy : Remplacement de NumPy Drop-in<\/h3>\n<p>Cupy est une biblioth\u00e8que open-source qui impl\u00e9mente un sous-ensemble d'API Nvidia et Scipy sur les GPU Nvidia \u00e0 l'aide de CUDA et sur les GPU AMD utilisant ROCM. La proposition de valeur fondamentale est la simplicit\u00e9&nbsp;: <strong>Vous pouvez souvent acc\u00e9l\u00e9rer le code existant en rempla\u00e7ant simplement <code>import numpy as np<\/code> par <code>import cupy as cp<\/code><\/strong>.<\/p>\n<h3>Comment fonctionne Cupie&nbsp;:<\/h3>\n<ul>\n<li>Les baies CUPY (<code>cupy.ndarray<\/code>) sont stock\u00e9es dans la m\u00e9moire du GPU, tandis que les baies de NumPy vivent dans la RAM du syst\u00e8me<\/li>\n<li>La plupart des op\u00e9rations Numpy ont des \u00e9quivalents CUPY qui s'ex\u00e9cutent sur le GPU<\/li>\n<li>Le transfert de donn\u00e9es entre CPU et GPU est explicite via <code>cp.asnumpy()<\/code> (GPU\u2192CPU) et <code>cp.asarray()<\/code> (CPU\u2192GPU)<\/li>\n<\/ul>\n<h3>Caract\u00e9ristiques de performance :<\/h3>\n<ul>\n<li>Les op\u00e9rations de la baie peuvent \u00eatre <strong>100x+ plus rapides<\/strong> que NumPy pour les grands ensembles de donn\u00e9es en raison du parall\u00e9lisme GPU<\/li>\n<li>Les frais g\u00e9n\u00e9raux des transferts de donn\u00e9es entre le processeur et le GPU peuvent dominer s'ils ne sont pas minimis\u00e9s<\/li>\n<li>Id\u00e9al pour les op\u00e9rations en masse : multiplication matricielle, FFT, op\u00e9rations \u00e9l\u00e9mentaires, r\u00e9ductions<\/li>\n<\/ul>\n<h3>Numba : compilation juste \u00e0 temps<\/h3>\n<p>NUMBA est un compilateur JIT open source qui traduit les fonctions Python en code machine optimis\u00e9 lors de l'ex\u00e9cution \u00e0 l'aide de LLVM. Contrairement \u00e0 Cupy, qui se concentre sur les op\u00e9rations de la baie, Numba acc\u00e9l\u00e8re les <strong>boucles de Python, les fonctions arithm\u00e9tiques et num\u00e9riques<\/strong> en les compilant vers un code machine efficace qui peut s'ex\u00e9cuter \u00e0 la fois sur le processeur et sur le GPU.<\/p>\n<h3>Comment fonctionne Numba&nbsp;:<\/h3>\n<ul>\n<li>Utilisez le d\u00e9corateur <code>@jit<\/code> pour marquer les fonctions pour la compilation<\/li>\n<li><code>@njit<\/code> (pas de mode Python) garantit des performances maximales en \u00e9vitant les frais g\u00e9n\u00e9raux de l'interpr\u00e9teur Python<\/li>\n<li><code>@cuda.jit<\/code> Pour \u00e9crire des noyaux CUDA personnalis\u00e9s qui s'ex\u00e9cutent directement sur le GPU<\/li>\n<li><code>parallel=True<\/code> Active la parall\u00e9lisation automatique des boucles sur les CPU multi-c\u0153urs<\/li>\n<\/ul>\n<h3>Caract\u00e9ristiques de performance :<\/h3>\n<ul>\n<li>Les boucles qui sont lentes en Python pur peuvent approcher des vitesses <strong>C ou Fortran<\/strong><\/li>\n<li>La compilation JIT ajoute une surcharge de d\u00e9marrage (g\u00e9n\u00e9ralement quelques secondes en minutes)<\/li>\n<li>Fonctionne avec le flux de contr\u00f4le Python, les op\u00e9rations NumPy et les types de donn\u00e9es de base<\/li>\n<li>Le mode GPU (<code>@cuda.jit<\/code>) n\u00e9cessite l'\u00e9criture de noyaux CUDA explicites, qui a une courbe d'apprentissage plus raide<\/li>\n<\/ul>\n<h2>CUPY VS NUMBA&nbsp;: Lequel choisir&nbsp;?<\/h2>\n<p>Le choix entre CUPY et NUMBA d\u00e9pend de votre charge de travail sp\u00e9cifique, de votre structure de code et de votre volont\u00e9 de refactoriser.<\/p>\n<h3>Utilisez CUPY lorsque&nbsp;:<\/h3>\n<ul>\n<li>Vous avez <strong>code de NumPy-Heavy existant<\/strong> et souhaitez des modifications minimes<\/li>\n<li>Votre goulot d'\u00e9tranglement est <strong>op\u00e9rations de r\u00e9seau<\/strong> (matrix math\u00e9matiques, fonctions \u00e9l\u00e9mentaires, agr\u00e9gations)<\/li>\n<li>Vous travaillez avec des <strong>grands tableaux contigus<\/strong> qui s'int\u00e8grent confortablement dans la m\u00e9moire GPU<\/li>\n<li>Vous pr\u00e9f\u00e9rez une approche de remplacement <strong>drop-in<\/strong> \u00e0 l'apprentissage de nouveaux mod\u00e8les de programmation<\/li>\n<\/ul>\n<p><strong>Sc\u00e9nario d'exemple&nbsp;:<\/strong> Vous r\u00e9solvez une \u00e9quation de diffusion avec un grand maillage 3D et le co\u00fbt dominant est dans les op\u00e9rations matricielles et les math\u00e9matiques vectorielles&nbsp;: le passage \u00e0 CUPY peut entra\u00eener des acc\u00e9l\u00e9rations imm\u00e9diates avec seulement quelques lignes de code modifi\u00e9es.<\/p>\n<h3>Utilisez NUMBA lorsque&nbsp;:<\/h3>\n<ul>\n<li>Votre goulot d'\u00e9tranglement est <strong>boucles Python<\/strong> qui it\u00e8rent sur des tableaux ou des cellules<\/li>\n<li>Vous avez <strong>fonctions num\u00e9riques personnalis\u00e9es<\/strong> qui ne correspondent pas proprement aux op\u00e9rations NumPy<\/li>\n<li>Vous avez besoin d'un <strong>contr\u00f4le \u00e0 grain fin<\/strong> sur le parall\u00e9lisme et les mod\u00e8les d'acc\u00e8s \u00e0 la m\u00e9moire<\/li>\n<li>Vous impl\u00e9mentez <strong>Nouveaux algorithmes<\/strong> \u00e0 partir de z\u00e9ro et pouvez concevoir des GPU d\u00e8s le d\u00e9part<\/li>\n<\/ul>\n<p><strong>Exemple de sc\u00e9nario&nbsp;:<\/strong> Vous impl\u00e9mentez un limiteur de flux ou un terme source qui implique une logique conditionnelle complexe et des mises \u00e0 jour it\u00e9ratives par cellule\u2014numba <code>@njit<\/code> avec <code>prange<\/code> peut parall\u00e9liser efficacement.<\/p>\n<h3>Pouvez-vous utiliser les deux&nbsp;?<\/h3>\n<p>Oui. CUPY et NUMBA peuvent \u00eatre combin\u00e9s :<\/p>\n<ul>\n<li>Utilisez CUPY pour les op\u00e9rations et les transferts de tableaux<\/li>\n<li>Utilisez Numba pour \u00e9crire des noyaux CUDA personnalis\u00e9s qui fonctionnent sur des tableaux CUPY<\/li>\n<li>Le support CUDA de Numba peut lancer des noyaux qui traitent directement les donn\u00e9es CUPY<\/li>\n<\/ul>\n<p>Pour les utilisateurs de FIPY, une approche pratique consiste d'abord \u00e0 profiler, puis \u00e0 appliquer CUPY aux sections lourdes en r\u00e9seau et \u00e0 Numba aux sections lourdes de boucles, selon les besoins.<\/p>\n<h2>Mise en \u0153uvre pratique : Acc\u00e9l\u00e9rer Fipy avec Cupy<\/h2>\n<h3>\u00c9tape&nbsp;1&nbsp;: Installez CUPY<\/h3>\n<p>CUPY n\u00e9cessite CUDA Toolkit (NVIDIA) ou ROCM (AMD). Installez avec :<\/p>\n<pre><code class=\"language-bash\"># For CUDA 11.x\npip install cupy-cuda11x\n\n# For CUDA 12.x\npip install cupy-cuda12x\n\n# Or from source for custom builds\n<\/code><\/pre>\n<p>V\u00e9rifier l'installation&nbsp;:<\/p>\n<pre><code class=\"language-python\">import cupy as cp\nprint(cp.cuda.runtime.getDeviceCount())  # Should print number of GPUs\n<\/code><\/pre>\n<h3>\u00c9tape&nbsp;2&nbsp;: Remplacez les importations NumPy<\/h3>\n<p>La forme d'int\u00e9gration la plus simple consiste \u00e0 remplacer NumPy par Cupy dans tout votre code de solveur :<\/p>\n<pre><code class=\"language-python\"># Before\nimport numpy as np\n\n# After\nimport cupy as cp\n<\/code><\/pre>\n<p><strong>Important&nbsp;:<\/strong> \u00e0 lui seul, ce changement n'acc\u00e9l\u00e9rera pas comme par magie Fipy car Fipy lui-m\u00eame utilise Numpy en interne. Pour gagner en performances, vous devez vous assurer que les <strong>grands tableaux<\/strong> (coordonn\u00e9es maill\u00e9es, vecteurs de solution, matrices de coefficients) sont d\u00e9plac\u00e9s vers le GPU et que les <strong>noyaux de calcul<\/strong> fonctionnent sur des baies de GPU.<\/p>\n<h3>\u00c9tape&nbsp;3&nbsp;: Transf\u00e9rez les donn\u00e9es vers le GPU<\/h3>\n<p>Les variables FIPY sont g\u00e9n\u00e9ralement <code>numpy.ndarray<\/code>. Vous devez les d\u00e9placer explicitement vers la m\u00e9moire GPU&nbsp;:<\/p>\n<pre><code class=\"language-python\"># Example: FiPy solution variable\nphi = CellVariable(name=\"phi\", mesh=mesh)  # Uses NumPy internally\n\n# To use CuPy, you'd need to override the array storage:\nphi._array = cp.asarray(phi._array)  # Move to GPU\n<\/code><\/pre>\n<p><strong>Attention&nbsp;:<\/strong> Il s'agit d'une technique avanc\u00e9e et peut briser les hypoth\u00e8ses internes de Fipy. Une approche plus pratique consiste \u00e0 utiliser CUPY pour les <strong>pr\u00e9traitement<\/strong>, les <strong>post-traitement<\/strong> et les <strong>op\u00e9rations autonomes<\/strong> en dehors de la boucle de solveur de base de FIPY, ou pour impl\u00e9menter des termes personnalis\u00e9s qui utilisent des tableaux CUPY.<\/p>\n<h3>\u00c9tape&nbsp;4&nbsp;: Impl\u00e9mentez les termes GPU personnalis\u00e9s<\/h3>\n<p>FIPY autorise les termes personnalis\u00e9s via les objets <code>Term<\/code>. Vous pouvez cr\u00e9er un terme qui utilise Cupy pour son calcul :<\/p>\n<pre><code class=\"language-python\">import cupy as cp\nfrom fipy import Term, CellVariable, Mesh\n\nclass CuPyConvectionTerm(Term):\n    \"\"\"Convection term implemented with CuPy for GPU acceleration.\"\"\"\n    \n    def __init__(self, velocity):\n        self.velocity = velocity  # Should be a CuPy array\n    \n    def _buildMatrix(self, var, solver, boundaryConditions=(), dt=1.0):\n        # This method would construct the discretized matrix using CuPy\n        # Implementation requires deep FiPy knowledge\n        pass\n    \n    def _compute(var, velocity):\n        # Use CuPy for the actual computation\n        # var should be a CuPy array\n        flux = velocity * var\n        return flux\n<\/code><\/pre>\n<p>Cette approche est avanc\u00e9e et n\u00e9cessite de comprendre les internes de discr\u00e9tisation de Fipy.<\/p>\n<h3>\u00c9tape&nbsp;5&nbsp;: Profiler et valider<\/h3>\n<p>Toujours profiler pour confirmer l'acc\u00e9l\u00e9ration&nbsp;:<\/p>\n<pre><code class=\"language-python\">import time\nimport cupy as cp\n\n# CPU version\nstart = time.time()\nresult_cpu = heavy_numpy_operation(data)\ncp.cuda.Stream.null.synchronize()\ncpu_time = time.time() - start\n\n# GPU version\nstart = time.time()\nresult_gpu = cp.asnumpy(heavy_cupy_operation(cp.asarray(data)))\ncp.cuda.Stream.null.synchronize()\ngpu_time = time.time() - start\n\nprint(f\"CPU: {cpu_time:.3f}s, GPU: {gpu_time:.3f}s, Speedup: {cpu_time\/gpu_time:.1f}x\")\n<\/code><\/pre>\n<h2>Mise en \u0153uvre pratique : Acc\u00e9l\u00e9rer Fipy avec Numba<\/h2>\n<h3>\u00c9tape&nbsp;1&nbsp;: Installer Numba<\/h3>\n<p>Numba fonctionne avec les GPU CPU et NVIDIA (CUDA). Pour la prise en charge du GPU, assurez-vous d'avoir install\u00e9 CUDA Toolkit.<\/p>\n<pre><code class=\"language-bash\">pip install numba\n<\/code><\/pre>\n<h3>\u00c9tape&nbsp;2&nbsp;: Identifier les goulots d'\u00e9tranglement<\/h3>\n<p>Utilisez les outils de profilage de Python pour trouver les fonctions les plus lentes :<\/p>\n<pre><code class=\"language-bash\">python -m cProfile -s cumulative your_solver.py\n<\/code><\/pre>\n<p>Recherchez des fonctions avec des boucles serr\u00e9es qui traitent les valeurs des cellules ou effectuent l'arithm\u00e9tique sur les tableaux.<\/p>\n<h3>\u00c9tape&nbsp;3&nbsp;: Appliquer <code>@njit<\/code> D\u00e9corateur<\/h3>\n<p>Pour une fonction qui traite les valeurs des variables FIPY&nbsp;:<\/p>\n<pre><code class=\"language-python\">from numba import njit\nimport numpy as np\n\n@njit  # Compile to machine code\ndef compute_fluxes(phi_values, velocities, mesh_shape):\n    \"\"\"Compute convective fluxes for all cells.\"\"\"\n    fluxes = np.zeros(mesh_shape)\n    for i in range(mesh_shape[0]):\n        for j in range(mesh_shape[1]):\n            fluxes[i, j] = velocities[i, j] * phi_values[i, j]\n    return fluxes\n\n# Usage with FiPy\nphi_array = phi.value  # NumPy array from FiPy variable\nfluxes = compute_fluxes(phi_array, velocity_field, mesh.shape)\n<\/code><\/pre>\n<h3>\u00c9tape&nbsp;4&nbsp;: Parall\u00e8lement avec <code>parallel=True<\/code><\/h3>\n<p>Pour les op\u00e9rations bas\u00e9es sur la boucle qui peuvent s'ex\u00e9cuter ind\u00e9pendamment&nbsp;:<\/p>\n<pre><code class=\"language-python\">from numba import njit, prange\n\n@njit(parallel=True)\ndef compute_source_terms(phi_values, source_coeff, result):\n    \"\"\"Compute source terms in parallel across all cells.\"\"\"\n    for i in prange(phi_values.shape[0]):\n        # Each iteration independent\n        result[i] = source_coeff[i] * phi_values[i]**2\n    return result\n<\/code><\/pre>\n<p><strong>Important&nbsp;:<\/strong> Utilisez uniquement <code>prange<\/code> lorsque les it\u00e9rations sont <strong>ind\u00e9pendantes<\/strong>. Les d\u00e9pendances de donn\u00e9es entra\u00eeneront des conditions de course et des r\u00e9sultats incorrects.<\/p>\n<h3>\u00c9tape 5 : Acc\u00e9l\u00e9ration du GPU avec Numba CUDA<\/h3>\n<p>Pour les noyaux CUDA personnalis\u00e9s&nbsp;:<\/p>\n<pre><code class=\"language-python\">from numba import cuda\nimport numpy as np\n\n@cuda.jit\ndef flux_kernel(phi, velocity, flux, nx, ny):\n    \"\"\"CUDA kernel computing fluxes in parallel.\"\"\"\n    i, j = cuda.grid(2)\n    if i &lt; nx and j &lt; ny:\n        idx = i * ny + j\n        flux[idx] = velocity[idx] * phi[idx]\n\n# Configure grid and block sizes\nthreads_per_block = (16, 16)\nblocks_per_grid = ((nx + threads_per_block[0] - 1) \/\/ threads_per_block[0],\n                  (ny + threads_per_block[1] - 1) \/\/ threads_per_block[1])\n\n# Launch kernel\nflux_kernel[blocks_per_grid, threads_per_block](phi_gpu, velocity_guy, flux_guy, nx, ny)\n<\/code><\/pre>\n<p>Les noyaux CUDA n\u00e9cessitent une gestion de la m\u00e9moire et une configuration de grille explicites, ce qui les rend plus complexes que les op\u00e9rations Array de Cupy.<\/p>\n<h2>Contraintes de m\u00e9moire et solutions de contournement<\/h2>\n<p>La m\u00e9moire GPU est souvent le facteur limitant pour les simulations FIPY de grande taille. Un maillage 3D avec des cellules 1000\u00b3 peut facilement d\u00e9passer 32 Go de m\u00e9moire GPU lors du stockage des champs de solution, des coefficients et des tableaux temporaires.<\/p>\n<h3>Reconna\u00eetre les limites de m\u00e9moire<\/h3>\n<p>Empreintes typiques de la m\u00e9moire GPU&nbsp;:<\/p>\n<ul>\n<li>Tableau unique <code>float64<\/code> de taille 1&nbsp;000&nbsp;\u00b3&nbsp;: ~&nbsp;8&nbsp;Go<\/li>\n<li>Plusieurs champs (vitesse, pression, scalaire) : 32+ Go<\/li>\n<li>Tableaux temporaires lors de l'assemblage matriciel : 10 \u00e0 20&nbsp;Go suppl\u00e9mentaires<\/li>\n<\/ul>\n<p>Si votre simulation plante avec <code>cupy.cuda.memory.OutOfMemoryError<\/code>, vous avez atteint la limite.<\/p>\n<h3>Solution 1 : Pr\u00e9cision r\u00e9duite<\/h3>\n<p>Utilisation de <code>float32<\/code> au lieu de <code>float64<\/code> <strong>Mise en moiti\u00e9 de l'utilisation de la m\u00e9moire<\/strong>&nbsp;:<\/p>\n<pre><code class=\"language-python\">import cupy as cp\n\n# Create arrays in single precision\nphi_f32 = cp.array(phi_values, dtype=cp.float32)\n<\/code><\/pre>\n<p>La plupart des simulations scientifiques tol\u00e8rent <code>float32<\/code> avec une perte de pr\u00e9cision acceptable, bien que certains PDE (en particulier des probl\u00e8mes s\u00e9v\u00e8res) puissent n\u00e9cessiter <code>float64<\/code> pour la stabilit\u00e9.<\/p>\n<h3>Solution de contournement&nbsp;2&nbsp;: d\u00e9composition du domaine avec multi-GPU<\/h3>\n<p>Pour les probl\u00e8mes tr\u00e8s importants, divisez le maillage sur plusieurs GPU&nbsp;:<\/p>\n<pre><code class=\"language-python\"># Pseudocode: split mesh into subdomains\nsubdomains = split_mesh(mesh, num_gpus=4)\n\nfor i, subdomain in enumerate(subdomains):\n    with cp.cuda.Device(i):\n        solve_subdomain(subdomain)  # Each GPU handles one piece\n<\/code><\/pre>\n<p>Cela n\u00e9cessite une manipulation minutieuse des cellules fant\u00f4mes et une communication de limite entre les sous-domaines. Des biblioth\u00e8ques comme <code>mpi4py<\/code> combin\u00e9es \u00e0 CUPY peuvent faciliter la coordination multi-GPU.<\/p>\n<h3>Solution&nbsp;3&nbsp;: \u00c9change de m\u00e9moire et de donn\u00e9es unifi\u00e9e<\/h3>\n<p>CUDA Unified Memory permet au GPU de d\u00e9passer la m\u00e9moire physique en t\u00e9l\u00e9chargeant automatiquement les donn\u00e9es entre le GPU et le CPU :<\/p>\n<pre><code class=\"language-python\">import cupy as cp\n\n# Allocate managed memory (Unified Memory)\nphi_managed = cp.cuda.managed_array(shape=(1000, 1000, 1000), dtype=cp.float64)\n\n# Use like regular CuPy array\nphi_managed[:] = initial_conditions\n\n# Kernel accesses will trigger page faults and data migration\nmy_kernel(phi_managed)\n<\/code><\/pre>\n<p><strong>Trade-off&nbsp;:<\/strong> La m\u00e9moire unifi\u00e9e simplifie la programmation, mais peut \u00eatre <strong>consid\u00e9rablement plus lente<\/strong> en raison de la surcharge de transfert PCIe lorsque les pages migrent.<\/p>\n<h3>Solution&nbsp;4&nbsp;: R\u00e9duisez la taille du lot \/ les pas de temps<\/h3>\n<p>Pour les simulations en fonction du temps, traitez des pas de temps plus petits ou des r\u00e9gions spatiales plus petites&nbsp;:<\/p>\n<pre><code class=\"language-python\"># Instead of solving entire domain at once\nfor t in range(0, total_steps, step_chunk):\n    solve_chunk(t, t + step_chunk)  # Smaller chunks use less memory\n<\/code><\/pre>\n<h3>Solution de contournement&nbsp;5&nbsp;: regroupement et r\u00e9utilisation de la m\u00e9moire<\/h3>\n<p>\u00c9vitez d'allouer de nouveaux tableaux \u00e0 l'int\u00e9rieur des boucles chaudes. Pr\u00e9-allouer et r\u00e9utiliser&nbsp;:<\/p>\n<pre><code class=\"language-python\"># Bad: allocates new array each iteration\nfor step in range(steps):\n    temp = cp.zeros_like(phi)  # Repeated allocation\n    temp[:] = compute(phi)\n\n# Good: reuse pre-allocated buffer\ntemp_buffer = cp.zeros_like(phi)\nfor step in range(steps):\n    temp_buffer[:] = compute(phi)\n<\/code><\/pre>\n<p>CUPY et NUMBA prennent tous deux en charge les pools de m\u00e9moire qui r\u00e9duisent les frais g\u00e9n\u00e9raux d'allocation.<\/p>\n<h2>Erreurs et \u00e9cueils courants<\/h2>\n<p>L'acc\u00e9l\u00e9ration du GPU peut se retourner contre lui si elle est mal appliqu\u00e9e. Voici les probl\u00e8mes les plus fr\u00e9quents que nous voyons dans les projets de calcul scientifique.<\/p>\n<h3>Erreur&nbsp;1&nbsp;: petites tailles de probl\u00e8mes<\/h3>\n<p><strong>Probl\u00e8me&nbsp;:<\/strong> Le surcharge de transfert de donn\u00e9es vers\/depuis le GPU et le lancement de noyaux dominent le temps r\u00e9el de calcul pour les petits tableaux (&lt;&nbsp;; 10&nbsp;\u2074&nbsp;\u00e9l\u00e9ments).<\/p>\n<p><strong>Solution&nbsp;:<\/strong> n'utilisez que le GPU pour les probl\u00e8mes vraiment importants. Profilez les versions CPU et GPU avec des tailles de donn\u00e9es r\u00e9alistes avant de valider.<\/p>\n<h3>Erreur&nbsp;2&nbsp;: Transferts fr\u00e9quents de CPU-GPU<\/h3>\n<p><strong>Probl\u00e8me&nbsp;:<\/strong> Le d\u00e9placement des donn\u00e9es d'un processeur \u00e0 l'autre pour chaque petite op\u00e9ration tue les performances en raison de la latence PCIe (~&nbsp;10&nbsp;\u03bcs par transfert, ce qui s'additionne).<\/p>\n<p><strong>Solution&nbsp;:<\/strong> Conservez les donn\u00e9es sur le GPU pour l'ensemble du pipeline de calcul. Transf\u00e9rer les r\u00e9sultats uniquement lorsque cela est n\u00e9cessaire pour la sortie ou les E\/S.<\/p>\n<pre><code class=\"language-python\"># Bad: Transfer every iteration\nfor i in range(1000):\n    result_gpu = compute_gpu(input_gpu)\n    result_cpu = cp.asnumpy(result_gpu)  # Transfer each iteration\n    process(result_cpu)\n\n# Good: Minimize transfers\nfor i in range(1000):\n    result_gpu = compute_gpu(input_gpu)  # Stay on GPU\nfinal_result = cp.asnumpy(result_gpu)    # Single transfer at end\n<\/code><\/pre>\n<h3>Erreur&nbsp;3&nbsp;: op\u00e9rations li\u00e9es \u00e0 la m\u00e9moire<\/h3>\n<p><strong>Probl\u00e8me&nbsp;:<\/strong> Certaines op\u00e9rations sont limit\u00e9es par la bande passante de m\u00e9moire, et non par la puissance de calcul. L'ajout de deux grands vecteurs, par exemple, ne peut pas \u00eatre acc\u00e9l\u00e9r\u00e9 par le GPU, car le goulot d'\u00e9tranglement est en mouvement et non en calcul.<\/p>\n<p><strong>Solution&nbsp;:<\/strong> Profil pour d\u00e9terminer si votre code est li\u00e9 \u00e0 un calcul ou li\u00e9 \u00e0 la m\u00e9moire. Si la m\u00e9moire est li\u00e9e \u00e0 la m\u00e9moire, le GPU peut ne pas \u00eatre tr\u00e8s utile. Consid\u00e9rez plut\u00f4t les am\u00e9liorations algorithmiques (par exemple, la fusion, la pr\u00e9cision r\u00e9duite).<\/p>\n<h3>Erreur&nbsp;4&nbsp;: structures de donn\u00e9es inefficaces<\/h3>\n<p><strong>Probl\u00e8me&nbsp;:<\/strong> \u00e0 l'aide de listes Python, de dictionnaires ou de mod\u00e8les orient\u00e9s objet avec NUMBA\/CUPY.<\/p>\n<p><strong>Solution&nbsp;:<\/strong> Respectez les tableaux NumPy\/Cupy et les types primitifs. Le mode <code>@njit<\/code> de Numba fonctionne mieux avec des tableaux num\u00e9riques, et non avec des objets Python.<\/p>\n<pre><code class=\"language-python\"># Bad: List of dicts\ndata = [{'value': i} for i in range(1000)]\n\n# Good: Structured array or separate arrays\nvalues = np.arange(1000)\n<\/code><\/pre>\n<h3>Erreur&nbsp;5&nbsp;: ignorer la synchronisation des fils<\/h3>\n<p><strong>Probl\u00e8me&nbsp;:<\/strong> Utiliser <code>parallel=True<\/code> avec des boucles qui ont des d\u00e9pendances entre les it\u00e9rations provoque des conditions de course et des r\u00e9sultats erron\u00e9s.<\/p>\n<p><strong>Solution&nbsp;:<\/strong> Assurez-vous que les it\u00e9rations de boucle sont <strong>ind\u00e9pendantes<\/strong> avant de parall\u00e9liser&nbsp;:<\/p>\n<pre><code class=\"language-python\"># Bad: Dependency on previous iteration\n@njit(parallel=True)\ndef cumulative_sum(arr):\n    total = 0\n    for i in prange(len(arr)):  # RACE CONDITION!\n        total += arr[i]        # Multiple threads modify same variable\n    return total\n\n# Good: Sequential or use reduction pattern\n@njit\ndef cumulative_sum(arr):\n    total = 0\n    for i in range(len(arr)):\n        total += arr[i]  # Sequential is correct\n    return total\n<\/code><\/pre>\n<h3>Erreur&nbsp;6&nbsp;: oubli de synchroniser le timing<\/h3>\n<p><strong>Probl\u00e8me&nbsp;:<\/strong> Les op\u00e9rations GPU sont asynchrones. Le code de synchronisation sans synchronisation donne des r\u00e9sultats trompeurs.<\/p>\n<p><strong>Solution&nbsp;:<\/strong> Appelez <code>cp.cuda.Stream.null.synchronize()<\/code> avant d'arr\u00eater la minuterie&nbsp;:<\/p>\n<pre><code class=\"language-python\">import time\nimport cupy as cp\n\nstart = time.time()\nresult = heavy_computation_gpu(data)\ncp.cuda.Stream.null.synchronize()  # Wait for GPU to finish\nelapsed = time.time() - start\n<\/code><\/pre>\n<h3>Erreur&nbsp;7&nbsp;: ne pas v\u00e9rifier le mode de compilation<\/h3>\n<p><strong>Probl\u00e8me&nbsp;:<\/strong> Numba revient en \"mode objet\" (lent) si votre code utilise des fonctionnalit\u00e9s non prises en charge, mais vous n'obtenez pas d'erreur.<\/p>\n<p><strong>Solution&nbsp;:<\/strong> Utilisez <code>@njit<\/code> au lieu de <code>@jit<\/code> pour forcer le mode NoPython, ce qui d\u00e9clenchera une erreur en cas d'\u00e9chec de la compilation&nbsp;:<\/p>\n<pre><code class=\"language-python\">from numba import njit\n\n@njit  # Will error if can't compile\ndef fast_func(arr):\n    return arr * 2\n\n# @jit would fall back to slow interpreter mode silently\n<\/code><\/pre>\n<p>V\u00e9rifiez l'\u00e9tat de la compilation&nbsp;:<\/p>\n<pre><code class=\"language-python\">signature = fast_func.signatures  # Empty list means fallback to object mode\n<\/code><\/pre>\n<h2>Comparaison des performances&nbsp;: \u00e0 quelles acc\u00e9l\u00e9rations pouvez-vous vous attendre&nbsp;?<\/h2>\n<p>Les performances du monde r\u00e9el d\u00e9pendent fortement de votre probl\u00e8me sp\u00e9cifique, mais voici les r\u00e9f\u00e9rences de la litt\u00e9rature sur le calcul scientifique&nbsp;:<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"8\">\n<thead>\n<tr>\n<th>Type d'op\u00e9ration<\/th>\n<th>Acc\u00e9l\u00e9ration typique du GPU (vs CPU Numpy)<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Grande multiplication matricielle (n &gt; 2000)<\/td>\n<td>50x \u2013 100x<\/td>\n<\/tr>\n<tr>\n<td>Arithm\u00e9tique \u00e9l\u00e9mentaire<\/td>\n<td>10x \u2013 50x<\/td>\n<\/tr>\n<tr>\n<td>FFT<\/td>\n<td>20x \u2013 80x<\/td>\n<\/tr>\n<tr>\n<td>Noyaux personnalis\u00e9s (bien optimis\u00e9s)<\/td>\n<td>100x \u2013 500x<\/td>\n<\/tr>\n<tr>\n<td>Petits tableaux (&lt; \u00e9l\u00e9ments 10\u2074)<\/td>\n<td>0,5&nbsp;x&nbsp;-&nbsp;2&nbsp;x (domine des frais g\u00e9n\u00e9raux)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Pour les simulations FIPY, qui impliquent des op\u00e9rations matricielles clairsem\u00e9es et des calculs de pochoir, les gains sont g\u00e9n\u00e9ralement plus modestes&nbsp;:<\/p>\n<ul>\n<li><strong>Pr\u00e9traitement\/post-traitement lourds&nbsp;:<\/strong>&nbsp;10&nbsp;x&nbsp;\u2013&nbsp;30&nbsp;x<\/li>\n<li><strong>Calculs personnalis\u00e9s de terme de flux\/source (numba)&nbsp;:<\/strong>&nbsp;5&nbsp;x&nbsp;\u2013&nbsp;20&nbsp;x<\/li>\n<li><strong>Solveur complet avec interne Fipy&nbsp;:<\/strong>&nbsp;1&nbsp;x&nbsp;\u2013&nbsp;3&nbsp;x&nbsp;(Fipy lui-m\u00eame n'est pas un GPU-natif)<\/li>\n<\/ul>\n<p><strong>Informations cl\u00e9s&nbsp;:<\/strong> Les victoires les plus importantes proviennent de l'acc\u00e9l\u00e9ration de votre propre code personnalis\u00e9, et non de FIPY lui-m\u00eame. Si les solveurs int\u00e9gr\u00e9s de Fipy dominent le temps d'ex\u00e9cution, vous devrez peut-\u00eatre passer \u00e0 un solveur GPU-natif (par exemple, envisager des biblioth\u00e8ques sp\u00e9cialis\u00e9es telles que PYFR ou des impl\u00e9mentations CUDA personnalis\u00e9es).<\/p>\n<h2>Cadre de d\u00e9cision&nbsp;: quand choisir l'acc\u00e9l\u00e9ration du GPU<\/h2>\n<p>Utilisez cet organigramme pour d\u00e9cider si l'acc\u00e9l\u00e9ration GPU vaut l'effort pour votre projet FIPY&nbsp;:<\/p>\n<pre><code>START: Is your simulation slow (&gt; hours per run)?\n  \u2514\u2500 No \u2192 Don't optimize prematurely. Profile first.\n  \u2514\u2500 Yes \u2192 What is the bottleneck?\n      \u251c\u2500 FiPy built-in solvers (matrix assembly\/solve)\n      \u2502   \u2514\u2500 GPU may not help much. Consider:\n      \u2502       \u2022 Different linear solver (e.g., PETSc with GPU support)\n      \u2502       \u2022 Coarser mesh\n      \u2502       \u2022 Alternative PDE solver library\n      \u2502\n      \u251c\u2500 Custom Python loops (pre\/post-processing, custom terms)\n      \u2502   \u2514\u2500 Use Numba @njit(parallel=True)\n      \u2502       \u2022 Small to medium loops: CPU Numba\n      \u2502       \u2022 Very large loops: Numba CUDA or CuPy\n      \u2502\n      \u251c\u2500 Large NumPy array operations\n      \u2502   \u2514\u2500 Use CuPy drop-in replacement\n      \u2502       \u2022 Ensure arrays &gt; 10\u2076 elements\n      \u2502       \u2022 Minimize CPU-GPU transfers\n      \u2502\n      \u2514\u2500 Mixed workload\n          \u2514\u2500 Profile both CuPy and Numba approaches\n              \u2022 Try CuPy first (easier)\n              \u2022 Add Numba for remaining hotspots\n              \u2022 Consider hybrid: CuPy arrays + Numba kernels\n<\/code><\/pre>\n<p><strong>Quand ignorer enti\u00e8rement le GPU&nbsp;:<\/strong><\/p>\n<ul>\n<li>La taille du probl\u00e8me est trop petite pour surmonter les frais g\u00e9n\u00e9raux<\/li>\n<li>Le code est d\u00e9j\u00e0 optimis\u00e9 et le goulot d'\u00e9tranglement est I\/O ou bande passante de m\u00e9moire<\/li>\n<li>Vous manquez de mat\u00e9riel GPU ou d'expertise en configuration CUDA\/ROCM<\/li>\n<li>Le calendrier du projet ne justifie pas l'effort d'optimisation<\/li>\n<\/ul>\n<h2>Int\u00e9gration de l'acc\u00e9l\u00e9ration du GPU dans votre flux de travail Fipy<\/h2>\n<p>Une approche pragmatique qui donne des r\u00e9sultats sans refactorisation majeure :<\/p>\n<h3>Phase 1 : Profiler et identifier les points chauds<\/h3>\n<p>Ex\u00e9cutez votre simulation avec un profileur pour trouver o\u00f9 le temps est pass\u00e9&nbsp;:<\/p>\n<pre><code class=\"language-bash\">python -m cProfile -o profile.out your_solver.py\nsnakeviz profile.out  # Visualize with SnakeViz\n<\/code><\/pre>\n<p>Concentrez-vous sur les fonctions qui :<\/p>\n<ul>\n<li>sont appel\u00e9s plusieurs fois (boucles serr\u00e9es)<\/li>\n<li>Traiter de grandes tableaux<\/li>\n<li>Contient de l'arithm\u00e9tique pure avec une surcharge minimale de python<\/li>\n<\/ul>\n<h3>Phase 2 : Acc\u00e9l\u00e9rer le code non-Fipy en premier<\/h3>\n<p>Si votre workflow comprend :<\/p>\n<ul>\n<li>Chargement et pr\u00e9traitement des donn\u00e9es<\/li>\n<li>Post-traitement et visualisation<\/li>\n<li>Conditions de source personnalis\u00e9es ou conditions aux limites<\/li>\n<li>Balayages de param\u00e8tres ou boucles d'optimisation<\/li>\n<\/ul>\n<p>Appliquez d'abord CUPY ou NUMBA \u00e0 ces sections. Ils sont plus faciles \u00e0 modifier et peuvent fournir des gains imm\u00e9diats sans toucher les internes de Fipy.<\/p>\n<h3>Phase 3 : Envisager des solveurs alternatifs<\/h3>\n<p>Si le solveur de Fipy est le goulot d'\u00e9tranglement et que vous avez \u00e9puis\u00e9 les optimisations du processeur (mesures parcimonieuses, meilleurs solveurs lin\u00e9aires, pr\u00e9conditionneurs), vous devrez peut-\u00eatre \u00e9valuer si un solveur natif GPU est appropri\u00e9 pour votre probl\u00e8me. Il s'agit d'un changement architectural important et ne doit \u00eatre pris en compte que lorsque toutes les autres optimisations ont \u00e9t\u00e9 \u00e9puis\u00e9es.<\/p>\n<h2>Guides connexes<\/h2>\n<ul>\n<li><strong><a href=\"https:\/\/matforge.org\/what-is-fipy-and-when-should-you-use-it\/\">Qu'est-ce que FIPY et quand devriez-vous l'utiliser&nbsp;?<\/a><\/strong> - Comprendre les capacit\u00e9s de Fipy et si c'est le bon outil pour Vos probl\u00e8mes d'AED.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/introduction-to-materials-modeling-for-beginners\/\">Introduction \u00e0 la mod\u00e9lisation des mat\u00e9riaux pour les d\u00e9butants<\/a><\/strong> - Apprenez les principes fondamentaux de la simulation des mat\u00e9riaux qui sous-tendent les applications FIPY.<\/li>\n<li><strong>Profilage et optimisation des performances des solveurs PDE Python<\/strong> (\u00e0 venir) \u2013 Techniques avanc\u00e9es pour identifier et r\u00e9soudre les goulots d'\u00e9tranglement des performances.<\/li>\n<\/ul>\n<h2>Conclusion et prochaines \u00e9tapes<\/h2>\n<p>L'acc\u00e9l\u00e9ration des GPU \u00e0 l'aide de CUPY et de Numba peut transformer les simulations FIPY d'affaires d'une heure ou d'une minute, <strong>pourvu que vous l'appliquiez aux bons probl\u00e8mes<\/strong>. Les principaux points \u00e0 retenir :<\/p>\n<ol>\n<li><strong>Profil avant d'optimiser.<\/strong> Ne devinez pas o\u00f9 se trouve le goulot d'\u00e9tranglement&nbsp;; Mesurez-le.<\/li>\n<li><strong>Le cupy est le plus simple pour le code \u00e0 forte densit\u00e9 de matrice.<\/strong> Remplacez <code>numpy<\/code> par <code>cupy<\/code> et le benchmark.<\/li>\n<li><strong>Numba excelle \u00e0 acc\u00e9l\u00e9rer les boucles.<\/strong> Utilisez <code>@njit(parallel=True)<\/code> pour des it\u00e9rations ind\u00e9pendantes.<\/li>\n<li><strong>GPU n'est pas magique.<\/strong> Les petits probl\u00e8mes, les op\u00e9rations li\u00e9es \u00e0 la m\u00e9moire et le code Python complexe peuvent ne pas b\u00e9n\u00e9ficier.<\/li>\n<li><strong>Mindez la m\u00e9moire.<\/strong> Les grands maillages 3D peuvent d\u00e9passer la m\u00e9moire GPU ; Utilisez la r\u00e9duction de pr\u00e9cision, la d\u00e9composition du domaine ou la m\u00e9moire unifi\u00e9e si n\u00e9cessaire.<\/li>\n<li><strong>\u00c9vitez les pi\u00e8ges courants.<\/strong> Minimisez les transferts, pr\u00e9-allouez les tampons, v\u00e9rifiez le mode nodython et ne parall\u00e9liez jamais les boucles d\u00e9pendantes.<\/li>\n<\/ol>\n<h3>Plan d'action recommand\u00e9<\/h3>\n<ol>\n<li><strong>Installez CUPY<\/strong> sur une machine avec un GPU NVIDIA et ex\u00e9cutez un benchmark simple sur vos op\u00e9rations de la plus grande gamme.<\/li>\n<li><strong>Profilez votre solveur FIPY actuel<\/strong> pour identifier les 2-3 meilleurs points d'acc\u00e8s.<\/li>\n<li><strong>R\u00e9crivez un point d'acc\u00e8s<\/strong> \u00e0 l'aide de CUPY (op\u00e9rations de tableau) ou NUMBA (boucles) et mesurez la vitesse.<\/li>\n<li><strong>It\u00e9rer&nbsp;:<\/strong> si acc\u00e9l\u00e9rer &gt;&nbsp;; 2x, appliquez la m\u00eame approche \u00e0 d'autres points chauds. Si acc\u00e9l\u00e9rer &lt; 1,5x, reconsid\u00e9rez si le GPU en vaut la peine pour ce composant.<\/li>\n<li><strong>Documentez votre processus<\/strong> pour de futurs projets : les techniques d'acc\u00e9l\u00e9ration des GPU sont r\u00e9utilisables dans de nombreux codes de simulation.<\/li>\n<\/ol>\n<p>L'acc\u00e9l\u00e9ration GPU est un outil puissant dans la bo\u00eete \u00e0 outils de calcul scientifique, mais comme tout outil, il doit \u00eatre appliqu\u00e9 judicieusement. Avec les strat\u00e9gies d\u00e9crites dans ce guide, vous \u00eates \u00e9quip\u00e9 pour prendre des d\u00e9cisions \u00e9clair\u00e9es et acc\u00e9l\u00e9rer efficacement vos simulations FIPY.<\/p>\n"},"excerpt":{"rendered":"<p><span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\"> 13<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span>Les simulations FIPY peuvent atteindre 10x \u00e0 100x acc\u00e9l\u00e9rations en d\u00e9pla\u00e7ant des op\u00e9rations de calcul sur le GPU \u00e0 l&rsquo;aide de CUPY (remplacement NumPy) ou NUMBA (compilation JIT). CUPY excelle dans les op\u00e9rations de tableau et n\u00e9cessite des modifications de code minimales, tandis que Numba acc\u00e9l\u00e8re les boucles Python et les fonctions personnalis\u00e9es. Cependant, l&rsquo;acc\u00e9l\u00e9ration [&hellip;]<\/p>\n","protected":false,"raw":""},"author":6,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_locale":"fr_FR","_original_post":"https:\/\/matforge.org\/?p=180","iawp_total_views":0,"footnotes":""},"categories":[2],"tags":[],"class_list":["post-1240","post","type-post","status-publish","format-standard","hentry","category-fipy-documentation-examples-development","fr-FR"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Acc\u00e9l\u00e9ration GPU pour les simulations FIPY : Guide d&#039;int\u00e9gration CUPY et NUMBA - matforge.org<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/matforge.org\/fr\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Acc\u00e9l\u00e9ration GPU pour les simulations FIPY : Guide d&#039;int\u00e9gration CUPY et NUMBA - matforge.org\" \/>\n<meta property=\"og:description\" content=\"Reading Time:  13 minutesLes simulations FIPY peuvent atteindre 10x \u00e0 100x acc\u00e9l\u00e9rations en d\u00e9pla\u00e7ant des op\u00e9rations de calcul sur le GPU \u00e0 l&rsquo;aide de CUPY (remplacement NumPy) ou NUMBA (compilation JIT). CUPY excelle dans les op\u00e9rations de tableau et n\u00e9cessite des modifications de code minimales, tandis que Numba acc\u00e9l\u00e8re les boucles Python et les fonctions personnalis\u00e9es. Cependant, l&rsquo;acc\u00e9l\u00e9ration [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/matforge.org\/fr\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\/\" \/>\n<meta property=\"og:site_name\" content=\"matforge.org\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-21T14:28:35+00:00\" \/>\n<meta name=\"author\" content=\"steven\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u00c9crit par\" \/>\n\t<meta name=\"twitter:data1\" content=\"steven\" \/>\n\t<meta name=\"twitter:label2\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data2\" content=\"22 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/matforge.org\\\/fr\\\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/fr\\\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\\\/\"},\"author\":{\"name\":\"steven\",\"@id\":\"https:\\\/\\\/matforge.org\\\/#\\\/schema\\\/person\\\/8f690fb596d657b12994b83caa788f03\"},\"headline\":\"Acc\u00e9l\u00e9ration GPU pour les simulations FIPY : Guide d&rsquo;int\u00e9gration CUPY et NUMBA\",\"datePublished\":\"2026-08-21T14:28:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/fr\\\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\\\/\"},\"wordCount\":3522,\"commentCount\":0,\"articleSection\":[\"FIPY : documentation, exemples &amp; D\u00e9veloppement\"],\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/matforge.org\\\/fr\\\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/matforge.org\\\/fr\\\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\\\/\",\"url\":\"https:\\\/\\\/matforge.org\\\/fr\\\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\\\/\",\"name\":\"Acc\u00e9l\u00e9ration GPU pour les simulations FIPY : Guide d'int\u00e9gration CUPY et NUMBA - matforge.org\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/#website\"},\"datePublished\":\"2026-08-21T14:28:35+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/#\\\/schema\\\/person\\\/8f690fb596d657b12994b83caa788f03\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/fr\\\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\\\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/matforge.org\\\/fr\\\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/matforge.org\\\/fr\\\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/matforge.org\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Acc\u00e9l\u00e9ration GPU pour les simulations FIPY : Guide d&#8217;int\u00e9gration CUPY et NUMBA\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/matforge.org\\\/#website\",\"url\":\"https:\\\/\\\/matforge.org\\\/\",\"name\":\"matforge.org\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/matforge.org\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/matforge.org\\\/#\\\/schema\\\/person\\\/8f690fb596d657b12994b83caa788f03\",\"name\":\"steven\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d46cfcd83a298f27e8d66bfa035514fefca7652f26bd3ef7402f82b68a41ec0f?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d46cfcd83a298f27e8d66bfa035514fefca7652f26bd3ef7402f82b68a41ec0f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d46cfcd83a298f27e8d66bfa035514fefca7652f26bd3ef7402f82b68a41ec0f?s=96&d=mm&r=g\",\"caption\":\"steven\"},\"url\":\"https:\\\/\\\/matforge.org\\\/author\\\/steven\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Acc\u00e9l\u00e9ration GPU pour les simulations FIPY : Guide d'int\u00e9gration CUPY et NUMBA - matforge.org","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/matforge.org\/fr\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\/","og_locale":"fr_FR","og_type":"article","og_title":"Acc\u00e9l\u00e9ration GPU pour les simulations FIPY : Guide d'int\u00e9gration CUPY et NUMBA - matforge.org","og_description":"Reading Time:  13 minutesLes simulations FIPY peuvent atteindre 10x \u00e0 100x acc\u00e9l\u00e9rations en d\u00e9pla\u00e7ant des op\u00e9rations de calcul sur le GPU \u00e0 l&rsquo;aide de CUPY (remplacement NumPy) ou NUMBA (compilation JIT). CUPY excelle dans les op\u00e9rations de tableau et n\u00e9cessite des modifications de code minimales, tandis que Numba acc\u00e9l\u00e8re les boucles Python et les fonctions personnalis\u00e9es. Cependant, l&rsquo;acc\u00e9l\u00e9ration [&hellip;]","og_url":"https:\/\/matforge.org\/fr\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\/","og_site_name":"matforge.org","article_published_time":"2026-08-21T14:28:35+00:00","author":"steven","twitter_card":"summary_large_image","twitter_misc":{"\u00c9crit par":"steven","Dur\u00e9e de lecture estim\u00e9e":"22 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/matforge.org\/fr\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\/#article","isPartOf":{"@id":"https:\/\/matforge.org\/fr\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\/"},"author":{"name":"steven","@id":"https:\/\/matforge.org\/#\/schema\/person\/8f690fb596d657b12994b83caa788f03"},"headline":"Acc\u00e9l\u00e9ration GPU pour les simulations FIPY : Guide d&rsquo;int\u00e9gration CUPY et NUMBA","datePublished":"2026-08-21T14:28:35+00:00","mainEntityOfPage":{"@id":"https:\/\/matforge.org\/fr\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\/"},"wordCount":3522,"commentCount":0,"articleSection":["FIPY : documentation, exemples &amp; D\u00e9veloppement"],"inLanguage":"fr-FR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/matforge.org\/fr\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/matforge.org\/fr\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\/","url":"https:\/\/matforge.org\/fr\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\/","name":"Acc\u00e9l\u00e9ration GPU pour les simulations FIPY : Guide d'int\u00e9gration CUPY et NUMBA - matforge.org","isPartOf":{"@id":"https:\/\/matforge.org\/#website"},"datePublished":"2026-08-21T14:28:35+00:00","author":{"@id":"https:\/\/matforge.org\/#\/schema\/person\/8f690fb596d657b12994b83caa788f03"},"breadcrumb":{"@id":"https:\/\/matforge.org\/fr\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/matforge.org\/fr\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/matforge.org\/fr\/gpu-acceleration-for-fipy-simulations-cupy-and-numba-integration-guide\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/matforge.org\/"},{"@type":"ListItem","position":2,"name":"Acc\u00e9l\u00e9ration GPU pour les simulations FIPY : Guide d&#8217;int\u00e9gration CUPY et NUMBA"}]},{"@type":"WebSite","@id":"https:\/\/matforge.org\/#website","url":"https:\/\/matforge.org\/","name":"matforge.org","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/matforge.org\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"fr-FR"},{"@type":"Person","@id":"https:\/\/matforge.org\/#\/schema\/person\/8f690fb596d657b12994b83caa788f03","name":"steven","image":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/secure.gravatar.com\/avatar\/d46cfcd83a298f27e8d66bfa035514fefca7652f26bd3ef7402f82b68a41ec0f?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/d46cfcd83a298f27e8d66bfa035514fefca7652f26bd3ef7402f82b68a41ec0f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d46cfcd83a298f27e8d66bfa035514fefca7652f26bd3ef7402f82b68a41ec0f?s=96&d=mm&r=g","caption":"steven"},"url":"https:\/\/matforge.org\/author\/steven\/"}]}},"_links":{"self":[{"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/posts\/1240","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/comments?post=1240"}],"version-history":[{"count":1,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/posts\/1240\/revisions"}],"predecessor-version":[{"id":1350,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/posts\/1240\/revisions\/1350"}],"wp:attachment":[{"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/media?parent=1240"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/categories?post=1240"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/tags?post=1240"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}