Template, OpenMP et clause reduction

Template, OpenMP et clause reduction - C++ - Programmation

Marsh Posté le 14-03-2009 à 00:55:34    

Salut,
 
J'ai une fonction template resolvant une équation de Poisson.
Dans cette méthode je fais appel  des boucles que je parallelise avec OpenMP.
A un moment donné de l'algo, une boucle incrémente une variable extérieure à la boucle, donc je la passe en reduction.
 
Les problèmes arrivent lorsque mon template prendre des types non scalaire, par exemple un objet Coord_2D (pour gérer des coordonnées 2D).
 
Du coup la compile plante sur le pragma open mp reduction car la variable n'est plus de type scalaire.
 
J'ai donc besoin de commandes préprocesseur pour tester le type du template, et adapter les déclarations de variables / directives OpenMP en fonction.
 
Considérons la déclaration suivante :
 

Code :
  1. template <class type> void Poisson_solver(..)


 
J'ai essayé ça :
 

Code :
  1. typedef Coord_2D<float> coord_2d_float
  2. ...
  3. #if type == coord_2d_
  4. ..
  5. #endif


 
Mais cela ne semble pas fonctionner.
 
J'ai également essayé en passant un 2ème paramètre au template, comme ça :
 

Code :
  1. template <class type, int dimension> void Poisson_solver(..)
  2. ..
  3. #if dimension == 2
  4. ..
  5. #endif


[/cpp]
 
Mais ça ne semble pas fonctionner non plus.
 
Est-il possible de tester à la précompile le type du template ?
 
Merci d'avance !

Reply

Marsh Posté le 14-03-2009 à 00:55:34   

Reply

Marsh Posté le 14-03-2009 à 09:15:57    

Alors deja, on n'essaye aps des trucs au hasard en pensant que ca amrche.
Le preprocesseur est appelé en amont de la compilation, la résolution des types en plein mileiux, donc jamais ca amrche.

 

c'est pas du preprocesseur qu'il te faut mais meta-programmer deux variantes de ta boucle que tu spécialise selon le retour de la meta-fonction boost::is_fundamental qui renvoit un booleen statique si le type testé est un type atomique du langage.

 

en gros

 
Code :
  1. template<class T, bool isFundamental> struct mon_solveur_impl;
  2. template<class T> struct mon_solveur : mon_solveur_impl<T, typename boost::is_fundamental<T>::value> {};
  3. template<class T> struct mon_solveur_impl<T,true>
  4. {
  5.    void solve()
  6.   {
  7.    // T est fundamental, j'ecris du OpenMP sans probleme
  8.   }
  9. };
  10. template<class T> struct mon_solveur_impl<T,false>
  11. {
  12.    void solve()
  13.   {
  14.    // T n'est pas fundamental, j'ecris autre chose
  15.   }
  16. };
 

http://www.boost.org/doc/libs/1_38 [...] ental.html


Message édité par Joel F le 14-03-2009 à 09:21:06
Reply

Marsh Posté le 14-03-2009 à 10:14:04    

Le truc c'est que je ne veux pas réécrire 2 fois l'agorithmes du solver, c'est pas beau à mon gout. Je veux une seule fonction template qui gère tout les cas.


---------------
http://www.ryphon-mechanics.com
Reply

Marsh Posté le 14-03-2009 à 10:24:30    

C'est pas bien compliqué. Si la seule difference entre la version OpenMP et l'autre c'est les pragma openMP tu ecris :

 
Code :
  1. template<class T, bool isFundamental> struct mon_solveur_impl;
  2. template<class T> struct mon_solveur : mon_solveur_impl<T, typename boost::is_fundamental<T>::value> {};
  3. template<class T> struct mon_solveur_impl<T,false>
  4. {
  5.    void solve()
  6.   {
  7.    // T n'est pas fundamental, j'ecris autre chose
  8.      mon_solveur_qui_fait_le_vrai_calcul<T>();
  9.   }
  10. };
  11. template<class T> struct mon_solveur_impl<T,true>
  12. {
  13.    void solve()
  14.   {
  15.    // T est fundamental, j'ecris du OpenMP sans probleme
  16.   #pragma omp parallel ????
  17.      mon_solveur_qui_fait_le_vrai_calcul<T>();
  18.  
  19.   }
  20. };
 

Aprés tu n'as pas le choix, le controle sur les types se fait là et pas avant.


Message édité par Joel F le 14-03-2009 à 10:24:46
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed