I have been trying to understand the difference in performance between the Python interface and native C++, so I took the randomWalkers example, and I translated it to Python:
#!/usr/bin/env python3
#-*-coding: utf-8-*-
import random
import sys
import time
sys.path.append("/usr/local/pandora/bin")
sys.path.append("/usr/local/pandora/lib")
import pyPandora as pandora
class RandomAgent(pandora.Agent):
def __init__(self, agent_id):
super().__init__(agent_id)
self._resources = 5
def selectActions(self):
# move
newPosition = pandora.Point2DInt(self.position._x + random.randint(-1, 1),
self.position._y + random.randint(-1, 1))
if self.getWorld().checkPosition(newPosition):
self.position = newPosition
# eat
self._resources += self.getWorld().getValue("resources", self.position)
self.getWorld().setValue("resources", self.position, 0)
self._resources -= 1
def updateState(self):
if self._resources<0:
self.remove()
def registerAttributes(self):
self.registerIntAttribute("resources")
def serialize(self):
self.serializeIntAttribute("resources", self._resources)
class RandomWorld(pandora.World):
def __init__(self, config):
super().__init__(config)
self.numAgents = config.numAgents
def createRasters(self):
self.registerDynamicRaster("resources", True)
self.getDynamicRaster("resources").setInitValues(0, 5, 0)
for i in range(self.getBoundaries().left, self.getBoundaries().right+1):
for j in range(self.getBoundaries().top, self.getBoundaries().bottom+1):
self.setMaxValue("resources", pandora.Point2DInt(i,j), random.randint(0, 5))
#self.updateRasterToMaxValues("resources")
def createAgents(self):
for i in range(self.numAgents):
agent = RandomAgent("RandomAgent_{}".format(i))
self.addAgent(agent)
agent.setRandomPosition()
class RandomWorldConfig(pandora.Config):
def __init__(self, xmlFile):
super().__init__(xmlFile)
self.numAgents = 0
def loadParams(self):
self.numAgents = self.getParamInt("numAgents", "value")
if __name__=="__main__":
if len(sys.argv)>2:
print("USAGE: randomWalkers [config file]")
sys.exit(1)
fileName = "config.xml"
if len(sys.argv)!=1:
fileName = sys.argv[1]
world = RandomWorld(RandomWorldConfig(fileName))
world.initialize()
world.run()
I also modified the randomWalkers code (in C++) to change the scheduler to OpenMPSingleNode (main.cxx:24), and the createAgents method in RandomWorld.cxx:43 (commented out if((i%getNumTasks())==getId())). As far as I can tell, there should be no differences in functionality between the two models.