]> SALOME platform Git repositories - modules/adao.git/blob - src/daComposant/daCore/PlatformInfo.py
Salome HOME
Improving process memory measures
[modules/adao.git] / src / daComposant / daCore / PlatformInfo.py
1 #-*-coding:iso-8859-1-*-
2 #
3 # Copyright (C) 2008-2013 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 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     #
140     def _VmA(self, VmKey, unit):
141         try:
142             t = open(self._memo_status)
143             v = t.read()
144             t.close()
145         except:
146             return 0.0           # non-Linux?
147         i = v.index(VmKey)       # get VmKey line e.g. 'VmRSS:  9999  kB\n ...'
148         v = v[i:].split(None, 3) # whitespace
149         if len(v) < 3:
150             return 0.0           # invalid format?
151         # convert Vm value to bytes
152         mem = float(v[1]) * self._scale[v[2]]
153         return mem / self._scale[unit]
154     #
155     def getAvailablePhysicalMemory(self, unit="o"):
156         "Renvoie la mémoire physique utilisable en octets"
157         return self._VmA('MemTotal:', unit)
158     #
159     def getAvailableSwapMemory(self, unit="o"):
160         "Renvoie la mémoire swap utilisable en octets"
161         return self._VmA('SwapTotal:', unit)
162     #
163     def getAvailableMemory(self, unit="o"):
164         "Renvoie la mémoire totale (physique+swap) utilisable en octets"
165         return self._VmA('MemTotal:', unit) + self._VmA('SwapTotal:', unit)
166     #
167     def getUsableMemory(self, unit="o"):
168         """Renvoie la mémoire utilisable en octets
169         Rq : il n'est pas sûr que ce décompte soit juste...
170         """
171         return self._VmA('MemFree:', unit) + self._VmA('SwapFree:', unit) + \
172                self._VmA('Cached:', unit) + self._VmA('SwapCached:', unit)
173     #
174     def _VmB(self, VmKey, unit):
175         try:
176             t = open(self._proc_status)
177             v = t.read()
178             t.close()
179         except:
180             return 0.0           # non-Linux?
181         i = v.index(VmKey)       # get VmKey line e.g. 'VmRSS:  9999  kB\n ...'
182         v = v[i:].split(None, 3) # whitespace
183         if len(v) < 3:
184             return 0.0           # invalid format?
185         # convert Vm value to bytes
186         mem = float(v[1]) * self._scale[v[2]]
187         return mem / self._scale[unit]
188     #
189     def getUsedMemory(self, unit="o"):
190         "Renvoie la mémoire résidente utilisée en octets"
191         return self._VmB('VmRSS:', unit)
192     #
193     def getVirtualMemory(self, unit="o"):
194         "Renvoie la mémoire totale utilisée en octets"
195         return self._VmB('VmSize:', unit)
196     #
197     def getUsedStacksize(self, unit="o"):
198         "Renvoie la taille du stack utilisé en octets"
199         return self._VmB('VmStk:', unit)
200     #
201     def getMaxUsedMemory(self, unit="o"):
202         "Renvoie la mémoire résidente maximale mesurée"
203         return self._VmB('VmHWM:', unit)
204     #
205     def getMaxVirtualMemory(self, unit="o"):
206         "Renvoie la mémoire totale maximale mesurée"
207         return self._VmB('VmPeak:', unit)
208
209 # ==============================================================================
210 if __name__ == "__main__":
211     print '\n AUTODIAGNOSTIC \n'
212
213     print PlatformInfo()
214     print
215     p = PlatformInfo()
216     print "Les caractéristiques détaillées des applications et outils sont :"
217     print "  - Application.......:",p.getName()
218     print "  - Version...........:",p.getVersion()
219     print "  - Date Application..:",p.getDate()
220     print "  - Python............:",p.getPythonVersion()
221     print "  - Numpy.............:",p.getNumpyVersion()
222     print "  - Scipy.............:",p.getScipyVersion()
223     print
224     
225     p = PathManagement()
226     print "Les chemins ajoutés au système pour des outils :"
227     for k,v in p.getpaths().items():
228         print "  %12s : %s"%(k,os.path.basename(v))
229     print
230
231     m = SystemUsage()
232     print "La mémoire disponible est la suivante :"
233     print "  - mémoire totale....: %4.1f Mo"%m.getAvailableMemory("Mo")
234     print "  - mémoire physique..: %4.1f Mo"%m.getAvailablePhysicalMemory("Mo")
235     print "  - mémoire swap......: %4.1f Mo"%m.getAvailableSwapMemory("Mo")
236     print "  - utilisable........: %4.1f Mo"%m.getUsableMemory("Mo")
237     print "L'usage mémoire de cette exécution est le suivant :"
238     print "  - mémoire résidente.: %4.1f Mo"%m.getUsedMemory("Mo")
239     print "  - mémoire virtuelle.: %4.1f Mo"%m.getVirtualMemory("Mo")
240     print "  - taille de stack...: %4.1f Mo"%m.getUsedStacksize("Mo")
241     print "Création d'un objet range(1000000) et mesure mémoire"
242     x = range(1000000)
243     print "  - mémoire totale....: %4.1f Mo"%m.getUsedMemory("Mo")
244     print "Destruction de l'objet et mesure mémoire"
245     del x
246     print "  - mémoire totale....: %4.1f Mo"%m.getUsedMemory("Mo")
247     print "L'usage mémoire maximal de cette exécution est le suivant :"
248     print "  - mémoire résidente.: %4.1f Mo"%m.getMaxUsedMemory("Mo")
249     print "  - mémoire virtuelle.: %4.1f Mo"%m.getMaxVirtualMemory("Mo")
250     print