Projet

Général

Profil

Actions

Assistance #398

ouvert

Compilation Herezh++ sur Linux

Ajouté par Julien Troufflard il y a 21 jours. Mis à jour il y a 18 jours.

Statut:
En cours
Priorité:
Normal
Assigné à:
Version cible:
-
Début:
05/03/2026
Echéance:
% réalisé:

20%

Temps estimé:
Temps passé:

Description

Gérard,

je suis en train d'essayer de me mettre à jour sur la compilation de Herezh.
J'ouvre donc un sujet sur la compilation Herezh.

J'avais déjà essayé depuis la branche V_7.028 ou V_7.30. Et j'avais réussi d'après ce ticket : https://herezh.irdl.fr/issues/371
Mais ce n'était pas vraiment le sujet du ticket, et depuis, je n'ai jamais réussi à recompiler une version Herezh (avec CodeBlocks).

J'ai envie de repartir de la base en utilisant un Makefile (et le tout dans l'EDI : Visual Studio Code, qui est plus couramment utilisé que CodeBlocks, mais ceci n'a pas d'importance, ça revient à faire du Makefile dans un terminal).

J'ai refait un makefile en partant de la base et en m'inspirant de celui proposé dans Herezh_dev/fichiers_makefile/makefile_HZppfast.

Je travaille depuis la branche V_7.061.

Je vais commencer par 3 points pas vraiment bloquant mais à résoudre quand même :

1) Mon compilateur m'indique un problème venant de Herezh_dev/Util/Algo_Integ1D.h
à la fin de ce fichier, il y a un include du fichier Herezh_dev/Util/Algo_Integ1D_2.cc :

};
  // pour faire de l'inline: nécessaire avec les templates
  // on n'inclut que les méthodes templates
  #include "Algo_Integ1D_2.cc" 
  #define  Algo_Integ1D_deja_inclus
 /// @}  // end of group

#endif  

Ceci provoque une erreur car mon compilateur prétend que la fonction double Algo_Integ1D::IntegGauss serait déclarée plusieurs fois (error: redefinition of ...).

J'ai réussi à supprimer cette erreur en commentant la ligne concernée :

};
  // pour faire de l'inline: nécessaire avec les templates
  // on n'inclut que les méthodes templates
  //#include "Algo_Integ1D_2.cc" 
  #define  Algo_Integ1D_deja_inclus
 /// @}  // end of group

#endif  

et ceci, sachant que Algo_Integ1D_2.cc est déjà include dans mon Makefile.

Je remarque à ce sujet que le makefile proposé dans Herezh_dev/ ne fait pas d'include de ce fichier Algo_Integ1D_2.cc. Mais par contre, il le fait dans la version codeblock (il est include dans le fichier Herezh_dev/linux/Herezh.cbp).

Je réussis donc à surmonter cette erreur en mettant en commentaires, mais ça m'embête un peu de devoir modifier le fichier source alors que toi de ton côté tu ne le fais pas. Je serais obligé de refaire la manip à chaque nouvelle branche d'Herezh que tu vas produire.

As-tu une idée de comment procéder ?

2) dans le fichier Herezh_dev/Util/suites/Suite_geometrique.h ou .cc, il y a un include du fichier "Enum_Suite.h". Mon compilateur ne le trouve pas à cause d'une erreur de casse.

Dans le répertoire Herezh_dev/Enumeration/, on a d'une part un fichier Enum_Suite.cc (avec un S majuscule) mais d'autre part un fichier Enum_suite.h (avec un s minuscule).

Dans la même lignée que le 1), je pourrais modifier à la main en renommant Enum_suite.h en Enum_Suite.h. Mais pour la même raison, j'attends ton avis là-dessus.

3) toutes ces tentatives de compilation ont été faites dans la norme : -std=gnu++98. En fait, j'ai pas mal d'erreur si j'essaye un standard plus récent. Mon gcc est en c++17 par défaut.

Je ne vois aucune option à ce sujet dans les Makefile de Herezh_dev/. As-tu une idée de la norme utilisée de ton côté quand tu compiles sur Linux.
Pour connaitre celle de mon gcc par défaut, j'ai fait :

echo | gcc -x c++ -dM -E - | grep __cplusplus

qui m'a renvoyé :
#define __cplusplus 201703L

c'est-à-dire la norme c++17

pour info, a priori, si j'étais en norme gnu++98 (ou c++98), j'aurais obtenu : #define __cplusplus 199711L

Mis à jour par Gérard Rio il y a 21 jours

  • Statut changé de Nouveau à En cours

bonjour Julien,
Je crois savoir où est (potentiellement) le problème.
C'est une manip particulière que j'effectue dans pas mal d'endroits.
J'essaie de décrire le processus de manière générale et ensuite j'en viendrai à tes cas pratiques
Il y a plusieurs raisons.
1) Dans la version lente avec vérification, c'est intéressant de pouvoir en debug exécuter step par step, chaque ligne. De plus souvent les méthodes mêmes courtes peuvent devenir longue à cause de vérifications diverses en cours d'exécution. Dans la version rapide, il y a le minimum de vérif, et je cherche à optimiser la vitesse.
Du coup dans la version rapide je privilégie les méthodes en inline, c'est-à-dire que le compilo remplace l'appel à une méthode par la réécriture de la méthode au sein de la méthode appelante. Le code est plus long, mais on gagne l'appel. Par exemple pour une méthode qui ne fait que ramener un pointeur sur une variable interne, en inline, la méthode est remplacée par l'adresse de la variable interne. Par contre en débug, là je souhaite que le programme passe par la méthode qui ramène le pointeur et si je suspecte une erreur à ce niveau, je peux mettre un breakpoint au niveau de cette méthode (ce qui n'est pas possible en version rapide). C'est un exemple basique, mais par exemple dans le cas des opérations sur les tenseurs, les opérations sont également mises en inline en version rapide, et là c'est beaucoup plus rapide qu'en version lente.
Pour indiquer qu'une méthode est en inline, il y a deux façons, soit on la déclare dans le .h, ou soit on indique devant le mot clé inline.
Du coup dans Herezh, en version lente, j'ai un .h qui décrit la signature d'appel, sans le corps d'exécution, et en rapide j'inclus dans le .h, à la fin j'inclus tous les .cc en inline.Ceci via des variables de précompilation
voir par exemple Tenseur1HH.h et Tenseur1HH.cc

Mais au niveau de la déclaration des fichiers (pour les méthodes qui ont des inlines):
- en version lente on déclare les .h et les .cc
- en version rapide on déclare que les .h (car ils contiennent déjà les .cc)

Je pense que c'est une des raisons potentielles des pb que tu as rencontrés. Si tu compares les makefiles pour les versions lentes et rapides (idem pour les fichiers de config pour codeblock) tu verras qu'ils ne sont pas exactement identiques.

2) La deuxième raison est que pour les templates, ce n'est pas possible d'utiliser de manière séparée les .h et les .cc. C'est obligatoire de mettre le corps des méthodes soit dans la partie signature, soit après, mais pas de manière séparé, donc soit en mettant tout dans un même fichier, ou soit via des includes.
Du coup, comme je préfère, même pour des templates, avoir une séparation entre la signature et le corps pour plus de lisibilité, j'utilise le même mécanisme qu'exposé en 1)
Mais là aussi il ne faut pas inclure le .cc dans la liste des méthodes à compiler dans le makefile, et ceci pour les deux versions lente et rapide.

Donc à vérifier dans ton cas.

Mis à jour par Julien Troufflard il y a 20 jours

ok. J'ai tenu compte de ça en excluant le fichier Algo_Integ1D_2.cc dans le makefile. Et donc en gardant le #define dans le .h

J'ai fini par remporter la bataille avec un premier HZppfast64 compilé avec succès. Un seul vrai souci dans ce que je vais raconter ci-dessous.

1) concernant la norme C++ (option gcc : -std)

J'ai fini par trouver ce qui coinçait. Dans les makefile proposés sur Herezh_dev/, il y a l'option : -D__cplusplus=1
Il faut absolument la supprimer. Cette variable revient à indiquer un -std égal à 1. Cette variable est utilisée dans des lib standard du C++. A cause d'elle, mon option -std n'était pas prise en compte partout. A la place, certaines libs considéraient un équivalent : -std=1. Or certaines requièrent au minimum c++11.

Après suppression de cette option, j'ai pu compiler en prenant simplement le standard par défaut de gcc (c++17 dans mon cas).

2) Dans mon makefile, j'ai voulu éviter de lister un à un les répertoires à include -I et également éviter de lister un à un les fichiers .cc à compiler.
J'ai mis une instruction qui récupère automatiquement tous les répertoires de Herezh_dev/ à include + quelques rép ciblés pour les lib exterieures (muParser, etc...). Et ensuite j'y récupère automatiquement les fichiers .cc.

Je voulais plus de lisibilité dans mon makefile et éviter de passer à côté de certains fichiers si la liste n'est pas up-to-date. Mais le problème est que certains .cc ne sont pas nécessaires à Herezh et surtout certains d'entre-eux ne sont pas compilables (erreurs diverses).

Donc j'ai résolu en excluant les fichiers problématiques et en vérifiant qu'ils n'étaient pas nécessaires d'après la liste de .cc indiquée dans le makefile : Herezh_dev/fichiers_makefile/makefile_HZppfast_MPI (j'ai supposé que c'était le makefile le plus récent que tu avais archivé sur git).

J'en arrive à cette liste d'exclusion :
SRC_CC_EXCLUDE = $(SRC_DIR)/Util/Algo_Integ1D_2.cc
SRC_CC_EXCLUDE += $(SRC_DIR)/Elements/ResRaid_MPI.cc
SRC_CC_EXCLUDE += $(SRC_DIR)/Elements/Mecanique/Triangle/Met_triaMemb.cc
SRC_CC_EXCLUDE += $(SRC_DIR)/Elements/Mecanique/Hexaedre/HexaLMemb.cc
SRC_CC_EXCLUDE += $(SRC_DIR)/Elements/Mecanique/SFE/PoutSfe3.cc
SRC_CC_EXCLUDE += $(SRC_DIR)/Elements/Mecanique/SFE/Sfeg.cc
SRC_CC_EXCLUDE += $(SRC_DIR)/Elements/Mecanique/SFE/Met_Sfe2s2.cc
SRC_CC_EXCLUDE += $(SRC_DIR)/Elements/Mecanique/Biellette/PoutTimo.cc
SRC_CC_EXCLUDE += $(SRC_DIR)/Lecture/LectBloc_T.cc
SRC_CC_EXCLUDE += $(SRC_DIR)/Algo/GalerkinContinu/AlgoMixte/AlgoriMixte.cc
SRC_CC_EXCLUDE += $(SRC_DIR)/Util/externe/quartic.cc
SRC_CC_EXCLUDE += $(SRC_DIR)/References/Lect_reference.cc
SRC_CC_EXCLUDE += $(SRC_DIR)/Resolin/Resolution_Condi/resol.cc
SRC_CC_EXCLUDE += $(SRC_DIR)/Tableaux/Tableau_double.cc
SRC_CC_EXCLUDE += $(SRC_DIR)/General/Distribution_CPU.cc
SRC_CC_EXCLUDE += $(SRC_DIR)/comportement/Hyper_elastique/Hyper10.cc
SRC_CC_EXCLUDE += $(SRC_DIR)/comportement/Hyper_elastique/HyperDN.cc
SRC_CC_EXCLUDE += lib_ex_pour_HZpp/Partie_2/algebre_lineaire/sparselib
+/sp1_5c/src/qsort_type.cc
SRC_CC_EXCLUDE = lib_ex_pour_HZpp/Partie_2/algebre_lineaire/sparselib+/sp1_5c/src/icpre.cc
SRC_CC_EXCLUDE = lib_ex_pour_HZpp/Partie_2/algebre_lineaire/sparselib+/sp1_5c/src/diagpre.cc
SRC_CC_EXCLUDE = lib_ex_pour_HZpp/Partie_2/algebre_lineaire/sparselib+/sp1_5c/src/ilupre.cc
SRC_CC_EXCLUDE = lib_ex_pour_HZpp/Partie_2/algebre_lineaire/sparselib+/sp1_5c/src/ilupre_1.5.cc
SRC_CC_EXCLUDE = lib_ex_pour_HZpp/Partie_2/algebre_lineaire/sparselib+/sp1_5c/src/ilupre_double_1.5.cc
SRC_CC_EXCLUDE = lib_ex_pour_HZpp/Partie_2/algebre_lineaire/sparselib+/sp1_5c/src/ilupre_double.cc
SRC_CC_EXCLUDE = lib_ex_pour_HZpp/Partie_2/algebre_lineaire/sparselib+/sp1_5c/src/diagpre_double.cc
SRC_CC_EXCLUDE = lib_ex_pour_HZpp/Partie_2/algebre_lineaire/sparselib+/sp1_5c/src/icpre_double.cc

A noter que le fichier Elements/Mecanique/Triangle/Met_triaMemb.cc est très bizarre. On dirait un fichier venant de Windows avec des retour chariot <CR>. Le plus bizarre est qu'il est impossible de le lire avec un programme Perl.

3) Pour compléter le point 2), j'exclue également le répertoire Herezh_dev/Util/suites/.

Cette fois, je le fais de manière plus brutale. J'efface tout simplement (rm -rf) ce répertoire de Herezh_dev/ avant de lancer make.
En attendant de modifier mon makefile pour juste l'exclure.

Je suis également obligé de dupliquer le fichier Herezh_dev/Enumeration/Enum_suite.h en Herezh_dev/Enumeration/Enum_Suite.h. En fait, selon les endroits du code, il est parfois demandé sous la forme d'un #include Enum_Suite.h et parfois #include Enum_suite.h. Il faut donc une version avec et sans S majuscules.

4) J'en arrive à la vraie erreur qui me pose problème venant du fichier Herezh_dev/Elements/Mecanique/Deformation_gene/Deformation_2.cc

La compilation de ce fichier se déroule a priori correctement. Mais au moment de générer l'exécutable, j'ai une erreur avec le .o généré depuis ce .cc :

/usr/bin/ld : Herezh_dev/Elements/Mecanique/Deformation_gene/Deformation_2.o : dans la fonction « Deformation::Mise_a_jour_def_log(int, TenseurBB const&, TenseurHH const&, TenseurBB const&, TenseurHH const&) » :
Deformation_2.cc:(.text+0x353e) : référence indéfinie vers « Deformation::Cal_var_Logarithmique(TenseurBB const&, TenseurHH const&, TenseurBB const&, TenseurHH const&) »
/usr/bin/ld : Deformation_2.cc:(.text+0x355e) : référence indéfinie vers « Deformation::Cal_var_Logarithmique(TenseurBB const&, TenseurHH const&, TenseurBB const&, TenseurHH const&) »

Donc, un pb avec la méthode Cal_var_Logarithmique qui est utilisée à la fin du fichier Deformation_2.cc :


       switch (inter_pour_def_log->situation)
        { case 0:
            Cal_Logarithmique(gijBB_0,gijHH_0,gijBB,gijHH,variation_epsBB);
            if (!variation_epsBB) {inter_pour_def_log->situation = 1;}
            else                  {inter_pour_def_log->situation = 3;}
              break;
          case 1:
            // calcul éventuelle d'uniquement de la variation
            if (variation_epsBB)
              {Cal_var_Logarithmique (gijBB_0,gijHH_0,gijBB,gijHH);
               inter_pour_def_log->situation = 3;
              };
            break;
          case 2:
            // calcul éventuelle d'uniquement de la variation
            if (variation_epsBB)
              {Cal_var_Logarithmique (gijBB_0,gijHH_0,gijBB,gijHH);
               inter_pour_def_log->situation = 4;
              };
            break;
        };

Cette méthode est présente Herezh_dev/Elements/Mecanique/Deformation_gene/Deformation_2.h :

   // méthode qui calcule uniquement la variation du  tenseur logarithmique  par rapport aux déformations d'Almansi eps_{mn}
   // dHHHH_eHH_epsBB = d_e^{ij}/d_eps_{mn}
   // le calcul du tenseur lui-même doit déjà avoir été fait
   void Cal_var_Logarithmique (const TenseurBB & gijBB_0,const TenseurHH& gijHH_0
                           ,const TenseurBB& gijBB,const TenseurHH& gijHH);

Mais elle est seulement déclarée là sans être implémentée dans Deformation.cc.

J'ai réussi à supprimer cette erreur de compilation en commentant l'appel à Cal_var_Logarithmique dans Deformation_2.cc.
J'obtiens donc un exécutable HZppfast, mais on dirait qu'il manque quelque chose dans ces fichiers Deformation*.h et .cc

Autre point curieux :
La méthode Cal_Logarithmique est également appelée dans Deformation_2.cc (cf extrait du code dans le "case 0"). Il n'y a pas de pb de compilation mais je trouve étrange car on se retrouve dans la même config que Cal_var_Logarithmique.
Cette méthode est simplement déclarée dans le .h :

                      
   // méthode qui calcule le tenseur logarithmique "e" et sa variation éventuelle par rapport aux déformations d'Almansi eps_{mn}
   // dHHHH_eHH_epsBB = d_e^{ij}/d_eps_{mn}
   void Cal_Logarithmique (const TenseurBB & gijBB_0,const TenseurHH& gijHH_0
                           ,const TenseurBB& gijBB,const TenseurHH& gijHH
                           ,const bool variation_epsBB);

et n'est pas implémentée dans le .cc. Et pourtant pas d'erreur de compilation. Si je cherche cette fonction dans les sources d'Herezh, il se trouve qu'elle existe également dans Herezh_dev/Elements/Mecanique/Deformation_gene/Deformation_log.cc :

    // fonction qui calcule le tenseur logarithmique et sa variation éventuelle
    // par rapport aux ddl
void Deformation::Cal_Logarithmique 
                     (const TenseurBB & gijBB_0,const TenseurHH& _gijHH_0,Tableau <TenseurBB *> & d_epsBB
                      ,const TenseurBB& _gijBB,const TenseurHH& _gijHH,TenseurBB & _epsBB
                      ,const Tableau <TenseurBB *>& _d_gijBB,bool variation)
{// dimensions                                                     
 int dima = gijBB_0.Dimension(); // dimension des tenseurs
etc...

donc a priori, c'est là qu'il va la chercher. Je ne comprends pas le fonctionnement des divers fichiers Deformation* du répertoire Elements/Mecanique/Deformation. Le fichier Deformation_log.cc n'a pas de .h et il définit une fonction Deformation::Cal_Logarithmique que Deformation_2.cc est capable de trouver malgré aucun appel à quelque chose du genre #include Deformation_log.h en début de fichier Deformation_2.cc.

Au final, comme je compile chaque objet avec tous les rép -I dans gcc, j'ai l'impression que Deformation_2.o arrive quand même à trouver une référence vers Deformation::Cal_Logarithmique car elle existe dans Deformation_log.cc tout en étant déclarée dans Deformation.h.

Mais ce n'est pas le cas de Cal_var_Logarithmique qui est une méthode qui n'apparait nulle part ailleurs que Deformation.h.

Mis à jour par Julien Troufflard il y a 20 jours

dernière info :

j'arrive à compiler un exécutable qui fonctionne sur un exemple. Mais le calcul se termine systématiquement par un segmentation fault. Aucune idée de comment résoudre ça. J'ai retenter une compilation en ne gardant que les fichiers .cc présent dans un makefile de Herezh_dev. Sans amélioration

Mis à jour par Gérard Rio il y a 20 jours

  • % réalisé changé de 0 à 20

- Concernant le bug, est-ce que tu as déjà un .CVisu ? car dans ma version actuelle (7.062) j'ai corrigé un bug dans le cas d'une sortie au fil du calcul lorsque le CVisu n'existait pas

- effectivement il faut retirer -D__cplusplus=1, Mais je pensais que c'était le cas, car j'avais eu le même pb sur le cluster ?? donc à faire ...

- dans le makefile il y a tous les fichiers et répertoires: c'était plus facile pour moi, car j'ai de nombreux autres fichiers d'essais que je garde, mais qui ne sont pas utilisés actuellement. Donc effectivement, 2 possibilités: soit mettre des exclude ou soit mettre ceux que l'on veut garder.

- effectivement le makefile MPI doit-être le plus récent

- Elements/Mecanique/Triangle/Met_triaMemb.cc avec encodage Windows ... a regarder

- dans mon cas sur osX avec xcode, si une méthode n'est pas utilisée, le compilateur n'intègre pas le contenu de la méthode, enfin c'est en générale le cas (pas toujours). Et j'ai commenté et inactivé du code relatif à la mesure log, au moment où j'ai commencé à travailler sur #397 , d'après ton retour j'ai sans doute été un peu rapide. De toute manière aussitôt que je vais revenir sur la mesure log, je vais décommenter pas mal de choses. Donc il faut voir cette partie comme transitoire et si tu trouves une astuce pour que l'édition de lien fonctionne c'est ok pour l'instant (il ne faut pas utiliser la mesure log évidemment)

Mis à jour par Julien Troufflard il y a 18 jours

oui, j'ai un .CVisu. J'ai réessayé en prenant une version antérieure aux modifs de sortie différenciées. J'ai compilé une version 7.058 mais toujours la même erreur à la fin :

======================================================================
INCREMENT DE CHARGE : 119  intensite 1.00000000  t= 1.00000000 dt= 0.00040202
======================================================================
       >>>> temps fin (1.00000000) atteint <<<<< 1.00000000

 temps_user:0/00:00:00.90 system:0/00:00:00.29 reel:0/00:00:00.78

 =============================================================
 |                     fin HEREZH++                          |
 =============================================================
Incident de segmentation (core dumped)

J'ai bien peur que le problème vienne de mon côté.

Je vais faire d'autres tentatives en reprenant plus fidèlement ton makefile. Notamment, je n'ai repris exactement la fin (que je ne comprends pas trop) :


# partie pour fabriquer les dependances "http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/" 

DEPDIR := $(REP_OBJET)/.d
$(shell mkdir -p $(DEPDIR) >/dev/null)
DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td
COMPILE.cc = $(CC) $(DEPFLAGS) $(CC_OPTIONS)  -c
POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d

%.o: %.cc    $(DEPDIR)/%.d
                                $(CC) $(DEPFLAGS) $(CC_OPTIONS) $(INCLUDE) -o $(REP_OBJET)/$@ -c $< 
                                $(POSTCOMPILE)

listes_SRC:
    echo $(LISTE_DE_CC) $(SRC) $(LISTE_DE_DEPEND) $(VPATH)

listes_path:
    $(VPATH) $(vpath)    

liste_INCLUDE:
    echo $(INCLUDE) 

#total_dependance = $(patsubst %,$(DEPDIR)/%,$(dependance))    
liste_total_depend:
    @echo  $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRC))) 
    #$(total_dependance) 

liste_objet:
    @echo $(OBJ)    

liste_objet_pre:
    @echo $(P_OBJ)

# .PRECIOUS: suivi d'une cible, indique que la cible ne doit pas être détruite
# si le make plante !, cela permet de concerver les dépendances déjà construite
$(DEPDIR)/%.d: ;
.PRECIOUS: $(DEPDIR)/%.d

# -include : veut dire d'inclure la suite, avec le moins cela indique que si la suite
# n'existe pas, il n'y a pas de pb généré
# patsubst -> veut dire substituer : l'expression régulière qui suit
# $(basename $(SRCS)) : le nom de base sans le .quelquechose c-a-d ici sans le .cc
# %,$(DEPDIR)/%.d, $(chose)  -> remplace un nom de $(chose) par $(DEPDIR)/<le nom>.d
# donc si je comprends bien la ligne
# on inclue tous les fichiers  makefile situés en  $(DEPDIR)/
# normalement le make fait toutes ses inclusions à la fin de sa lecture
-include $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRC)))

J'utilise une version allégée de tes DEPFLAGS en ne prenant que les options -MMD -MP dans ma compilation gcc. Mais en vrai, je ne pense pas que le problème vienne de là. Si ma méthode posait problème, j'aurais plutôt des pb au moment de la compilation.

Actions

Formats disponibles : Atom PDF

Redmine Appliance - Powered by TurnKey Linux