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')
def activeProcess(self, index): node = self.skeleton.getNodeWithIndex(index) shared = node.sharedWith() # send the node (remote) index for s in shared: mpitools.Send_Int(node.remoteIndex(s), s, self.move_channel) move_candidates = self.mover.active(self.skeleton, node) mpitools.Isend_Int(len(move_candidates), shared, tag=self.move_channel) changes = [] for mc in move_candidates: change = deputy.DeputyProvisionalChanges() change.moveNode(node, mc, self.skeleton) # moved the node # Building data to be sent to sharers. nodeMoves = [] for s in shared: nodeMoves.append( cfiddler.create_movedata( _rank, # master process node.remoteIndex(s), # remote index mc.x, # x mc.y # y )) # Sending move data to shared processes cfiddler.Isend_MoveData(nodeMoves, shared, tag=self.move_channel) ## REPORT("STARTED WORKING ON NODE #", index, "WITH", shared) # receiving illegality from shared processes illegal = mpitools.Irecv_Bools(shared, tag=self.illegal_channel) legal = True not in illegal and not change.illegal(self.skeleton) mpitools.Isend_Bool(legal, shared, tag=self.verdict_channel) if not legal: continue # Receiving report from shared processes reports = mpitools.Irecv_DoubleVecs(shared, tag=self.report_channel) homog0 = [] shape0 = [] homog1 = [] shape1 = [] for r in reports: n = len(r) / 4 homog0 += r[:n] shape0 += r[n:2 * n] homog1 += r[2 * n:3 * n] shape1 += r[3 * n:4 * n] change.augmentData(homog0, homog1, shape0, shape1) changes.append(change) # Now, the decision time bestchange = self.criterion(changes, self.skeleton) if bestchange is not None: self.nok += 1 self.deltaE += bestchange.deltaE(self.skeleton, self.alpha) bestchange.accept(self.skeleton) mpitools.Isend_Bool(True, shared, tag=self.verdict_channel) theindex = changes.index(bestchange) x = move_candidates[theindex].x y = move_candidates[theindex].y mpitools.Isend_DoubleVec([x, y], shared, tag=self.move_channel, size=2) else: self.nbad += 1 mpitools.Isend_Bool(False, shared, tag=self.verdict_channel)