La sonde CUDA reconnait aussi les DLL Windows

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Ralph Mayola 2026-08-23 18:10:23 +02:00
parent 734bba31da
commit 5f83e4c6a3
2 changed files with 71 additions and 7 deletions

View File

@ -1,4 +1,5 @@
"""Choisit le moteur de transcription d'après le matériel.""" """Choisit le moteur de transcription d'après le matériel."""
import ctypes
import platform import platform
import sys import sys
@ -16,13 +17,41 @@ def detecter_moteur():
return nom_moteur_pour(sys.platform, platform.machine(), _cuda_disponible()) return nom_moteur_pour(sys.platform, platform.machine(), _cuda_disponible())
def _cuda_disponible(): # Le nom de la bibliothèque partagée CUDA diffère radicalement par plateforme ET
try: # par version : `libcudart.so` (parfois suffixé `.12`, `.11.0`...) sous Linux/macOS,
import ctypes # mais `cudart64_12.dll`, `cudart64_110.dll`... sous Windows, où le numéro de version
ctypes.CDLL("libcudart.so") # est ENCODÉ DANS LE NOM du fichier. `ctypes.util.find_library` ne résout pas ces DLL
return True # versionnées de façon fiable — il cherche un nom canonique qui n'existe pas pour
except Exception: # CUDA sous Windows. On essaie donc une liste explicite de noms candidats, du plus
return False # récent au plus ancien, et on s'arrête au premier qui charge.
_NOMS_CUDART_WINDOWS = [
"cudart64_12.dll",
"cudart64_110.dll",
"cudart64_101.dll",
"cudart64_100.dll",
]
_NOMS_CUDART_UNIX = [
"libcudart.so",
"libcudart.so.12",
"libcudart.so.11.0",
]
def _cuda_disponible(plateforme=None, charger=None):
"""Sonde la présence du runtime CUDA en tentant de charger sa bibliothèque
partagée. `plateforme` et `charger` sont injectables : ça rend la sonde
testable avec une doublure, sans dépendre d'une vraie machine CUDA ni d'un
vrai Windows. Ne lève jamais dans le doute, on rend False."""
plateforme = plateforme if plateforme is not None else sys.platform
charger = charger if charger is not None else ctypes.CDLL
noms = _NOMS_CUDART_WINDOWS if plateforme.startswith("win") else _NOMS_CUDART_UNIX
for nom in noms:
try:
charger(nom)
return True
except Exception:
continue
return False
def choisir_transcripteur(nom, modele, langue, amorce): def choisir_transcripteur(nom, modele, langue, amorce):

View File

@ -29,3 +29,38 @@ def test_un_moteur_inconnu_est_refuse_clairement():
with pytest.raises(NotImplementedError) as e: with pytest.raises(NotImplementedError) as e:
choisir_transcripteur(nom="vosk", modele="x", langue="fr", amorce="") choisir_transcripteur(nom="vosk", modele="x", langue="fr", amorce="")
assert "vosk" in str(e.value) assert "vosk" in str(e.value)
# --- Sonde CUDA : le nom de la bibliothèque partagée diffère par OS et par version.
# Ces tests injectent une doublure de chargeur pour rester exécutables depuis
# n'importe quelle machine, sans jamais dépendre d'une vraie installation CUDA.
from moteur import _cuda_disponible
def test_cuda_reconnue_sur_windows_via_dll_versionnee():
def charger(nom):
if nom == "cudart64_12.dll":
return object()
raise OSError(f"introuvable : {nom}")
assert _cuda_disponible(plateforme="win32", charger=charger) is True
def test_cuda_absente_sur_windows_si_aucune_dll_ne_charge():
def charger(nom):
raise OSError(f"introuvable : {nom}")
assert _cuda_disponible(plateforme="win32", charger=charger) is False
def test_cuda_reconnue_sur_linux_darwin_via_so():
def charger(nom):
if nom == "libcudart.so":
return object()
raise OSError(f"introuvable : {nom}")
assert _cuda_disponible(plateforme="linux", charger=charger) is True
assert _cuda_disponible(plateforme="darwin", charger=charger) is True
def test_cuda_sonde_ne_leve_jamais_meme_si_le_chargeur_explose():
def charger(nom):
raise RuntimeError("chargeur casse, pas seulement OSError")
assert _cuda_disponible(plateforme="win32", charger=charger) is False