123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- """
- This module has utilities to benchmark paraview.
- You can set up arbitrary pipelines and this module helps you obtain,
- interpret and report the information recorded by ParaView's logs.
- Do that like so:
- 1. Optionally, call maximize logs first
- 2. Setup and run your visualization pipeline (via GUI or script as you prefer)
- 3. Call print_logs() to print out the logs in raw format
- """
- from __future__ import print_function
- from paraview.simple import *
- import paraview
- start_frame = 0
- default_log_threshold = dict()
- def component_to_string(comp):
- session = servermanager.ProxyManager().GetSessionProxyManager().GetSession()
- if comp == session.NONE: return 'None'
- if comp == session.DATA_SERVER: return 'DataServer'
- if comp == session.DATA_SERVER_ROOT: return 'DataServerRoot'
- if comp == session.RENDER_SERVER: return 'RenderServer'
- if comp == session.RENDER_SERVER_ROOT: return 'RenderServerRoot'
- if comp == session.SERVERS: return 'Servers'
- if comp == session.CLIENT: return 'Client'
- if comp == session.CLIENT_AND_SERVERS: return 'ClientAndServers'
- return None
- class OneLog :
- def __init__(self, runmode='batch', servertype='unified', component=0, rank=0):
- self.runmode = runmode
- self.servertype = servertype
- self.component = component_to_string(component)
- self.rank = rank
- self.lines = []
- def print_log(self, showlines=False):
- print ("#RunMode:", self.runmode, end="")
- print ("ServerType:", self.servertype, end="")
- print ("Component:", self.component, end="")
- print ("processor#:", self.rank)
- if showlines:
- for i in self.lines:
- print (i)
- def toString(self, showlines=False):
- result = "#RunMode: " + self.runmode + " ServerType: " + self.servertype + " processor#: " + str(self.rank) + "\n"
- if showlines:
- for i in self.lines:
- result += i + "\n"
- return result
- logs = []
- def maximize_logs () :
- """
- Convenience method to ask paraview to produce logs with lots of space and
- highest resolution.
- """
- pm = paraview.servermanager.vtkProcessModule.GetProcessModule()
- if pm == None:
- return
- ss = paraview.servermanager.vtkSMSession
- for ptype in [ss.CLIENT_AND_SERVERS, ss.CLIENT, ss.SERVERS,
- ss.RENDER_SERVER, ss.DATA_SERVER]:
- default_log_threshold[str(ptype)] = 0.0
- pxm = paraview.servermanager.ProxyManager()
- tl = pxm.NewProxy("misc", "TimerLog")
- prop = tl.GetProperty("MaxEntries")
- prop.SetElements1(1000000)
- tl.UpdateVTKObjects()
- def get_memuse() :
- pm = paraview.servermanager.vtkProcessModule.GetProcessModule()
- session = servermanager.ProxyManager().GetSessionProxyManager().GetSession()
- retval = []
- if pm.GetProcessTypeAsInt() == pm.PROCESS_BATCH:
- components = {'CL_DS_RS': session.CLIENT_AND_SERVERS}
- else:
- if session.GetRenderClientMode() == session.RENDERING_UNIFIED:
- components = {'CL': session.CLIENT, 'DS_RS': session.SERVERS}
- else:
- components = {'CL': session.CLIENT, 'RS': session.RENDER_SERVER, 'DS': session.DATA_SERVER}
- for comp_label, comp_type in components.items():
- infos = servermanager.vtkPVMemoryUseInformation()
- session.GatherInformation(comp_type, infos, 0)
- for i in range(0,infos.GetSize()):
- retval.append('%(l)s[%(r)d] %(pu)d / %(hu)d' %
- {'l': comp_label, 'r': infos.GetRank(i),
- 'pu': infos.GetProcMemoryUse(i),
- 'hu': infos.GetHostMemoryUse(i)})
- return retval
- def dump_logs( filename ) :
- """
- This saves off the logs we've gathered.
- Ot allows you to run a benchmark somewhere, save off all of the details in
- raw format, then load them somewhere else. You can then do a detailed
- analysis and you always have the raw data to go back to.
- """
- import pickle
- global logs
- if sys.version_info < (3,):
- f = open(filename, "w")
- else:
- f = open(filename, "wb")
- pickle.dump(logs, f)
- f.close()
- def import_logs( filename ) :
- """
- This is for bringing in a saved log files and parse it after the fact.
- TODO: add an option to load in raw paraview logs in text format
- """
- import pickle
- global logs
- logs = []
- if sys.version_info < (3,):
- f = open(filename, "r")
- else:
- f = open(filename, "rb")
- logs = pickle.load(f)
- f.close()
- def get_logs() :
- """
- This is for bringing in logs at run time to parse while running.
- """
- global logs
- logs = []
- pm = paraview.servermanager.vtkProcessModule.GetProcessModule()
- if pm == None:
- return
- connectionId = paraview.servermanager.ActiveConnection.ID
- session = paraview.servermanager.ActiveConnection.Session
- is_symmetric_mode = False
- if pm.GetProcessTypeAsInt() == pm.PROCESS_BATCH:
- runmode = 'batch'
- is_symmetric_mode = pm.GetSymmetricMPIMode()
- else:
- runmode = 'interactive'
- if session.GetRenderClientMode() == session.RENDERING_UNIFIED:
- servertype = 'unified'
- else:
- servertype = 'split'
- if runmode == 'batch':
- # collect information from all processes in one go.
- components = [session.CLIENT_AND_SERVERS]
- else:
- if servertype == 'unified':
- # collect information separately for client and servers.
- components = [session.CLIENT, session.SERVERS]
- else:
- # collect information separately for all process types.
- components = [session.CLIENT, session.RENDER_SERVER, session.DATA_SERVER]
- for component in components:
- timerInfo = paraview.servermanager.vtkPVTimerInformation()
- if len(default_log_threshold) != 0:
- timerInfo.SetLogThreshold(default_log_threshold[str(component)])
- session.GatherInformation(component, timerInfo, 0)
- for i in range(timerInfo.GetNumberOfLogs()):
- alog = OneLog(runmode, servertype, component, i)
- if is_symmetric_mode:
- # in Symmetric mode, GatherInformation() only collects
- # information from the current node. so the
- # vtkPVTimerInformation will only have info for local process.
- alog.rank = pm.GetPartitionId()
- alog.lines = timerInfo.GetLog(i).split('\n');
- logs.append(alog)
- def print_logs() :
- """
- Print logs on the root node by gathering logs across all the nodes
- regardless if the process was started in symmetric mode or not.
- """
- global logs
- if len(logs) == 0:
- get_logs()
- # Handle symmetric mode specifically if need be
- pm = paraview.servermanager.vtkProcessModule.GetProcessModule()
- is_symmetric_mode = False
- if pm != None:
- is_symmetric_mode = pm.GetSymmetricMPIMode()
- if is_symmetric_mode:
- # Need to provide extra synchronization
- ctrl = pm.GetGlobalController()
- proc = pm.GetPartitionId()
- nbProc = pm.GetNumberOfLocalPartitions()
- if proc == 0:
- # Start with my logs
- for i in logs:
- i.print_log(True)
- # Then Print the log of every other rank
- for otherProc in range(1, nbProc):
- # Max buffer size 999999
- logSize = " " * 6
- ctrl.Receive(logSize, len(logSize), otherProc, 987455)
- logSize = int(logSize)
- logTxt = " " * logSize
- ctrl.Receive(logTxt, logSize, otherProc, 987456)
- print (logTxt)
- else:
- # Extract logs text
- logTxt = ""
- for i in logs:
- logTxt += i.toString(True)
- logSize = str(len(logTxt))
- # Push local logs to process 0
- ctrl.Send(logSize, len(logSize), 0, 987455)
- ctrl.Send(logTxt, len(logTxt), 0, 987456)
- else:
- # Regular local print
- for i in logs:
- i.print_log(True)
- def test_module():
- """Simply exercises a few components of the module."""
- maximize_logs()
- paraview.servermanager.SetProgressPrintingEnabled(0)
- ss = Sphere(ThetaResolution=1000, PhiResolution=500)
- rep = Show()
- v = Render()
- print_logs()
- if __name__ == "__main__":
- test_module()
|