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