def passiveProcess(self, stopper): # the node to move myindex = mpitools.Recv_Int(stopper, tag=self.move_channel) node = self.skeleton.getNodeWithIndex(myindex) self.mover.passive(self.skeleton, node, stopper) # getting no. of move candidates nmoves = mpitools.Recv_Int(stopper, tag=self.move_channel) for i in range(nmoves): moveData = cfiddler.Recv_MoveData(stopper, tag=self.move_channel) ## REPORT("HELPING", stopper, "FOR NODE #", node.remoteIndex(stopper)) # recording energy-before neighbors = node.aperiodicNeighborElements(self.skeleton) reportData = [ el.energyHomogeneity(self.skeleton) for el in neighbors ] reportData += [el.energyShape() for el in neighbors] # move to the position -- self.skeleton is a DeputySkeleton self.skeleton.moveNodeTo(node, primitives.Point(moveData.x, moveData.y)) # Check & send illegality mpitools.Send_Bool(bool(node.illegal()), stopper, tag=self.illegal_channel) # if illegal in any processes, it should be aborted if mpitools.Recv_Bool( stopper, tag=self.verdict_channel): # True:continue, False:abort # recording energy-after reportData += [ el.energyHomogeneity(self.skeleton) for el in neighbors ] reportData += [el.energyShape() for el in neighbors] # reporting mpitools.Send_DoubleVec(reportData, stopper, tag=self.report_channel) # reset for the next one self.skeleton.moveNodeBack(node) ## REPORT("DONE HELPING", moveData.master, " ON NODE #", ## node.remoteIndex(moveData.master)) # receiving verdivt, True:stay, False:move back if mpitools.Recv_Bool(stopper, self.verdict_channel): x, y = mpitools.Recv_DoubleVec(stopper, tag=self.move_channel, size=2) self.skeleton.moveNodeTo(node, primitives.Point(x, y))
def passive(self, skeleton, stopper): # Parallel mode -- share-holder from ooflib.SWIG.common import mpitools _rank = mpitools.Rank() # Getting the node index (local) index = mpitools.Recv_Int(stopper) node = skeleton.getNodeWithIndex(index) # Get the neighbor nodes (but not ones are shared with stoppers, # since they are already accounted for at "stopper".) nbrNodes = node.neighborNodes(skeleton) positions = [] for nd in nbrNodes: if _rank == nd.master(): # my own node positions.append(skeleton.nodePosition(nd).x) positions.append(skeleton.nodePosition(nd).y) mpitools.Send_DoubleVec(positions, stopper)
def parallel_info_subproblem(menuitem, subproblem): subpctxt = ooflib.engine.subproblemcontext.subproblems[subproblem] subpctxt.begin_reading() reportstring = "" nGatherNodes = 0 nElements = 0 TotalArea = 0 try: nElements = subpctxt.nelements() TotalArea = subpctxt.area() reportstring = """*** Subproblem Info *** %s %d elements %d nodes area = %g\n""" % (subpctxt.getObject(), nElements, subpctxt.nnodes(), TotalArea) nGatherNodes = subpctxt.getObject().GatherNumNodes() finally: subpctxt.end_reading() if mpitools.Rank() == 0: #Get output from other processes for proc in range(mpitools.Size()): if proc != 0: reportstring += "(From remote process %d:)\n" % proc reportstring += mpitools.Recv_String(proc) nElements += mpitools.Recv_Int(proc) TotalArea += mpitools.Recv_Double(proc) reportstring += """***** Totals (union) ***** %d elements %d unique nodes Total Area = %g""" % (nElements, nGatherNodes, TotalArea) reporter.report(reportstring) else: mpitools.Send_String(reportstring, 0) mpitools.Send_Int(nElements, 0) mpitools.Send_Double(TotalArea, 0)
def parallel_move_node(menuitem, origin, destination, allow_illegal, skeletonpath): skelcontext = skeletoncontext.skeletonContexts[skeletonpath] #skelcontext = self.gfxwindow().topwho('Skeleton') if skelcontext: skeleton = skelcontext.getObject().deputyCopy() skeleton.activate() #If one looks at moveNodeGUI.py, origin here is already #set to the position of the nearest node. node = skeleton.nearestNode(origin) nodeindex=node.getIndex() distance2=(node.position()-origin)**2 ############################################################### # Get nearest node distances from all processes if _rank==0: #Get list of squares of distance of node to the click point distance2list=[distance2] dmin=-1 dmin_proc_list=[] #Get distances from other processes for proc in range(_size): if proc!=0: distance2list.append(mpitools.Recv_Double(proc)) if distance2list[proc]>=0: dmin=distance2list[proc] #Find closest node among those "nominated" by each process for proc in range(_size): if distance2list[proc]>=0: if distance2list[proc]<dmin: dmin=distance2list[proc] for proc in range(_size): if distance2list[proc]==dmin: dmin_proc_list.append(proc) else: #Backend sends report to front end mpitools.Send_Double(distance2,0) mpitools.Barrier() #Tell the processes in dmin_proc_list to try moving their nodes #and report back the result. Then really move the node if the #move is valid for all of them. if _rank==0: for proc in range(_size): if proc in dmin_proc_list: if proc==0: moveit=1 else: mpitools.Send_Int(1,proc) else: if proc==0: moveit=0 else: mpitools.Send_Int(0,proc) else: moveit=mpitools.Recv_Int(0) mpitools.Barrier() # ############################################################### skelcontext.reserve() skelcontext.begin_writing() try: if moveit: skeleton.moveNodeTo(node, destination) #TODO 3.1: If the node is shared, the move may be valid in one process #but invalid in another. if node.illegal(): if allow_illegal==1: skeleton.setIllegal() else: node.moveBack() elif skeleton.illegal(): # node motion may have rehabilitated skeleton.checkIllegality() skelcontext.pushModification(skeleton) finally: # collect_pieces(skeleton) # skelcontext.end_writing() skelcontext.cancel_reservation() skeleton.needsHash() switchboard.notify('redraw')