Python coprocessing example: Difference between revisions
Andy.bauer (talk | contribs) |
Andy.bauer (talk | contribs) |
||
(13 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
This example is used to demonstrate how the | This example is used to demonstrate how the co-processing library can be used with a python based simulation code. Note that this example requires MPI to be available on your system as well as pyMPI to initialize and finalize MPI from the python script. The executable takes in a python co-processing script and a number of time steps to be run for. Note to remember to set your system environment properly. See [[http://paraview.org/Wiki/ParaView/Python_Scripting#Getting_Started]] for details. | ||
== Serial python driver code == | |||
== | |||
<source lang="python"> | <source lang="python"> | ||
import sys | import sys | ||
if len(sys.argv) != 3: | if len(sys.argv) != 3: | ||
print "command is ' | print "command is 'python <python driver code> <script name> <number of time steps>'" | ||
sys.exit(1) | sys.exit(1) | ||
import paraview | import paraview | ||
import paraview.vtk as vtk | import paraview.vtk as vtk | ||
def coProcess(grid, time, step, scriptname): | def coProcess(grid, time, step, scriptname): | ||
import vtkCoProcessorPython # import libvtkCoProcessorPython for older PV versions | import vtkCoProcessorPython # import libvtkCoProcessorPython for older PV versions | ||
if scriptname.endswith(".py"): | if scriptname.endswith(".py"): | ||
scriptname = scriptname.rstrip(".py") | scriptname = scriptname[0:len(scriptname)-3]#scriptname.rstrip(".py") | ||
try: | try: | ||
cpscript = __import__(scriptname) | cpscript = __import__(scriptname) | ||
Line 41: | Line 29: | ||
inputdescription.SetGrid(grid) | inputdescription.SetGrid(grid) | ||
inputdescription.SetWholeExtent(grid.GetWholeExtent()) | |||
cpscript.DoCoProcessing(datadescription) | cpscript.DoCoProcessing(datadescription) | ||
Line 46: | Line 35: | ||
numsteps = int(sys.argv[2]) | numsteps = int(sys.argv[2]) | ||
except ValueError: | except ValueError: | ||
print 'the last argument should be a number' | print 'the last argument should be a number, setting the number of time steps to 10' | ||
numsteps = 10 | numsteps = 10 | ||
for step in range(numsteps): | for step in range(numsteps): | ||
Line 59: | Line 47: | ||
imageData.SetOrigin(0, 0, 0) | imageData.SetOrigin(0, 0, 0) | ||
imageData.SetSpacing(.1, .1, .1) | imageData.SetSpacing(.1, .1, .1) | ||
imageData. | imageData.SetExtent(0, 10, 0, 12, 0, 12) | ||
imageData.SetWholeExtent(imageData.GetExtent()) | |||
pointArray = vtk.vtkDoubleArray() | pointArray = vtk.vtkDoubleArray() | ||
pointArray.SetNumberOfTuples(imageData.GetNumberOfPoints()) | pointArray.SetNumberOfTuples(imageData.GetNumberOfPoints()) | ||
Line 70: | Line 59: | ||
# the passed in script says we should at time/step | # the passed in script says we should at time/step | ||
coProcess(imageData, time, step, sys.argv[1]) | coProcess(imageData, time, step, sys.argv[1]) | ||
</source> | |||
== Parallel python driver code == | |||
<source lang="python"> | |||
import sys | |||
if len(sys.argv) != 3: | |||
print "command is 'mpirun -np <#> pyMPI parallelexample.py <script name> <number of time steps>'" | |||
sys.exit(1) | |||
import paraview | |||
import paraview.vtk as vtk | |||
import mpi | |||
mpi.initialized() | |||
import paraview | |||
import libvtkParallelPython | |||
import paraview.simple | |||
import vtk | |||
# set up ParaView to properly use MPI | |||
pm = paraview.servermanager.vtkProcessModule.GetProcessModule() | |||
globalController = pm.GetGlobalController() | |||
if globalController == None or globalController.IsA("vtkDummyController") == True: | |||
globalController = vtk.vtkMPIController() | |||
globalController.Initialize() | |||
globalController.SetGlobalController(globalController) | |||
def coProcess(grid, simtime, simstep, scriptname): | |||
# the name of the library was changed so for previous version of ParaView | |||
# you have to import libvtkCoProcessorPython instead of vtkCoProcessorPython | |||
#import libvtkCoProcessorPython as vtkCoProcessorPython | |||
import vtkCoProcessorPython | |||
if scriptname.endswith(".py"): | |||
scriptname = scriptname[0:len(scriptname)-3]#scriptname.rstrip(".py") | |||
try: | |||
cpscript = __import__(scriptname) | |||
except: | |||
print 'Cannot find ', scriptname, ' -- no coprocessing will be performed.' | |||
return | |||
datadescription = vtkCoProcessorPython.vtkCPDataDescription() | |||
datadescription.SetTimeData(simtime, simstep) | |||
datadescription.AddInput("input") | |||
cpscript.RequestDataDescription(datadescription) | |||
inputdescription = datadescription.GetInputDescriptionByName("input") | |||
if inputdescription.GetIfGridIsNecessary() == False: | |||
return | |||
import paraview.simple | |||
extents = grid.GetWholeExtent() | |||
inputdescription.SetWholeExtent(extents) | |||
inputdescription.SetGrid(grid) | |||
cpscript.DoCoProcessing(datadescription) | |||
def createGrid(time): | |||
""" | |||
Create a vtkImageData and a point data field called 'pointData'. | |||
time is used to make the field time varying. The grid is | |||
partitioned in slices in the x-direction here but that is | |||
not required. | |||
""" | |||
imageData = vtk.vtkImageData() | |||
imageData.Initialize() | |||
imageData.SetOrigin(0, 0, 0) | |||
imageData.SetSpacing(.1, .1, .1) | |||
imageData.SetWholeExtent(0, 2*mpi.size, 0, 5, 0, 5) | |||
imageData.SetExtent(mpi.rank*2, (mpi.rank+1)*2, 0, 5, 0, 5) | |||
pointArray = vtk.vtkDoubleArray() | |||
pointArray.SetNumberOfTuples(imageData.GetNumberOfPoints()) | |||
for i in range(imageData.GetNumberOfPoints()): | |||
pointArray.SetValue(i, i+time) | |||
pointArray.SetName("pointData") | |||
imageData.GetPointData().AddArray(pointArray) | |||
return imageData | |||
try: | |||
numsteps = int(sys.argv[2]) | |||
except ValueError: | |||
print 'the last argument should be a number, setting the number of time steps to 10' | |||
numsteps = 10 | |||
for step in range(numsteps): | |||
# assume simulation time starts at 0 | |||
time = step/float(numsteps) | |||
# create the input to the coprocessing library. normally | |||
# this will come from the adaptor | |||
grid = createGrid(time) | |||
# "perform" coprocessing. results are outputted only if | |||
# the passed in script says we should at time/step | |||
coProcess(grid, time, step, sys.argv[1]) | |||
globalController.SetGlobalController(None) | |||
globalController = None | |||
mpi.finalized() | mpi.finalized() | ||
</source> | </source> | ||
Line 78: | Line 163: | ||
try: paraview.simple | try: paraview.simple | ||
except: from paraview.simple import * | except: from paraview.simple import * | ||
def RequestDataDescription(datadescription): | def RequestDataDescription(datadescription): | ||
Line 93: | Line 177: | ||
def DoCoProcessing(datadescription): | def DoCoProcessing(datadescription): | ||
"Callback to do co-processing for current timestep" | "Callback to do co-processing for current timestep" | ||
cp_writers = [] | cp_writers = [] | ||
timestep = datadescription.GetTimeStep() | timestep = datadescription.GetTimeStep() | ||
grid = CreateProducer( datadescription, "input" ) | |||
ImageWriter1 = CreateWriter( XMLPImageDataWriter, "input_grid_%t.pvti", 1 ) | ImageWriter1 = CreateWriter( XMLPImageDataWriter, "input_grid_%t.pvti", 1, cp_writers ) | ||
for writer in cp_writers: | for writer in cp_writers: | ||
Line 106: | Line 189: | ||
# explicitly delete the proxies -- we do it this way to avoid problems with prototypes | # explicitly delete the proxies -- we do it this way to avoid problems with prototypes | ||
tobedeleted = | tobedeleted = GetNextProxyToDelete() | ||
while | while tobedeleted != None: | ||
Delete(tobedeleted | Delete(tobedeleted) | ||
tobedeleted = | tobedeleted = GetNextProxyToDelete() | ||
return | def GetNextProxyToDelete(): | ||
proxyiterator = servermanager.ProxyIterator() | |||
for proxy in proxyiterator: | |||
group = proxyiterator.GetGroup() | |||
if group.find("prototypes") != -1: | |||
continue | |||
if group != 'timekeeper' and group.find("pq_helper_proxies") == -1 : | |||
return proxy | |||
return None | |||
def CreateProducer(datadescription, gridname): | def CreateProducer(datadescription, gridname): | ||
"Creates a producer proxy for the grid" | |||
if not datadescription.GetInputDescriptionByName(gridname): | |||
raise RuntimeError, "Simulation input name '%s' does not exist" % gridname | |||
grid = datadescription.GetInputDescriptionByName(gridname).GetGrid() | |||
producer = PVTrivialProducer() | |||
producer.GetClientSideObject().SetOutput(grid) | |||
if grid.IsA("vtkImageData") == True or grid.IsA("vtkStructuredGrid") == True or grid.IsA("vtkRectilinearGrid") == True: | |||
extent = datadescription.GetInputDescriptionByName(gridname).GetWholeExtent() | |||
producer.WholeExtent= [ extent[0], extent[1], extent[2], extent[3], extent[4], extent[5] ] | |||
producer.UpdatePipeline() | |||
return producer | |||
def CreateWriter(proxy_ctor, filename, freq): | def CreateWriter(proxy_ctor, filename, freq, cp_writers): | ||
writer = proxy_ctor() | writer = proxy_ctor() | ||
writer.FileName = filename | writer.FileName = filename |
Latest revision as of 19:33, 10 February 2012
This example is used to demonstrate how the co-processing library can be used with a python based simulation code. Note that this example requires MPI to be available on your system as well as pyMPI to initialize and finalize MPI from the python script. The executable takes in a python co-processing script and a number of time steps to be run for. Note to remember to set your system environment properly. See [[1]] for details.
Serial python driver code
<source lang="python"> import sys if len(sys.argv) != 3:
print "command is 'python <python driver code> <script name> <number of time steps>'" sys.exit(1)
import paraview import paraview.vtk as vtk
def coProcess(grid, time, step, scriptname):
import vtkCoProcessorPython # import libvtkCoProcessorPython for older PV versions if scriptname.endswith(".py"): scriptname = scriptname[0:len(scriptname)-3]#scriptname.rstrip(".py") try: cpscript = __import__(scriptname) except: print 'Cannot find ', scriptname, ' -- no coprocessing will be performed.' return
datadescription = vtkCoProcessorPython.vtkCPDataDescription() datadescription.SetTimeData(time, step) datadescription.AddInput("input") cpscript.RequestDataDescription(datadescription) inputdescription = datadescription.GetInputDescriptionByName("input") if inputdescription.GetIfGridIsNecessary() == False: return
inputdescription.SetGrid(grid) inputdescription.SetWholeExtent(grid.GetWholeExtent()) cpscript.DoCoProcessing(datadescription)
try:
numsteps = int(sys.argv[2])
except ValueError:
print 'the last argument should be a number, setting the number of time steps to 10' numsteps = 10
for step in range(numsteps):
# assume simulation time starts at 0 time = step/float(numsteps)
# create the input to the coprocessing library. normally # this will come from the adaptor imageData = vtk.vtkImageData() imageData.SetOrigin(0, 0, 0) imageData.SetSpacing(.1, .1, .1) imageData.SetExtent(0, 10, 0, 12, 0, 12) imageData.SetWholeExtent(imageData.GetExtent()) pointArray = vtk.vtkDoubleArray() pointArray.SetNumberOfTuples(imageData.GetNumberOfPoints()) for i in range(imageData.GetNumberOfPoints()): pointArray.SetValue(i, i) pointArray.SetName("pointData") imageData.GetPointData().AddArray(pointArray)
# "perform" coprocessing. results are outputted only if # the passed in script says we should at time/step coProcess(imageData, time, step, sys.argv[1])
</source>
Parallel python driver code
<source lang="python"> import sys if len(sys.argv) != 3:
print "command is 'mpirun -np <#> pyMPI parallelexample.py <script name> <number of time steps>'" sys.exit(1)
import paraview import paraview.vtk as vtk
import mpi mpi.initialized()
import paraview import libvtkParallelPython import paraview.simple import vtk
- set up ParaView to properly use MPI
pm = paraview.servermanager.vtkProcessModule.GetProcessModule() globalController = pm.GetGlobalController() if globalController == None or globalController.IsA("vtkDummyController") == True:
globalController = vtk.vtkMPIController() globalController.Initialize() globalController.SetGlobalController(globalController)
def coProcess(grid, simtime, simstep, scriptname):
# the name of the library was changed so for previous version of ParaView # you have to import libvtkCoProcessorPython instead of vtkCoProcessorPython #import libvtkCoProcessorPython as vtkCoProcessorPython import vtkCoProcessorPython if scriptname.endswith(".py"): scriptname = scriptname[0:len(scriptname)-3]#scriptname.rstrip(".py") try: cpscript = __import__(scriptname) except: print 'Cannot find ', scriptname, ' -- no coprocessing will be performed.' return
datadescription = vtkCoProcessorPython.vtkCPDataDescription() datadescription.SetTimeData(simtime, simstep) datadescription.AddInput("input") cpscript.RequestDataDescription(datadescription) inputdescription = datadescription.GetInputDescriptionByName("input") if inputdescription.GetIfGridIsNecessary() == False: return import paraview.simple extents = grid.GetWholeExtent() inputdescription.SetWholeExtent(extents) inputdescription.SetGrid(grid) cpscript.DoCoProcessing(datadescription)
def createGrid(time):
""" Create a vtkImageData and a point data field called 'pointData'. time is used to make the field time varying. The grid is partitioned in slices in the x-direction here but that is not required. """ imageData = vtk.vtkImageData() imageData.Initialize() imageData.SetOrigin(0, 0, 0) imageData.SetSpacing(.1, .1, .1) imageData.SetWholeExtent(0, 2*mpi.size, 0, 5, 0, 5) imageData.SetExtent(mpi.rank*2, (mpi.rank+1)*2, 0, 5, 0, 5) pointArray = vtk.vtkDoubleArray() pointArray.SetNumberOfTuples(imageData.GetNumberOfPoints()) for i in range(imageData.GetNumberOfPoints()): pointArray.SetValue(i, i+time) pointArray.SetName("pointData") imageData.GetPointData().AddArray(pointArray)
return imageData
try:
numsteps = int(sys.argv[2])
except ValueError:
print 'the last argument should be a number, setting the number of time steps to 10' numsteps = 10
for step in range(numsteps):
# assume simulation time starts at 0 time = step/float(numsteps)
# create the input to the coprocessing library. normally # this will come from the adaptor grid = createGrid(time)
# "perform" coprocessing. results are outputted only if # the passed in script says we should at time/step coProcess(grid, time, step, sys.argv[1])
globalController.SetGlobalController(None)
globalController = None
mpi.finalized()
</source>
Sample coprocessing script
<source lang="python"> try: paraview.simple except: from paraview.simple import *
def RequestDataDescription(datadescription):
"Callback to populate the request for current timestep" timestep = datadescription.GetTimeStep() input_name = 'input' if (timestep % 1 == 0) : datadescription.GetInputDescriptionByName(input_name).AllFieldsOn() datadescription.GetInputDescriptionByName(input_name).GenerateMeshOn() else: datadescription.GetInputDescriptionByName(input_name).AllFieldsOff() datadescription.GetInputDescriptionByName(input_name).GenerateMeshOff()
def DoCoProcessing(datadescription):
"Callback to do co-processing for current timestep" cp_writers = [] timestep = datadescription.GetTimeStep()
grid = CreateProducer( datadescription, "input" ) ImageWriter1 = CreateWriter( XMLPImageDataWriter, "input_grid_%t.pvti", 1, cp_writers )
for writer in cp_writers: if timestep % writer.cpFrequency == 0: writer.FileName = writer.cpFileName.replace("%t", str(timestep)) writer.UpdatePipeline()
# explicitly delete the proxies -- we do it this way to avoid problems with prototypes tobedeleted = GetNextProxyToDelete() while tobedeleted != None: Delete(tobedeleted) tobedeleted = GetNextProxyToDelete()
def GetNextProxyToDelete():
proxyiterator = servermanager.ProxyIterator() for proxy in proxyiterator: group = proxyiterator.GetGroup() if group.find("prototypes") != -1: continue if group != 'timekeeper' and group.find("pq_helper_proxies") == -1 : return proxy return None
def CreateProducer(datadescription, gridname):
"Creates a producer proxy for the grid" if not datadescription.GetInputDescriptionByName(gridname): raise RuntimeError, "Simulation input name '%s' does not exist" % gridname grid = datadescription.GetInputDescriptionByName(gridname).GetGrid() producer = PVTrivialProducer() producer.GetClientSideObject().SetOutput(grid) if grid.IsA("vtkImageData") == True or grid.IsA("vtkStructuredGrid") == True or grid.IsA("vtkRectilinearGrid") == True: extent = datadescription.GetInputDescriptionByName(gridname).GetWholeExtent() producer.WholeExtent= [ extent[0], extent[1], extent[2], extent[3], extent[4], extent[5] ] producer.UpdatePipeline() return producer
def CreateWriter(proxy_ctor, filename, freq, cp_writers):
writer = proxy_ctor() writer.FileName = filename writer.add_attribute("cpFrequency", freq) writer.add_attribute("cpFileName", filename) cp_writers.append(writer) return writer
</source>