예제 #1
0
파일: stencil.py 프로젝트: nopper/skippy
    def __init__(self, offsets, data_segments, partition, pwidth, pheight, \
                 connections=None):
        self.wid = StencilWorker._id
        self.offsets = offsets
        self.data_segments = data_segments
        self.partition = partition

        self.col, self.row = 0, 0
        self.width, self.height = self.partition.cols, self.partition.rows
        self.pwidth, self.pheight = pwidth, pheight

        self.conns = connections

        if rank == 0:
            log.debug("Worker %d has %s" % (StencilWorker._id, self.partition))
            StencilWorker._id += 1
        else:
            self.comm = Communicator(self)
예제 #2
0
파일: stencil.py 프로젝트: nopper/skippy
class StencilWorker(object):
    _id = 0

    def __init__(self, offsets, data_segments, partition, pwidth, pheight, \
                 connections=None):
        self.wid = StencilWorker._id
        self.offsets = offsets
        self.data_segments = data_segments
        self.partition = partition

        self.col, self.row = 0, 0
        self.width, self.height = self.partition.cols, self.partition.rows
        self.pwidth, self.pheight = pwidth, pheight

        self.conns = connections

        if rank == 0:
            log.debug("Worker %d has %s" % (StencilWorker._id, self.partition))
            StencilWorker._id += 1
        else:
            self.comm = Communicator(self)

    def autoconnect(self, wdict, rows=None, cols=None):
        if self.conns:
            if self.conns.up:
                self.conns.up_left = self.conns.up.conns.left
                self.conns.up_right = self.conns.up.conns.right
            if self.conns.down:
                self.conns.down_left = self.conns.down.conns.left
                self.conns.down_right = self.conns.down.conns.right

            return

        tot = int(rows * cols)

        i_col = self.wid % cols
        i_row = int(self.wid / cols)

        start = cols * i_row

        # Here we calculate our position in the general matrix
        self.col, self.row = i_col * self.height, i_row * self.width

        links = []

        for wid in ((self.wid + 1) % cols + start,
                   (self.wid - 1) % cols + start,
                   (self.wid - cols) % tot,
                   (self.wid + cols) % tot):

            if wid == self.wid:
                links.append(None)
            else:
                links.append(wdict[wid])

        self.conns = Connections(*links)

    def __repr__(self):
        return 'Worker(%d [%d %d %d %d])' % (self.wid, self.row, self.col,
                self.width, self.height)

    def start(self):
        log.info("Worker started on processor %d %s" % (rank, name))

        # First we send all the required partitions to the neighbors and then
        # receive all the segments and reconstruct a local matrix where the
        # function will be evaluated.

        puzzle = Puzzle(self.partition)

        for lbl, enum in zip(LABELS, ORDERED):
            self.comm.send(getattr(self.conns, lbl), enum)

        for lbl, enum in zip(RLABELS, REVERSED):
            m = self.comm.receive(getattr(self.conns, lbl), enum)
            if m: puzzle.add_piece(m, enum)

        start = time.time()
        puzzle.apply(self.offsets, function)
        log.info("Worker %d: %.10f seconds to compute the partition" % \
                 (rank - 1, time.time() - start))

        log.info("Sending back the computed sub-partition from %d" % rank)

        start = time.time()
        comm.gather(self.partition.matrix, root=0)
        log.info("Worker %d: %.10f seconds to send back the partition" % \
                 (rank - 1, time.time() - start))

        comm.Barrier()