Difference between revisions of "Python coprocessing example"

From KitwarePublic
Jump to: navigation, search
m (Python driver code)
(Sample coprocessing script)
 
(7 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
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.  
 
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 ==
== 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 'pyMPI <python driver code> <script name> <number of time steps>'"
+
     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
 
# initialize and read input parameters
 
paraview.options.batch = True
 
paraview.options.symmetric = True
 
  
 
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 34: Line 29:
  
 
     inputdescription.SetGrid(grid)
 
     inputdescription.SetGrid(grid)
 +
    inputdescription.SetWholeExtent(grid.GetWholeExtent())
 
     cpscript.DoCoProcessing(datadescription)
 
     cpscript.DoCoProcessing(datadescription)
  
Line 41: Line 37:
 
     print 'the last argument should be a number, setting the number of time steps to 10'
 
     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 52: Line 47:
 
     imageData.SetOrigin(0, 0, 0)
 
     imageData.SetOrigin(0, 0, 0)
 
     imageData.SetSpacing(.1, .1, .1)
 
     imageData.SetSpacing(.1, .1, .1)
     imageData.SetDimensions(10, 12, 12)
+
     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 63: 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()
 
</source>
 
</source>
  
Line 101: Line 195:
  
 
def GetNextProxyToDelete():
 
def GetNextProxyToDelete():
     iter = servermanager.vtkSMProxyIterator()
+
     proxyiterator = servermanager.ProxyIterator()
     iter.Begin()
+
     for proxy in proxyiterator:
    while not iter.IsAtEnd():
+
        group = proxyiterator.GetGroup()
         if iter.GetGroup().find("prototypes") != -1:
+
         if group.find("prototypes") != -1:
            iter.Next()
+
 
             continue
 
             continue
        proxy = servermanager._getPyProxy(iter.GetProxy())
+
         if group != 'timekeeper' and group.find("pq_helper_proxies") == -1 :
        proxygroup = iter.GetGroup()
+
        iter.Next()
+
         if proxygroup != 'timekeeper' and proxy != None and proxygroup.find("pq_helper_proxies") == -1 :
+
 
             return proxy
 
             return proxy
 
 
     return None
 
     return None
  
Line 120: Line 209:
 
         raise RuntimeError, "Simulation input name '%s' does not exist" % gridname
 
         raise RuntimeError, "Simulation input name '%s' does not exist" % gridname
 
     grid = datadescription.GetInputDescriptionByName(gridname).GetGrid()
 
     grid = datadescription.GetInputDescriptionByName(gridname).GetGrid()
     producer = TrivialProducer()
+
     producer = PVTrivialProducer()
 
     producer.GetClientSideObject().SetOutput(grid)
 
     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()
 
     producer.UpdatePipeline()
 
     return producer
 
     return producer

Latest revision as of 15: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

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])

Parallel python driver code

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()

Sample coprocessing script

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