Comme dis plus haut, pas de classes utilisateur pour le moment…
L'objectif numéro 1 c'est d'avoir les perfs du C pour des applis scientifiques, donc on a pas forcément besoin de classes utilisateur. Après, tu peux compiler la partie calcul intensif en pythran et garder le reste en Python, c'est là l'intérêt : seule la partie gourmande en calcul a besoin d'être traduite.
Boarf C ou C++, c'est pas le problème, dans les deux cas ça se traduit en code natif. C'est assez transparent pour l'utilisateur lambda.
En ce qui concerne Cython, Je suis assez de l'avis de l'auteur de Nuitka qui dit que cython ça casse la compatibilité avec le code d'origine et c'est pô bien. Pythran n'a pas ce problème.
Bon par contre cython supporte beaucoup plus de modules que nous hein, pythran c'est pas du dix ans d'âge non plus, plutôt moins d'un an sur les week end.
Salut,
ton code m'intéresse. On est en travailler sur le support NumPy (c'est pour ça que c'est dans une branche…), et ton appli peut nous servir de base. Si tu peux le mettre en ligne quelque part, ou le poster sur la mliste pythran, ce serait chouette (voire ce serait hibou).
que ce serait trop beau pour être vrai
Tu as partiellement raison. On supporte quelques modules standards (math, random…) mais pas mal de fonctionnalités du langage (list comprehension, générateurs, …). La plus grosse limitation c'est sûrement l'absence de support pour les classes utilisateurs. là encore si tu rends ton code dispo, on peut ajouter le support pour les fonctionnalités qui manquent.
Je suis surpris que tu compares les performances entre un code en python avec OpenMP vs un code en C sans OpenMP.
Mais non, la vie n'est pas remplie de personnes malhonnêtes. Pour prendre en compte les directives OpenMP dans pythran, il faut spécifier -fopenmp, tout comme gcc. Pour l'exemple du dessus, elles sont bêtement ignorées…
Pour ton problème de compil, ça semble lié à un problème de support du C++11. Quelle est la version de ton compilo ?
Ici:
Debian clang version 3.1-8
gcc (Debian 4.7.2-5) 4.7.2
En tout cas merci de pousser si loin la comparaison :-)
La suite au prochain épisode (si tu passes sur FreeNode #pythran, je me ferai un plaisir de discuter :-))
Et tu es bien content que d'autres réfléchissent à ta place sur une façon d'exécuter de manière décente ta ligne. Normal. Si tu veux la perf de la perf, faut aller la chercher et se retrousser les manches, sinon, tu es content que d'autres capitalisent leur savoir faire dans un outil.
C'est vrai que je ne me suis pas fendu d'un long commentaire sur les raisons de ces résultats… disons que cela alimente le débat… choquer pour provoquer la discussion :-)
Les tableaux utilisés dans le code Python sont des tableaux NumPy, et pas des listes de listes. Ces tableaux ne sont ni plus ni moins que des tableaux natifs encapsulés. Les accès se font en row major en C et en Python et le code donné en tient bien sûr compte.
Autrement dit : très peu de défauts de cache dans cet exemple, que ce soit pour le code C (cf. http://ridee.enstb.org/sguelton/hyantes_bench.tgz) ou le code Python, ou le code C++ généré d'ailleurs.
et ensuite tu peux utiliser le module foocomme un module python normal, sauf que c'est le code natif qui s'execute
fromfooimportma_fonction# là c'est le code natif qui s'execute si foo.so est dans le pathma_fonction(range(10000),{1./iforiinxrange(1,1000)},{i,str(i)foriinrange(10)})
l'avantage c'est que même si pythran disparait de ton environnement, tu touches rien à ton code et il continue de fonctionner. Le seul changement, c'est d'isoler les parties calcul intensif dans un module, mais on pourrait presque dire que c'est pas une mauvaise pratique d'ingénierie :-)
Remarque que rien n'empêche d'écrire un décorateur @pythran qui compile à la volée, mais le temps fuit sous mon clavier, et j'ai pas eu de demandes dans ce sens pour le moment.
Si tu as un code à passer, on peut en discuter sur Freenode #pythran ou pythran@freelists.org :-)
L'info MaisQuelType == int vient de append caché dans foo. Et malheureusement je n'ai pas trouvé de moyen de faire remonter cette info au moment de l'instanciation, donc je suis obliger de mettre ça dans l'inférence de type interprocédurale… je ne sais pas si c'est plus clair comme ça ?
C'est ce que fait https://github.com/numba/numba. (du moins pour la deuxième alternative). Tu ne trouves pas ça ultra moche ? Moi si. Bon ça garde la propriété « compatible python » mais je trouve ça très intrusif.
Pour le moment on donne quelques directives pour les fonctions exportées
#pythran export fibo(int)
mais elles sont facultatives, auquel cas on génère un bon gros .h que l'utilisateur peut instancier comme il le sent. Donc on ne peut pas se servire de ses infos pour l'inférence de type.
mmmh, c'est un peu compliqué à expliquer, mais je me lance. Déjà tout est fonction, els appels de méthodes sont convertis en appels de fonctions. Prenons le cas de la fonction list.append. Les informations associées sont
elle revoie None
elle nous informe que le type de son premier paramètre self doit être compatible avec liste de . Je dis compatible parceque si on ajoute des int puis des float, au final on aura des float.
ces informations sont spécifiées en Pythran par une forme de signature de l'intrinsèque.
ensuite considérons, hors de son contexte (par exemple si la fonction n'est jamais appelée dans le module, on ne peut donc pas savoir le type des paramètres)
que faire pour append ? Je suis incapable de décider si c'est le append de list ou celui de ique. Quelles informations de type utiliser?
Vu autrement, le problème est que je veux générer des fonctions c++ polymorphiques, et donc on ne manipule ques des types symboliques ce qui fait que quand j'ai un appel de méthode, je ne sais pas (jusque l'instanciation, mais qui arrive bien plus tard) quel est le type exact des objets que je manipule, je connais juste les relations entre les types.
En théorie oui. D'ailleurs shedskin le fait.
Deux points me gênent pour le moment :
Gestion Mémoire :
En utilisant l'hypothèse types non récursifs on peut se permettre une gestion simplifiée de la mémoire (par compteurs de référence). Bon, on peut toujours refuser les classes qui induisent des dépendances de type circulaire…
Inférence de type :
Le moteur d'inférence de type de Pythran a quelques limitations. Quand je rencontre un appel de méthode, je ne sais pas à quelle classe elle est rattachée. Quand l'ensemble des méthodes (i.e. celles des conteneurs) est connu, je m'en sors très bien, mais sinon, je pense que ça va être coton.
mais la crème, c'est les variadic templates qui permettent d'implémenter de façon élégante les fonctions intrinsèques de la lib standard du genre reduce et cie…
Bah non… numpy c'est un module qui expose des structures de données optimisées (ndarray) pour le calcul scientifique et avec un coût de passage du monde python au monde natif quasi-nul et les fonctions pour travailler dessus.
Je suppose que le but c'est de pouvoir coder plus vite grâce à la simplicité de Python et générer du code C++ qui une fois compilé tournera vite ?
Oui :-) Dans la même veine que Cython, en moins intrusif
Ça veut dire qu'il n'y a plus de notion d'objet dans ton langage Python-like
C'est pas Python-like, c'est Python-embded mais c'est un détail. Tu as accès aux conteneurs de base (list/set/dict/tuple), à terme file, mais pas de classes utilisateurs. Tu peux avoir des classes au dessus (dans la partie non Pythran) et appeler le module devenu natif pour les parties gourmandes en calcul. Le but n'est pas de traduire tout Python, juste les parties gourmandes, qui n'ont pas forcément besoin de classe, comme l'illustre le lien sur le gars qui répond aux devinettes du projet euler sans utiliser de classes.
Par exemple on a récemment convertit un petit code de simulation (~300SLOC), pas de classes, et un speedup de x50 à la clef.
Si on est prêt à utiliser les extensions GNU, asprintf fait des merveilles. Sinon, il y a la gnulib qui apporte la couche de portabilité manquante et qui s'intègre merveilleusement bien à un build autotool.
C'est un convertisseur d'un sous ensemble de python vers du C++. En gros en enlevant les classes utilisateurs et tous les aspects trop dynamiques, on arrive à convertir des codes de calcul en des codes relativement efficace (cf. benchs dans le journal). Le README du projet est, je l'espère, plus explicite ?
[^] # Re: Ça m'intéresse
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran 0.2 : Python peut-il être aussi rapide que du C ?. Évalué à 1.
Owi un rapport de bug :-)
Bon on supporte pas scipy pour le moment… mais les fonctions que tu cites ont l'air abordables.
[^] # Re: Liaison dynamique
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran 0.2 : Python peut-il être aussi rapide que du C ?. Évalué à 2.
Comme dis plus haut, pas de classes utilisateur pour le moment…
L'objectif numéro 1 c'est d'avoir les perfs du C pour des applis scientifiques, donc on a pas forcément besoin de classes utilisateur. Après, tu peux compiler la partie calcul intensif en pythran et garder le reste en Python, c'est là l'intérêt : seule la partie gourmande en calcul a besoin d'être traduite.
[^] # Re: Ça m'intéresse
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran 0.2 : Python peut-il être aussi rapide que du C ?. Évalué à 2.
Boarf C ou C++, c'est pas le problème, dans les deux cas ça se traduit en code natif. C'est assez transparent pour l'utilisateur lambda.
En ce qui concerne Cython, Je suis assez de l'avis de l'auteur de Nuitka qui dit que cython ça casse la compatibilité avec le code d'origine et c'est pô bien. Pythran n'a pas ce problème.
Bon par contre cython supporte beaucoup plus de modules que nous hein, pythran c'est pas du dix ans d'âge non plus, plutôt moins d'un an sur les week end.
[^] # Re: Ça m'intéresse
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran 0.2 : Python peut-il être aussi rapide que du C ?. Évalué à 2.
Salut,
ton code m'intéresse. On est en travailler sur le support NumPy (c'est pour ça que c'est dans une branche…), et ton appli peut nous servir de base. Si tu peux le mettre en ligne quelque part, ou le poster sur la mliste pythran, ce serait chouette (voire ce serait hibou).
Tu as partiellement raison. On supporte quelques modules standards (
math
,random
…) mais pas mal de fonctionnalités du langage (list comprehension, générateurs, …). La plus grosse limitation c'est sûrement l'absence de support pour les classes utilisateurs. là encore si tu rends ton code dispo, on peut ajouter le support pour les fonctionnalités qui manquent.[^] # Re: show me the code
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran 0.2 : Python peut-il être aussi rapide que du C ?. Évalué à 6.
Mais non, la vie n'est pas remplie de personnes malhonnêtes. Pour prendre en compte les directives OpenMP dans pythran, il faut spécifier
-fopenmp
, tout comme gcc. Pour l'exemple du dessus, elles sont bêtement ignorées…Pour ton problème de compil, ça semble lié à un problème de support du C++11. Quelle est la version de ton compilo ?
Ici:
Debian clang version 3.1-8
gcc (Debian 4.7.2-5) 4.7.2
En tout cas merci de pousser si loin la comparaison :-)
La suite au prochain épisode (si tu passes sur FreeNode #pythran, je me ferai un plaisir de discuter :-))
[^] # Re: World is full of nonsense.
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran 0.2 : Python peut-il être aussi rapide que du C ?. Évalué à 7.
Et quel plaisir de participer au foutoir ambiant :-)
[^] # Re: UUUUUrgh !!!!!!
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran 0.2 : Python peut-il être aussi rapide que du C ?. Évalué à 10.
Et tu es bien content que d'autres réfléchissent à ta place sur une façon d'exécuter de manière décente ta ligne. Normal. Si tu veux la perf de la perf, faut aller la chercher et se retrousser les manches, sinon, tu es content que d'autres capitalisent leur savoir faire dans un outil.
[^] # Re: Je reste plus que dubitatif
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran 0.2 : Python peut-il être aussi rapide que du C ?. Évalué à 5.
C'est vrai que je ne me suis pas fendu d'un long commentaire sur les raisons de ces résultats… disons que cela alimente le débat… choquer pour provoquer la discussion :-)
Les tableaux utilisés dans le code Python sont des tableaux NumPy, et pas des listes de listes. Ces tableaux ne sont ni plus ni moins que des tableaux natifs encapsulés. Les accès se font en row major en C et en Python et le code donné en tient bien sûr compte.
Autrement dit : très peu de défauts de cache dans cet exemple, que ce soit pour le code C (cf. http://ridee.enstb.org/sguelton/hyantes_bench.tgz) ou le code Python, ou le code C++ généré d'ailleurs.
Pour en savoir plus: The NumPy array: a structure for efficient numerical computation
[^] # Re: Je ne comprend pas trop…
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran 0.2 : Python peut-il être aussi rapide que du C ?. Évalué à 3.
Oui c'est ça ! Si le code est implicitement non polymorphe, on s'en sort pas trop mal. Sinon on crache une erreur c++ de 50 lignes de long :-)
[^] # Re: show me the code
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran 0.2 : Python peut-il être aussi rapide que du C ?. Évalué à 6.
Homme de peu de foi !
Test efectué à l'instant avec la branche compas2013 du dépot sus-cité
Sur l'archive http://ridee.enstb.org/sguelton/hyantes_bench.tgz
En supposant pythran installé quelque par
Le tout sur un Core I7.
à vot' service Saint Thomas !
# En python
Posté par serge_sans_paille (site web personnel) . En réponse au message Générer des fichiers texte selon un modèle. Évalué à 1.
En utilisant le moteur de template fourni par le module string :
[^] # Re: Include à l'envers :-)
Posté par serge_sans_paille (site web personnel) . En réponse au message Problème de templates: undefined reference. Évalué à 1.
find /usr/include/c++/4.7
(et une paire d'yeux aguerris) nous informe que gcc stocke ça sous forme de.tcc
.[^] # Re: Plus de classes
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran : C++ pour les serpents. Évalué à 1.
Je dirais question de compilo / archi. Je n'observe pas ce phénomène sur ma machine (amd64/debian sid)
[^] # Re: Plus de classes
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran : C++ pour les serpents. Évalué à 1.
Pour le moment, tu prends un module python, disons
foo.py
, tu l'annotes légèrementpuis
et ensuite tu peux utiliser le module
foo
comme un module python normal, sauf que c'est le code natif qui s'executel'avantage c'est que même si pythran disparait de ton environnement, tu touches rien à ton code et il continue de fonctionner. Le seul changement, c'est d'isoler les parties calcul intensif dans un module, mais on pourrait presque dire que c'est pas une mauvaise pratique d'ingénierie :-)
Remarque que rien n'empêche d'écrire un décorateur
@pythran
qui compile à la volée, mais le temps fuit sous mon clavier, et j'ai pas eu de demandes dans ce sens pour le moment.Si tu as un code à passer, on peut en discuter sur Freenode #pythran ou pythran@freelists.org :-)
[^] # Re: Plus de classes
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran : C++ pour les serpents. Évalué à 4.
Oui, oui, je fais déjà tout ça. Mon exemple n'était pas bon
traduit comme tu le proposes ça donnerait
L'info
MaisQuelType == int
vient deappend
caché dans foo. Et malheureusement je n'ai pas trouvé de moyen de faire remonter cette info au moment de l'instanciation, donc je suis obliger de mettre ça dans l'inférence de type interprocédurale… je ne sais pas si c'est plus clair comme ça ?[^] # Re: Plus de classes
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran : C++ pour les serpents. Évalué à 2.
C'est ce que fait https://github.com/numba/numba. (du moins pour la deuxième alternative). Tu ne trouves pas ça ultra moche ? Moi si. Bon ça garde la propriété « compatible python » mais je trouve ça très intrusif.
Pour le moment on donne quelques directives pour les fonctions exportées
mais elles sont facultatives, auquel cas on génère un bon gros .h que l'utilisateur peut instancier comme il le sent. Donc on ne peut pas se servire de ses infos pour l'inférence de type.
[^] # Re: Plus de classes
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran : C++ pour les serpents. Évalué à 1.
mmmh, c'est un peu compliqué à expliquer, mais je me lance. Déjà tout est fonction, els appels de méthodes sont convertis en appels de fonctions. Prenons le cas de la fonction
list.append
. Les informations associées sontNone
self
doit être compatible avec liste de . Je dis compatible parceque si on ajoute desint
puis desfloat
, au final on aura desfloat
.ces informations sont spécifiées en
Pythran
par une forme de signature de l'intrinsèque.ensuite considérons, hors de son contexte (par exemple si la fonction n'est jamais appelée dans le module, on ne peut donc pas savoir le type des paramètres)
que faire pour append ? Je suis incapable de décider si c'est le append de
list
ou celui deique
. Quelles informations de type utiliser?Vu autrement, le problème est que je veux générer des fonctions c++ polymorphiques, et donc on ne manipule ques des types symboliques ce qui fait que quand j'ai un appel de méthode, je ne sais pas (jusque l'instanciation, mais qui arrive bien plus tard) quel est le type exact des objets que je manipule, je connais juste les relations entre les types.
[^] # Re: Plus de classes
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran : C++ pour les serpents. Évalué à 1.
En théorie oui. D'ailleurs shedskin le fait.
Deux points me gênent pour le moment :
Gestion Mémoire :
En utilisant l'hypothèse types non récursifs on peut se permettre une gestion simplifiée de la mémoire (par compteurs de référence). Bon, on peut toujours refuser les classes qui induisent des dépendances de type circulaire…
Inférence de type :
Le moteur d'inférence de type de
Pythran
a quelques limitations. Quand je rencontre un appel de méthode, je ne sais pas à quelle classe elle est rattachée. Quand l'ensemble des méthodes (i.e. celles des conteneurs) est connu, je m'en sors très bien, mais sinon, je pense que ça va être coton.[^] # Re: C++ oui mais pourquoi ?
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran : C++ pour les serpents. Évalué à 7.
Oui ! Plus précisément
Pour la lib standard
list
->std::vector
set
->std::unordered_set
dict
->std::unordered_map
tuple
->std::tuple
(assez costaud celui là)print(truc, muche)
->std::cout << truc << ' ' << muche
Pour l'inférence de type
decltype
etdeclval
font des merveillesPour la gestion mémoire
vive les
std::shared_ptr
Petit exemple
qui devient (en simplifiant)
La crème de la crème
mais la crème, c'est les variadic templates qui permettent d'implémenter de façon élégante les fonctions intrinsèques de la lib standard du genre
reduce
et cie…[^] # Re: Intéressant
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran : C++ pour les serpents. Évalué à 1.
C'est ça.
Nous apprend qu'il y a des dépendances sur
libgfortran3
,libblas3gf | libblas.so.3gf | libatlas3gf-base
ce qui annonce un peu la couleur :-)[^] # Re: Intéressant
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran : C++ pour les serpents. Évalué à 1.
Bah non… numpy c'est un module qui expose des structures de données optimisées (
ndarray
) pour le calcul scientifique et avec un coût de passage du monde python au monde natif quasi-nul et les fonctions pour travailler dessus.[^] # Re: Intéressant
Posté par serge_sans_paille (site web personnel) . En réponse au journal Pythran : C++ pour les serpents. Évalué à 2.
Oui :-) Dans la même veine que Cython, en moins intrusif
C'est pas Python-like, c'est Python-embded mais c'est un détail. Tu as accès aux conteneurs de base (
list
/set
/dict
/tuple
), à termefile
, mais pas de classes utilisateurs. Tu peux avoir des classes au dessus (dans la partie non Pythran) et appeler le module devenu natif pour les parties gourmandes en calcul. Le but n'est pas de traduire tout Python, juste les parties gourmandes, qui n'ont pas forcément besoin de classe, comme l'illustre le lien sur le gars qui répond aux devinettes du projet euler sans utiliser de classes.Par exemple on a récemment convertit un petit code de simulation (~300SLOC), pas de classes, et un speedup de x50 à la clef.
# asprintf
Posté par serge_sans_paille (site web personnel) . En réponse au journal Genèse d'un journal. Évalué à 3.
Si on est prêt à utiliser les extensions GNU,
asprintf
fait des merveilles. Sinon, il y a la gnulib qui apporte la couche de portabilité manquante et qui s'intègre merveilleusement bien à un build autotool.[^] # Re: Super naze
Posté par serge_sans_paille (site web personnel) . En réponse au journal Échec et mat. Évalué à 1.
Zut, j'aime bien faire des pompes moi…
[^] # Re: saikoi ?
Posté par serge_sans_paille (site web personnel) . En réponse au journal pythran prépare sa mue. Évalué à 2.
Merci de me faire découvrir la PEP20 !
Pour pythran c'est… bien :-)
C'est un convertisseur d'un sous ensemble de python vers du C++. En gros en enlevant les classes utilisateurs et tous les aspects trop dynamiques, on arrive à convertir des codes de calcul en des codes relativement efficace (cf. benchs dans le journal). Le README du projet est, je l'espère, plus explicite ?