Greboca  

Suport technique et veille technologique

Aujourd’hui, les grandes entreprises et administrations publiques hésitent entre continuer à utiliser des logiciels propriétaires ou basculer vers les Logiciels Libres. Pourtant, la plupart des logiciels libres sont capables de bien traiter les données issues des logiciels propriétaire, et parfois avec une meilleur compatibilité.

C’est alors la barrière de la prise en main qui fait peur, et pourtant...

Les logiciels libres

L’aspect « Logiciel Libre » permet une évolution rapide et une plus grande participation des utilisateurs. Les aides et tutoriels foisonnent sur Internet ou sont directement inclus dans le logiciel lui-même.

Enfin, les concepteurs sont plus proches des utilisateurs, ce qui rend les logiciels libres plus agréable à utiliser et conviviaux.

Grâce à la disponibilité des logiciels libres, vous trouverez facilement des services de support techniques et la licence n’est plus un frein à l’utilisation de ces logiciels par votre personnel.

Notre support technique concerne essentiellement les logiciels libres, que ce soit sous forme de services ponctuels ou de tutoriels.

DLFP - Dépêches  -  Numba 0.14

 -  Septembre 2014 - 

Numba, l'optimiseur Python spécialisé dans le calcul numérique, est sorti en version 0.14. Numba est un compilateur juste-à-temps (JIT) pour Python, basé sur LLVM, permettant d'optimiser du code de calcul numérique, notamment basé sur Numpy. Il est compatible avec CPython 2.6, 2.7, 3.3 et 3.4. Des paquets binaires sont disponibles via Anaconda, la distribution de paquets binaires dédiée au calcul scientifique maintenue par Continuum Analytics, l'entreprise qui développe Numba.

Sommaire

Qu'est-ce que Numba ?

Numba est un compilateur juste à temps pour CPython spécialisé dans l'optimisation de code scientifique.

… CPython ?

CPython est l'implémentation par défaut (ou "de référence", en langage politiquement correct) de Python. Les autres implémentations s'appellent PyPy, Jython, etc.

… Spécialisé ?

Numba ne prétend pas être capable d'optimiser tous les types de code Python, ni même toutes les constructions du langage (même si cela n'est pas exclu comme objectif à long terme). Numba est capable d'optimiser les calculs numériques et scientifiques impliquant des entiers, des flottants, des complexes ; il est capable de reconnaître certaines types de données bien connus, comme les tableaux Numpy.

La liste des fonctionnalités optimisables grandit évidemment de version en version, par exemple la version 0.14 supporte désormais les types numpy.datetime64 et numpy.timedelta64, qui permettent de faire des calculs sur des séries temporelles.

… Juste à temps ?

Numba fonctionne lors de l'exécution de votre code Python. Il suffit d'apposer le décorateur "@numba.jit" à une fonction pour la faire optimiser par Numba (certains aiment prier pour qu'il arrive à l'optimiser). Il n'y a pas de phase de compilation séparée, ni de ligne de commande à lancer.

Plateformes supportées

Numba utilise LLVM, ce qui permet une portabilité relativement aisée. Actuellement, les systèmes sous Linux, OS X et Windows sont supportés. Côté matériel, x86, x86-64 sont supportés et il y a également un backend CUDA (avec des limitations).

Un exemple

Partons de notre ami l'ensemble de Mandelbrot. Pour cela, posons la fonction suivante dans un fichier nommé mandel.py :

import numpy

def mandelbrot(width, height):
    x_min, x_max = -2.0, 1.0
    y_min, y_max = -1.0, 1.0
    arr = numpy.zeros((height, width), dtype=int)
    xs = numpy.linspace(x_min, x_max, num=width)
    ys = numpy.linspace(y_min, y_max, num=height)

    max_iters = 20
    for idx_x, x in enumerate(xs):
        for idx_y, y in enumerate(ys):
            c = complex(x, y)
            z = 0.0j
            for i in range(max_iters):
                z = z * z + c
                if z.real * z.real + z.imag * z.imag >= 4:
                    # Hors de l'ensemble
                    break
            else:
                # Dans l'ensemble
                arr[idx_y, idx_x] = 1

    return arr

Cette fonction renvoie un tableau d'entiers Numpy indiquant si un point fait partie de l'ensemble de Mandelbrot (1) ou non (0).

Maintenant, lançons un Python depuis le même répertoire :

>>> import mandel
>>> print(mandel.mandelbrot(20, 15))
[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0]
 [0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0]
 [0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0]
 [0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]

Ouf, ça ressemble :-) Maintenant compilons cette même fonction avec Numba :

>>> from numba import jit
>>> opt = jit(mandel.mandelbrot)
>>> print(opt(20, 15))
[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0]
 [0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0]
 [0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0]
 [0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]

Et lançons un benchmark d'une scientificité rigoureuse sur un tableau de 200x200 :

>>> import timeit
>>> timeit.timeit("mandel.mandelbrot(200, 200)", setup="import mandel", number=1)
0.20483311700081686
>>> timeit.timeit("opt(200, 200)", setup="from __main__ import opt", number=1)
0.003343598000355996

Sur ce cas d'usage d'une grande importance, Numba est ainsi 60 fois plus rapide que l'interpréteur CPython !

Principe de fonctionnement

Numba est un optimiseur fonction par fonction. Il part de la fonction que vous décorez avec numba.jit et lance une inférence de types pour essayer d'assigner un type précis à chaque variable et valeur intermédiaire dans la fonction. Pour cela, il utilise des règles dédiées à chaque opérateur, fonction standard, etc.

Pour définir les types de départ du processus d'inférence, il y a en réalité deux possibilités :

  • Dans l'utilisation de base de numba.jit, l'utilisateur ne passe pas de paramètres : c'est alors lors de l'appel de la fonction décorée que les types des arguments sont utilisés pour lancer le processus d'inférence (la compilation est ici paresseuse).
  • Dans une utilisation avancée, l'utilisateur peut décrire explicitement les types à l'entrée de la fonction (cela lui permet, par exemple, de choisir des flottants simple précision plutôt que double précision) ; dans ce cas, la compilation a lieu immédiatement.

L'inférence de type est l'étage fondamental qui permet ensuite de produire du code travaillant sur des types bas niveau, plutôt qu'au niveau du modèle objet de Python, qui est beaucoup plus difficile à optimiser. Bien entendu, la chaîne de traitement (pipeline) est constituée de multiples étages :

  1. décodage du bytecode CPython
  2. construction d'un graphe de flot de contrôle (CFG)
  3. génération d'une représentation intermédiaire (IR) spécifique à Numba
  4. inférence de types, produisant une détermination du type de chaque variable manipulée par la fonction
  5. génération de code LLVM correspondant à l'exécution de l'IR sur les types déterminés précédemment
  6. appel à LLVM pour la génération du code machine, et encapsulation du tout dans un objet dédié (wrapper) qui lance le code machine quand il est appelé

Grâce à LLVM, Numba n'a pas à se charger des optimisations bas niveau (propagation de constantes, vectorisation SIMD, etc.) et peut se concentrer sur les traitements spécifiques au langage Python.

Pour une présentation plus détaillée, il convient de lire la documentation (en anglais) : architecture de Numba.

Limitations

À l'heure actuelle, plutôt que de se lancer dans une liste interminable de limitations, il est plus raisonnable de lister ce qui est supporté.

Types supportés

  • les scalaires numériques, que ce soit les types Python (int, float, complex…) ou NumPy (numpy.complex64, etc.)
  • les booléens
  • les dates et intervalles de temps NumPy (numpy.datetime64 et numpy.timedelta64)—mais pas les types standard datetime.datetime et datetime.timedelta
  • les tuples des types ci-dessus
  • les tableaux NumPy des types ci-dessus

Constructions supportées

Numba supporte la plupart des constructions syntaxiques du langage, sauf le traitement des exceptions (try... except, etc.), les gestionnaires de contexte (with), les générateurs (yield) et quelques autres détails.

Fonctions supportées

Numba supporte une grande partie des opérateurs numériques, des fonctions standard (notamment le module math), et certaines fonctions de NumPy. Il est également capable d'optimiser les appels à des fonctions externes via ctypes ou cffi.

Différences sémantiques

Le caractère volontaire (opt-in) de la compilation permet à Numba de présenter des différences sémantiques par rapport au langage Python. Je ne les listerai pas ici, mais une différence évidente a trait aux entiers : les entiers de Python sont de largeur arbitraire, ceux de Numba sont de largeur fixe (déterminée à l'inférence de types, ou forcée par l'utilisateur). Un dépassement lors d'opérations mathématiques entraîne simplement une troncation.

Notons qu'une grande partie de ces différences reflète en réalité le comportement de NumPy (dont les entiers sont aussi à largeur fixe, par exemple).

Numba et l'écosystème Python

Le fait que Numba fonctionne au-dessus de CPython lui permet de s'intégrer facilement à l'écosystème existant. Comme on l'aura compris, l'intégration avec NumPy est également une fonctionnalité de premier plan. D'une manière générale, la stratégie de Continuum (cf. ci-dessous) est de maximiser les possibilités d'interaction entre les multiples briques de calcul scientifique disponibles pour Python.

Statut du projet

Numba est supporté par Continuum Analytics, qui paye à cet effet plusieurs développeurs (dont l'auteur de cette dépêche). Le développement est en partie financé par des clients et des fonds de recherche américains. Nous recevons également des contributions extérieures. Bien entendu, le projet est libre (licence de type MIT).

Contribuer

Numba est un projet jeune auquel manquent de nombreuses fonctionnalités ; il y a donc beaucoup d'opportunités de contribution. Le processus est détaillé dans la documentation. Les compétences nécessaires dépendent de ce à quoi vous vous intéressez :-) La majeure partie du code de Numba est en Python ; il y a quelques parties en C, mais on les évite assez facilement. Nul besoin d'être en expert en NumPy ou en LLVM pour commencer (je ne les connaissais presque pas).

Au débotté, voici quelques directions possibles de contribution, par ordre de difficulté :

  • améliorer la documentation
  • améliorer le retour utilisateur, qui est actuellement assez fruste (messages d'erreur, informations sur la fonction compilée)
  • corriger des bugs (!)
  • ajouter le support de nouvelles fonctions (de la bibliothèque standard ou de NumPy)
  • ajouter le support de nouveaux types
  • ajouter le support de nouvelles constructions (comme la gestion des exceptions ou les générateurs)

Lire les commentaires

par Antoine, Benoît Sibaud

DLFP - Dépêches

LinuxFr.org

L’écriture et l’image, des âges farouches au texte électronique

 -  16 mai - 

Dans cette nouvelle excursion du Transimpressux, nous voyagerons chez les Mayas de l’époque pré-colombienne ainsi que dans la Rome antique. Nous (...)


GIMP 2.10.38 est sorti

 -  14 mai - 

Note : cette dépêche est une traduction de l'annonce officielle de la sortie de GIMP 2.10.38 du 3 mai 2024 (en anglais).Cette (peut-être dernière) (...)


Visualisation d’imageries médicales avec Invesalius

 -  13 mai - 

Nous allons parler ici des examens par imageries médicales de type scanner ou IRM. Un scanner est une série d’images faites aux rayons X et pour une (...)


Lettre d'information XMPP de mars 2024

 -  11 mai - 

N. D. T. — Ceci est une traduction de la lettre d’information publiée régulièrement par l’équipe de communication de la XSF, essayant de conserver les (...)


Conférence OW2con’24 : financements et nouveaux défis réglementaires pour les logiciels libres

 -  9 mai - 

Avec quatre discours inauguraux, quatre sessions en petits groupes et 30 présentations d’experts, la conférence annuelle d’OW2 traite des aspects (...)