Пример #1
0
def test_dacc_path_has_no_critical():
    seg = Segment(
        [TaggedValue(1, "N"),
         TaggedValue(2, "L"),
         TaggedValue(3, "L")])
    with pytest.raises(ApplicationError):
        seg.dacc_path(fun.idt, fun.idt, operator.add)
Пример #2
0
def test_dacc_path_gt_node():
    seg = Segment([
        TaggedValue(1, "N"),
        TaggedValue(2, "L"),
        TaggedValue(1, "N"),
        TaggedValue(2, "L"),
        TaggedValue(3, "C")
    ])
    res = seg.dacc_path(fun.idt, fun.idt, operator.add)
    exp = TaggedValue((5, 5), "N")
    assert res == exp
Пример #3
0
    def dacc(self, gl, gr, c, phi_l, phi_r, psi_u, psi_d):
        """Downward accumulation skeleton for distributed tree

        The parameters must respect these equalities (closure property):
        * gl(c, b) = psi_d(c, phi_l(b))
        * gr(c, b) = psi_d(c, phi_r(b))
        * psi_d(psi_d(c, b), a) = psi_d(c, psi_u(b,a))

        Parameters
        ---------
        gl : callable
            The function used to make an accumulation to the left children in a binary tree
        gr : callable
            The function used to make an accumulation to the right children in a binary tree
        c
            Initial value of accumulation
        phi_l : callable
            A function used to respect the closure property to allow partial computation on the left
        phi_r : callable
            A function used to respect the closure property to allow partial computation on the right
        psi_d : callable
            A function used to respect the closure property to make partial downward accumulation
        psi_u : callable
            A function used to respect the closure property to make partial computation
        """
        logger.debug(
            '[START] PID[' + str(PID) + '] dAcc skeleton')
        # Step 1 : Computing Local Intermediate Values
        gt = Segment([None] * self.__nb_segs)
        i = 0
        for (start, offset) in self.__global_index[self.__start_index: self.__start_index + self.__nb_segs]:
            seg = Segment(self.__content[start:start + offset])
            logger.debug(
                '[START] PID[' + str(PID) + '] dacc_path from ' + str(start) + ' to ' + str(start + offset))
            if seg.has_critical():
                gt[i] = seg.dacc_path(phi_l, phi_r, psi_u)
            else:
                gt[i] = TaggedValue(seg[0].get_value(), "L")
            logger.debug(
                '[END] PID[' + str(PID) + '] dacc_path from ' + str(start) + ' to ' + str(start + offset))
            i = i + 1
        # Step 2 : Gather Local Results
        if PID == 0:
            for iproc in range(1, NPROCS):
                logger.debug(
                    '[START] PID[' + str(PID) + '] reception update from ' + str(i))
                gt.extend(COMM.recv(source=iproc, tag=TAG_COMM_DACC_1)['c'])
                logger.debug(
                    '[END] PID[' + str(PID) + '] reception update from ' + str(i))
        else:
            logger.debug(
                '[START] PID[' + str(PID) + '] emission update to ' + str(0))
            COMM.send({'c': gt}, dest=0, tag=TAG_COMM_DACC_1)
            logger.debug(
                '[END] PID[' + str(PID) + '] emission update to ' + str(0))
        # Step 3 : Global Downward Accumulation
        par.at_root(lambda: logger.debug('[START] PID[' + str(PID) + '] dacc_global'))
        gt2 = (gt.dacc_global(psi_d, c) if PID == 0 else None)
        par.at_root(lambda: logger.debug('[END] PID[' + str(PID) + '] dacc_global'))
        # Step 4 : Distributing Global Result
        if PID == 0:
            start = 0
            for iproc in range(NPROCS):
                iproc_off = self.__distribution[iproc]
                if iproc != 0:
                    logger.debug(
                        '[START] PID[' + str(PID) + '] emission global to ' + str(iproc))
                    COMM.send({'g': gt2[start: start + iproc_off]}, dest=iproc, tag=TAG_COMM_DACC_2)
                    logger.debug(
                        '[END] PID[' + str(PID) + '] emission global to ' + str(iproc))
                start = start + iproc_off
        else:
            logger.debug(
                '[START] PID[' + str(PID) + '] reception global from ' + str(0))
            gt2 = COMM.recv(source=0, tag=TAG_COMM_DACC_2)['g']
            logger.debug(
                '[END] PID[' + str(PID) + '] reception global from ' + str(0))
        # Step 5 : Local Downward Accumulation
        content = SList([None] * self.__content.length())
        for i in range(len(self.__global_index[self.__start_index: self.__start_index + self.__nb_segs])):
            (start, offset) = self.__global_index[self.__start_index: self.__start_index + self.__nb_segs][i]
            logger.debug(
                '[START] PID[' + str(PID) + '] dacc_local from ' + str(start) + ' to ' + str(start + offset))
            content[start:start + offset] = \
                Segment(self.__content[start:start + offset]).dacc_local(gl, gr, gt2[i].get_value())
            logger.debug(
                '[END] PID[' + str(PID) + '] dacc_local from ' + str(start) + ' to ' + str(start + offset))
        res = PTree.init(self, content)
        logger.debug(
            '[END] PID[' + str(PID) + '] dAcc skeleton')
        return res
Пример #4
0
def test_dacc_path_empty():
    seg = Segment()
    with pytest.raises(AssertionError):
        seg.dacc_path(fun.idt, fun.idt, operator.add)
Пример #5
0
    def dacc(self, gl, gr, c, phi_l, phi_r, psi_u, psi_d):
        """Downward accumulation skeleton for distributed tree

        The parameters must respect these equalities (closure property):
        * gl(c, b) = psi_d(c, phi_l(b))
        * gr(c, b) = psi_d(c, phi_r(b))
        * psi_d(psi_d(c, b), a) = psi_d(c, psi_u(b,a))

        Parameters
        ---------
        gl : callable
            The function used to make an accumulation to the left children in a binary tree
        gr : callable
            The function used to make an accumulation to the right children in a binary tree
        c
            Initial value of accumulation
        phi_l : callable
            A function used to respect the closure property to allow partial computation
            on the left
        phi_r : callable
            A function used to respect the closure property to allow partial computation
            on the right
        psi_d : callable
            A function used to respect the closure property to make partial downward accumulation
        psi_u : callable
            A function used to respect the closure property to make partial computation
        """
        logger.debug('[START] PID[%s] dAcc skeleton', PID)
        # Step 1 : Computing Local Intermediate Values
        gt = Segment([None] * self.__nb_segs)
        i = 0
        for (start, offset) in \
                self.__global_index[self.__start_index: self.__start_index + self.__nb_segs]:
            seg = Segment(self.__content[start:start + offset])
            logger.debug('[START] PID[%s] dacc_path from %s to %s', PID, start,
                         start + offset)
            if seg.has_critical():
                gt[i] = seg.dacc_path(phi_l, phi_r, psi_u)
            else:
                gt[i] = TaggedValue(seg[0].get_value(), "L")
            logger.debug('[END] PID[%s] dacc_path from %s to %s', PID, start,
                         start + offset)
            i = i + 1
        # Step 2 : Gather Local Results
        self.__gather_local_result(gt, i, TAG_COMM_DACC_1)
        # Step 3 : Global Downward Accumulation
        par.at_root(lambda: logger.debug('[START] PID[%s] dacc_global', PID))
        gt2 = (gt.dacc_global(psi_d, c) if PID == 0 else None)
        par.at_root(lambda: logger.debug('[END] PID[%s] dacc_global', PID))
        # Step 4 : Distributing Global Result
        gt2 = self.__distribute_global_result(gt2, TAG_COMM_DACC_2)
        # Step 5 : Local Downward Accumulation
        content = SList([None] * self.__content.length())
        for i in range(
                len(self.__global_index[self.__start_index:self.__start_index +
                                        self.__nb_segs])):
            (start, offset
             ) = self.__global_index[self.__start_index:self.__start_index +
                                     self.__nb_segs][i]
            logger.debug('[START] PID[%s] dacc_local from %s to %s', PID,
                         start, start + offset)
            content[start:start + offset] = \
                Segment(self.__content[start:start + offset]).dacc_local(gl, gr, gt2[i].get_value())
            logger.debug('[END] PID[%s] dacc_local from %s to %s', PID, start,
                         start + offset)
        logger.debug('[END] PID[%s] dAcc skeleton', PID)
        return PTree.init(self, content)