Introduction
JMFFT est une bibliothèque de sous-programmes de transformées de
Fourier écrite par Jean-Marie
Teuler, émulant la plupart des sous-programmes de transformées de
Fourier de la bibliothèque Cray (la SCILIB).
JMFFT offre les avantages suivants :
- JMFFT est très complète : elle couvre la plupart des sous-programmes
de la SCILIB CRAY, y compris certaines versions obsolètes,
- JMFFT est très portable.
- JMFFT est très simple à utiliser car elle émule exactement les
séquences d'appel de la SCILIB CRAY : mêmes arguments et mêmes dimensions.
- Bien que ceci n'ait pas été le souci majeur lors de sa conception,
JMFFT est raisonnablement performante.
- JMFFT peut être assez facilement optimisée pour une architecture
donnée car tout le temps de calcul se passe dans un petit nombre de
boucles d'environ 30 lignes.
Contenu de JMFFT
On y trouvera les sous-programmes suivants :
Outre ces sous-programmes de premier niveau, il existe également des
sous-programmes de second niveau, appelés par les précédents.
Il existe également certains sous-programmes de service qui peuvent
être intéressants à appeler :
Pour une discussion de l'intérêt et de l'utilisation de ces sous-programmes,
voir ci-dessous.
- JMFFT peut à priori traiter des tableaux dimensionnés avec
n'importe quelle combinaison de nombres premiers. Ceci dit, la version
fournie se limite aux combinaisons des nombres premiers suivants : 2, 3 et
5 d'une part (pour lesquels des sous-programmes particuliers sont écrits
pour des raisons de performance) puis une liste d'autres nombres premiers.
Cette liste est constituée des nombres premiers suivants : 7, 11, 13, 17,
19, 23 et 29. Il est possible assez facilement d'étendre cette liste. Il
suffit de modifer dans le sous-programme jmfact les instructions
suivantes :
integer, parameter :: npremiers = 7
integer, dimension(0:npremiers-1) :: premiers = (/7,11,13,17,19,23,29/)
de façon à inclure les nombres premiers de son choix, et de recompiler
ce sous-programme.
- Une autre limitation, pour laquelle il n'existe malheureusement pas
de solution pour l'instant, porte sur les transformées réelles-complexes
et complexes-réelles. Celles-ci sont disponibles, mais exigent que l'une
des dimensions au moins soit paire :
- en 1D, la dimension de la T.F. doit être paire
- en 2D, l'une des deux dimensions doit être paire
- en 3D, l'une des trois dimensions doit être paire
- en 1D multiple, la dimension de la T.F.
ou le nombre de T.F. doit être paire.
- Malgré le choix d'algorithmes très orientés vers la vectorisation,
les performances n'égalent pas encore celles des grandes bibliothèques,
notamment les bibliothèques constructeurs. Ceci dit, si quelqu'un veut s'y
mettre, sa tâche sera grandement facilitée par le fait que le temps de
calcul est concentré dans quelques sous-programmes : jmccm1d2
(base 2, inutilisée en principe), jmccm1d3 (base 3),
jmccm1d4 (base 4), jmccm1d5 (base 5) et
jmccm1dp (nombre premier général).
- Bien que la version Fortran soit écrite en Fortran 90, JMFFT ne tire
pas parti des nombreuses possibilités de ce langage, qui seraient pourtant
très intéressantes ici (allocation dynamique de mémoire, modules, tableaux
à profil implicite, arguments optionnels etc). La raison essentielle est
la compatibilité avec la SCILIB CRAY: il faut que l'utilisateur puisse
remplacer ses appels à la SCILIB directement par des appels à JMFFT sans
rien changer d'autre, ce qui exclut toute utilisation sophistiquée des
possiblités Fortran 90.
- JMFFT effectue un certain nombre de vérifications sur les arguments
qui lui sont transmis. Elle peut ainsi détecter des erreurs. Le problème
est alors d'en informer l'utilisateur. Ce n'est pas si simple car la
SciLib n'a pas inclus de code de retour parmi les arguments de ses
sous-programmes et que JMFFT, pour des raisons de compatibilité, n'a pas
pu en ajouter. Ceci dit, une solution a été trouvée pour contourner
cette lacune. Voir ci-dessous.
Il existe dans JMFFT des sous-programmes de service qui permettent
de contrôler son comportement.
- JMSETNWORK
Ce sous-programme permet de contrôler plus
finement l'espace de travail dont disposeront les sous-programmes 2D et
3D. En effet, dans la SCILIB, le tableau de travail WORK doit être
dimensionné à 512*MAX(N1,N2) en 2D et à 512*MAX(N1,N2,N3)
en 3D. Avec une telle dimension, la longueur des boucles dans les
sous-programmes de calcul est de 128, ce qui est optimal en effet sur les
C90. En revanche, une telle longueur de boucle est loin d'être optimale sur
un Fujitsu VPP300 ou sur un NEC SX-5 par exemple. JMSETNWORK permet de
fournir plus d'espace de travail à JMFFT, et donc d'obtenir de meilleures
performances. Son utilisation est très simple. Par exemple dans l'appel
suivant :
call jmsetnwork(4096)
on fournit 4096 éléments d'espace de travail à JMFFT.
Notes :
- Attention : L'utilisateur doit bien veiller à la cohérence
entre la dimension fournie à JMFFT et le dimensionnement du tableau
WORK dans son sous-programme appelant. JMFFT ne dispose
d'aucun moyen pour connaître la dimension réelle de ce tableau
(c'est d'ailleurs pour cela que dans le cas où l'utilisateur le
surdimensionne, il doit en informer JMFFT en appelant
JMSETNWORK). En particulier, la dimension réelle du tableau
WORK doit toujours être supérieure ou égale à ce qu'attend
JMFFT (qu'il s'agisse de la valeur par défaut ou de la valeur qui
lui a été transmise via JMSETNWORK).
- Ce mécanisme a été prévu pour augmenter l'espace de travail
disponible, mais il peut également être utilisé pour le réduire
(au cas où on manquerait de ressources mémoire).
- Ce mécanisme n'est effectif que sur les sous-programmes 2D et 3D.
- Cet espace de travail sera utilisé dans toutes les sous-programmes 2D
et 3D qui suivent, et restera en vigueur sauf si on appelle une nouvelle
fois JMSETNWORK.
- JMSETERREUR
Les sous-programmes de JMFFT vérifient la cohérence des arguments
transmis. Lorsqu'ils détectent une incohérence, le comportement par défaut
est alors de tout arrêter en affichant un message d'erreur et en
déclenchant une instruction STOP. Ce comportement est imposé
par la compatibilité avec la SCILIB qui n'a prévu aucun argument de
type code de retour, comme celui que l'on trouve par exemple
dans NAG et IMSL. Ceci dit, on peut le modifier légèrement. Si on
effectue l'appel suivant :
call jmseterreur(.false.)
en cas d'erreur l'exécution n'est pas interrompue. Voir ci-dessous les
deux sous-programmes qui permettent de vérifier si une erreur s'est
produite et si oui laquelle.
- JMGETCODE
Si l'on a effectué l'appel précédent, en cas d'erreur l'exécution se
poursuit. C'est donc à l'utilisateur de vérifier, après chaque appel
de JMFFT, si une erreur s'est produite. Ceci peut se faire de la
façon suivante :
call jmgetcode(irc)
où irc est une variable entière qui contient le code de retour
du dernier appel à JMFFT. Si ce code est nul, c'est que tout s'est bien
passé. Sinon, une erreur a été détectée. Pour savoir laquelle, voir
ci-dessous.
- JMGETMESSAGE
Si une erreur s'est produite et que l'on a obtenu le code d'erreur
irc par appel de JMGETCODE, on peut récupérer le
message d'erreur correspondant par l'appel suivant :
call jmgetmessage(irc, message)
où message est une variable de type chaîne de caractères qui
contiendra au retour le texte en clair du message d'erreur.
© CNRS - IDRIS, 08/03/2010