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)
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
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
def test_dacc_path_empty(): seg = Segment() with pytest.raises(AssertionError): seg.dacc_path(fun.idt, fun.idt, operator.add)
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)