示例#1
0
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)
示例#2
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')
示例#3
0
    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)