logbase.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. """
  2. This module has utilities to benchmark paraview.
  3. You can set up arbitrary pipelines and this module helps you obtain,
  4. interpret and report the information recorded by ParaView's logs.
  5. Do that like so:
  6. 1. Optionally, call maximize logs first
  7. 2. Setup and run your visualization pipeline (via GUI or script as you prefer)
  8. 3. Call print_logs() to print out the logs in raw format
  9. """
  10. from __future__ import print_function
  11. from paraview.simple import *
  12. import paraview
  13. start_frame = 0
  14. default_log_threshold = dict()
  15. def component_to_string(comp):
  16. session = servermanager.ProxyManager().GetSessionProxyManager().GetSession()
  17. if comp == session.NONE: return 'None'
  18. if comp == session.DATA_SERVER: return 'DataServer'
  19. if comp == session.DATA_SERVER_ROOT: return 'DataServerRoot'
  20. if comp == session.RENDER_SERVER: return 'RenderServer'
  21. if comp == session.RENDER_SERVER_ROOT: return 'RenderServerRoot'
  22. if comp == session.SERVERS: return 'Servers'
  23. if comp == session.CLIENT: return 'Client'
  24. if comp == session.CLIENT_AND_SERVERS: return 'ClientAndServers'
  25. return None
  26. class OneLog :
  27. def __init__(self, runmode='batch', servertype='unified', component=0, rank=0):
  28. self.runmode = runmode
  29. self.servertype = servertype
  30. self.component = component_to_string(component)
  31. self.rank = rank
  32. self.lines = []
  33. def print_log(self, showlines=False):
  34. print ("#RunMode:", self.runmode, end="")
  35. print ("ServerType:", self.servertype, end="")
  36. print ("Component:", self.component, end="")
  37. print ("processor#:", self.rank)
  38. if showlines:
  39. for i in self.lines:
  40. print (i)
  41. def toString(self, showlines=False):
  42. result = "#RunMode: " + self.runmode + " ServerType: " + self.servertype + " processor#: " + str(self.rank) + "\n"
  43. if showlines:
  44. for i in self.lines:
  45. result += i + "\n"
  46. return result
  47. logs = []
  48. def maximize_logs () :
  49. """
  50. Convenience method to ask paraview to produce logs with lots of space and
  51. highest resolution.
  52. """
  53. pm = paraview.servermanager.vtkProcessModule.GetProcessModule()
  54. if pm == None:
  55. return
  56. ss = paraview.servermanager.vtkSMSession
  57. for ptype in [ss.CLIENT_AND_SERVERS, ss.CLIENT, ss.SERVERS,
  58. ss.RENDER_SERVER, ss.DATA_SERVER]:
  59. default_log_threshold[str(ptype)] = 0.0
  60. pxm = paraview.servermanager.ProxyManager()
  61. tl = pxm.NewProxy("misc", "TimerLog")
  62. prop = tl.GetProperty("MaxEntries")
  63. prop.SetElements1(1000000)
  64. tl.UpdateVTKObjects()
  65. def get_memuse() :
  66. pm = paraview.servermanager.vtkProcessModule.GetProcessModule()
  67. session = servermanager.ProxyManager().GetSessionProxyManager().GetSession()
  68. retval = []
  69. if pm.GetProcessTypeAsInt() == pm.PROCESS_BATCH:
  70. components = {'CL_DS_RS': session.CLIENT_AND_SERVERS}
  71. else:
  72. if session.GetRenderClientMode() == session.RENDERING_UNIFIED:
  73. components = {'CL': session.CLIENT, 'DS_RS': session.SERVERS}
  74. else:
  75. components = {'CL': session.CLIENT, 'RS': session.RENDER_SERVER, 'DS': session.DATA_SERVER}
  76. for comp_label, comp_type in components.items():
  77. infos = servermanager.vtkPVMemoryUseInformation()
  78. session.GatherInformation(comp_type, infos, 0)
  79. for i in range(0,infos.GetSize()):
  80. retval.append('%(l)s[%(r)d] %(pu)d / %(hu)d' %
  81. {'l': comp_label, 'r': infos.GetRank(i),
  82. 'pu': infos.GetProcMemoryUse(i),
  83. 'hu': infos.GetHostMemoryUse(i)})
  84. return retval
  85. def dump_logs( filename ) :
  86. """
  87. This saves off the logs we've gathered.
  88. Ot allows you to run a benchmark somewhere, save off all of the details in
  89. raw format, then load them somewhere else. You can then do a detailed
  90. analysis and you always have the raw data to go back to.
  91. """
  92. import pickle
  93. global logs
  94. if sys.version_info < (3,):
  95. f = open(filename, "w")
  96. else:
  97. f = open(filename, "wb")
  98. pickle.dump(logs, f)
  99. f.close()
  100. def import_logs( filename ) :
  101. """
  102. This is for bringing in a saved log files and parse it after the fact.
  103. TODO: add an option to load in raw paraview logs in text format
  104. """
  105. import pickle
  106. global logs
  107. logs = []
  108. if sys.version_info < (3,):
  109. f = open(filename, "r")
  110. else:
  111. f = open(filename, "rb")
  112. logs = pickle.load(f)
  113. f.close()
  114. def get_logs() :
  115. """
  116. This is for bringing in logs at run time to parse while running.
  117. """
  118. global logs
  119. logs = []
  120. pm = paraview.servermanager.vtkProcessModule.GetProcessModule()
  121. if pm == None:
  122. return
  123. connectionId = paraview.servermanager.ActiveConnection.ID
  124. session = paraview.servermanager.ActiveConnection.Session
  125. is_symmetric_mode = False
  126. if pm.GetProcessTypeAsInt() == pm.PROCESS_BATCH:
  127. runmode = 'batch'
  128. is_symmetric_mode = pm.GetSymmetricMPIMode()
  129. else:
  130. runmode = 'interactive'
  131. if session.GetRenderClientMode() == session.RENDERING_UNIFIED:
  132. servertype = 'unified'
  133. else:
  134. servertype = 'split'
  135. if runmode == 'batch':
  136. # collect information from all processes in one go.
  137. components = [session.CLIENT_AND_SERVERS]
  138. else:
  139. if servertype == 'unified':
  140. # collect information separately for client and servers.
  141. components = [session.CLIENT, session.SERVERS]
  142. else:
  143. # collect information separately for all process types.
  144. components = [session.CLIENT, session.RENDER_SERVER, session.DATA_SERVER]
  145. for component in components:
  146. timerInfo = paraview.servermanager.vtkPVTimerInformation()
  147. if len(default_log_threshold) != 0:
  148. timerInfo.SetLogThreshold(default_log_threshold[str(component)])
  149. session.GatherInformation(component, timerInfo, 0)
  150. for i in range(timerInfo.GetNumberOfLogs()):
  151. alog = OneLog(runmode, servertype, component, i)
  152. if is_symmetric_mode:
  153. # in Symmetric mode, GatherInformation() only collects
  154. # information from the current node. so the
  155. # vtkPVTimerInformation will only have info for local process.
  156. alog.rank = pm.GetPartitionId()
  157. alog.lines = timerInfo.GetLog(i).split('\n');
  158. logs.append(alog)
  159. def print_logs() :
  160. """
  161. Print logs on the root node by gathering logs across all the nodes
  162. regardless if the process was started in symmetric mode or not.
  163. """
  164. global logs
  165. if len(logs) == 0:
  166. get_logs()
  167. # Handle symmetric mode specifically if need be
  168. pm = paraview.servermanager.vtkProcessModule.GetProcessModule()
  169. is_symmetric_mode = False
  170. if pm != None:
  171. is_symmetric_mode = pm.GetSymmetricMPIMode()
  172. if is_symmetric_mode:
  173. # Need to provide extra synchronization
  174. ctrl = pm.GetGlobalController()
  175. proc = pm.GetPartitionId()
  176. nbProc = pm.GetNumberOfLocalPartitions()
  177. if proc == 0:
  178. # Start with my logs
  179. for i in logs:
  180. i.print_log(True)
  181. # Then Print the log of every other rank
  182. for otherProc in range(1, nbProc):
  183. # Max buffer size 999999
  184. logSize = " " * 6
  185. ctrl.Receive(logSize, len(logSize), otherProc, 987455)
  186. logSize = int(logSize)
  187. logTxt = " " * logSize
  188. ctrl.Receive(logTxt, logSize, otherProc, 987456)
  189. print (logTxt)
  190. else:
  191. # Extract logs text
  192. logTxt = ""
  193. for i in logs:
  194. logTxt += i.toString(True)
  195. logSize = str(len(logTxt))
  196. # Push local logs to process 0
  197. ctrl.Send(logSize, len(logSize), 0, 987455)
  198. ctrl.Send(logTxt, len(logTxt), 0, 987456)
  199. else:
  200. # Regular local print
  201. for i in logs:
  202. i.print_log(True)
  203. def test_module():
  204. """Simply exercises a few components of the module."""
  205. maximize_logs()
  206. paraview.servermanager.SetProgressPrintingEnabled(0)
  207. ss = Sphere(ThetaResolution=1000, PhiResolution=500)
  208. rep = Show()
  209. v = Render()
  210. print_logs()
  211. if __name__ == "__main__":
  212. test_module()