Salome HOME
Simplification of naming for memory sizes
[modules/adao.git] / src / daComposant / daCore / PlatformInfo.py
1 #-*-coding:iso-8859-1-*-
2 #
3 #  Copyright (C) 2008-2012 EDF R&D
4 #
5 #  This library is free software; you can redistribute it and/or
6 #  modify it under the terms of the GNU Lesser General Public
7 #  License as published by the Free Software Foundation; either
8 #  version 2.1 of the License.
9 #
10 #  This library is distributed in the hope that it will be useful,
11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 #  Lesser General Public License for more details.
14 #
15 #  You should have received a copy of the GNU Lesser General Public
16 #  License along with this library; if not, write to the Free Software
17 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 #
19 #  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #
21 #  Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
22
23 __doc__ = """
24     Informations sur le code et la plateforme, et mise à jour des chemins
25     
26     La classe "PlatformInfo" permet de récupérer les informations générales sur
27     le code et la plateforme sous forme de strings, ou d'afficher directement
28     les informations disponibles par les méthodes. L'impression directe d'un
29     objet de cette classe affiche les informations minimales. Par exemple :
30         print PlatformInfo()
31         print PlatformInfo().getVersion()
32         created = PlatformInfo().getDate()
33
34     La classe "PathManagement" permet de mettre à jour les chemins système pour
35     ajouter les outils numériques, matrices... On l'utilise en instanciant
36     simplement cette classe, sans meme récupérer d'objet :
37         PathManagement()
38 """
39 __author__ = "Jean-Philippe ARGAUD"
40
41 import os
42
43 # ==============================================================================
44 class PlatformInfo:
45     """
46     Rassemblement des informations sur le code et la plateforme
47     """
48     def getName(self):
49         "Retourne le nom de l'application"
50         import version
51         return version.name
52
53     def getVersion(self):
54         "Retourne le numéro de la version"
55         import version
56         return version.version
57
58     def getDate(self):
59         "Retourne la date de création de la version"
60         import version
61         return version.date
62     
63     def getPythonVersion(self):
64         "Retourne la version de python utilisée"
65         import sys
66         return ".".join(map(str,sys.version_info[0:3]))
67
68     def getNumpyVersion(self):
69         "Retourne la version de numpy utilisée"
70         import numpy.version
71         return numpy.version.version
72
73     def getScipyVersion(self):
74         "Retourne la version de scipy utilisée"
75         import scipy.version
76         return scipy.version.version
77
78     def getCurrentMemorySize(self):
79         "Retourne la taille mémoire courante utilisée"
80         return 1
81
82     def __str__(self):
83         import version
84         return "%s %s (%s)"%(version.name,version.version,version.date)
85
86 # ==============================================================================
87 def uniq(sequence):
88     """
89     Fonction pour rendre unique chaque élément d'une liste, en préservant l'ordre
90     """
91     __seen = set()
92     return [x for x in sequence if x not in __seen and not __seen.add(x)]
93
94 # ==============================================================================
95 class PathManagement:
96     """
97     Mise à jour du path système pour les répertoires d'outils
98     """
99     def __init__(self):
100         import os, sys
101         parent = os.path.abspath(os.path.join(os.path.dirname(__file__),".."))
102         self.__paths = {}
103         self.__paths["daExternals"] = os.path.join(parent,"daExternals")
104         self.__paths["daMatrices"]  = os.path.join(parent,"daMatrices")
105         self.__paths["daNumerics"]  = os.path.join(parent,"daNumerics")
106         #
107         for v in self.__paths.values():
108             sys.path.insert(0, v )
109         #
110         # Conserve en unique exemplaire chaque chemin
111         sys.path = uniq( sys.path )
112         del parent
113
114     def getpaths(self):
115         """
116         Renvoie le dictionnaire des chemins ajoutés
117         """
118         return self.__paths
119
120 # ==============================================================================
121 class SystemUsage:
122     """
123     Permet de récupérer les différentes tailles mémoires du process courant
124     """
125     #
126     # Le module resource renvoie 0 pour les tailles mémoire. On utilise donc
127     # plutôt : http://code.activestate.com/recipes/286222/ et les infos de
128     # http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/en-US/Reference_Guide/s2-proc-meminfo.html
129     #
130     _proc_status = '/proc/%d/status' % os.getpid()
131     _memo_status = '/proc/meminfo'
132     _scale = {
133                       'K' : 1024.0, 'M' : 1024.0*1024.0,
134         'o':     1.0, 'ko': 1024.0, 'mo': 1024.0*1024.0,
135                       'Ko': 1024.0, 'Mo': 1024.0*1024.0,
136         'B':     1.0, 'kB': 1024.0, 'mB': 1024.0*1024.0,
137                       'KB': 1024.0, 'MB': 1024.0*1024.0,
138              }
139     _max_mem = 0
140     _max_rss = 0
141     _max_sta = 0
142     #
143     def _VmA(self, VmKey, unit):
144         try:
145             t = open(self._memo_status)
146             v = t.read()
147             t.close()
148         except:
149             return 0.0           # non-Linux?
150         i = v.index(VmKey)       # get VmKey line e.g. 'VmRSS:  9999  kB\n ...'
151         v = v[i:].split(None, 3) # whitespace
152         if len(v) < 3:
153             return 0.0           # invalid format?
154         # convert Vm value to bytes
155         mem = float(v[1]) * self._scale[v[2]]
156         return mem / self._scale[unit]
157     #
158     def getAvailablePhysicalMemory(self, unit="o"):
159         "Renvoie la mémoire physique utilisable en octets"
160         return self._VmA('MemTotal:', unit)
161     #
162     def getAvailableSwapMemory(self, unit="o"):
163         "Renvoie la mémoire swap utilisable en octets"
164         return self._VmA('SwapTotal:', unit)
165     #
166     def getAvailableMemory(self, unit="o"):
167         "Renvoie la mémoire totale (physique+swap) utilisable en octets"
168         return self._VmA('MemTotal:', unit) + self._VmA('SwapTotal:', unit)
169     #
170     def getUsableMemory(self, unit="o"):
171         """Renvoie la mémoire utilisable en octets
172         Rq : il n'est pas sûr que ce décompte soit juste...
173         """
174         return self._VmA('MemFree:', unit) + self._VmA('SwapFree:', unit) + \
175                self._VmA('Cached:', unit) + self._VmA('SwapCached:', unit)
176     #
177     def _VmB(self, VmKey, unit):
178         try:
179             t = open(self._proc_status)
180             v = t.read()
181             t.close()
182         except:
183             return 0.0           # non-Linux?
184         i = v.index(VmKey)       # get VmKey line e.g. 'VmRSS:  9999  kB\n ...'
185         v = v[i:].split(None, 3) # whitespace
186         if len(v) < 3:
187             return 0.0           # invalid format?
188         # convert Vm value to bytes
189         mem = float(v[1]) * self._scale[v[2]]
190         return mem / self._scale[unit]
191     #
192     def getUsedMemory(self, unit="o"):
193         "Renvoie la mémoire totale utilisée en octets"
194         mem = self._VmB('VmSize:', unit)
195         self._max_mem = max(self._max_mem, mem)
196         return mem
197     #
198     def getUsedResident(self, unit="o"):
199         "Renvoie la mémoire résidente utilisée en octets"
200         mem = self._VmB('VmRSS:', unit)
201         self._max_rss = max(self._max_rss, mem)
202         return mem
203     #
204     def getUsedStacksize(self, unit="o"):
205         "Renvoie la taille du stack utilisé en octets"
206         mem = self._VmB('VmStk:', unit)
207         self._max_sta = max(self._max_sta, mem)
208         return mem
209     #
210     def getMaxUsedMemory(self):
211         "Renvoie la mémoire totale maximale mesurée"
212         return self._max_mem
213     #
214     def getMaxUsedResident(self):
215         "Renvoie la mémoire résidente maximale mesurée"
216         return self._max_rss
217     #
218     def getMaxUsedStacksize(self):
219         "Renvoie la mémoire du stack maximale mesurée"
220         return self._max_sta
221
222 # ==============================================================================
223 if __name__ == "__main__":
224     print '\n AUTODIAGNOSTIC \n'
225
226     print PlatformInfo()
227     print
228     p = PlatformInfo()
229     print "Les caractéristiques détaillées des applications et outils sont :"
230     print "  - Application.......:",p.getName()
231     print "  - Version...........:",p.getVersion()
232     print "  - Date Application..:",p.getDate()
233     print "  - Python............:",p.getPythonVersion()
234     print "  - Numpy.............:",p.getNumpyVersion()
235     print "  - Scipy.............:",p.getScipyVersion()
236     print
237     
238     p = PathManagement()
239     print "Les chemins ajoutés au système pour des outils :"
240     for k,v in p.getpaths().items():
241         print "  %12s : %s"%(k,os.path.basename(v))
242     print
243
244     m = SystemUsage()
245     print "La mémoire disponible est la suivante :"
246     print "  - mémoire totale....: %4.1f Mo"%m.getAvailableMemory("Mo")
247     print "  - mémoire physique..: %4.1f Mo"%m.getAvailablePhysicalMemory("Mo")
248     print "  - mémoire swap......: %4.1f Mo"%m.getAvailableSwapMemory("Mo")
249     print "  - utilisable........: %4.1f Mo"%m.getUsableMemory("Mo")
250     print "L'usage mémoire de cette exécution est le suivant :"
251     print "  - mémoire totale....: %4.1f Mo"%m.getUsedMemory("Mo")
252     print "  - mémoire résidente.: %4.1f Mo"%m.getUsedResident("Mo")
253     print "  - taille de stack...: %4.1f Mo"%m.getUsedStacksize("Mo")
254     print "Création d'un objet range(1000000) et mesure mémoire"
255     x = range(1000000)
256     print "  - mémoire totale....: %4.1f Mo"%m.getUsedMemory("Mo")
257     print "Destruction de l'objet et mesure mémoire"
258     del x
259     print "  - mémoire totale....: %4.1f Mo"%m.getUsedMemory("Mo")
260     print "L'usage mémoire maximal de cette exécution est le suivant :"
261     print "  - mémoire totale....: %4.1f Mo"%m.getMaxUsedMemory()
262     print "  - mémoire résidente.: %4.1f Mo"%m.getMaxUsedResident()
263     print "  - taille de stack...: %4.1f Mo"%m.getMaxUsedStacksize()
264     print