def test_gen_loopblocking_ntops(self): ''' gen_loopblocking ntops. ''' tops = list( loop_blocking.gen_loopblocking(self.nld['BASE'], self.resource['LG'], self.cost, 1, self.options['NTOPS'])) cost_prev = -float('inf') for lbs in loop_blocking.gen_loopblocking(self.nld['BASE'], self.resource['LG'], self.cost, 1, self.options['BASE']): if not lbs.is_valid(): continue cost_curr = lbs.get_cost(self.cost) self.assertLessEqual(cost_prev, cost_curr) cost_prev = cost_curr if tops: top_lbs = tops.pop(0) self.assertAlmostEqual(cost_curr, top_lbs.get_cost(self.cost))
def test_bufshr_access_byp(self): ''' Access of scheme using bufshr with bypassing. ''' for part in self._gen_all_partition(): p_nld = self._part_nld(part) bufshr = BufShrScheme(self.par_proc_region, part) for lbs in loop_blocking.gen_loopblocking( p_nld, self.resource['PAR'], part, self.none_cstr, self.cost, self.options['BUFSHR-BYP']): if not lbs.is_valid(): continue # Skip those without bufshr. if all(sgs <= 1 for sgs in lbs.bufshr_subgrp_size): continue # Skip those without bypassing. if all(lbs.stored_in_gbuf): continue # Sim. dram_access, gbuf_access, bufshr_stats = \ self._sim_access_conv(lbs, get_bufshr=True) self._verify_bufshr_stats(dram_access, gbuf_access, bufshr_stats, lbs, bufshr, 'test_bufshr_access')
def test_gen_loopblocking_mp(self): ''' gen_loopblocking multiprocessing. ''' cnt1 = 0 for _ in loop_blocking.gen_loopblocking(self.nld['BASE'], self.resource['LG'], self.cost, 1, self.options['BASE']): cnt1 += 1 cnt8 = 0 for _ in loop_blocking.gen_loopblocking(self.nld['BASE'], self.resource['LG'], self.cost, 1, self.options['MP']): cnt8 += 1 self.assertEqual(cnt1, cnt8)
def test_gen_loopblocking_no_eqv(self): ''' gen_loopblocking no equivalent. ''' acc_dict = {} for lbs in loop_blocking.gen_loopblocking(self.nld['BASE'], self.resource['LG'], self.cost, 1, self.options['BASE']): if not lbs.is_valid(): continue sdict = lbs.get_scheme_dict(self.cost) # Make the keys hashable (list -> tuple). size = tuple(tuple(ss for ss in s) for s in sdict['size']) access = tuple(tuple(int(aa) for aa in a) for a in sdict['access']) keys = (size, access) self.assertNotIn( keys, acc_dict, 'test_gen_loopblocking_no_eqv: found equivalents. ' 'keys: access {} size {}\n {}\n {}'.format( access, size, sdict, acc_dict.get(keys))) acc_dict[keys] = sdict
def test_gen_loopblocking_all(self): ''' gen_loopblocking cover all. ''' exp_cnt = 0 for bl_ts, bl_ords in self._gen_loopblocking_all(): exp_cnt += 1 if not loop_blocking.skip_conv(bl_ts, bl_ords) else 0 cnt = 0 for _ in loop_blocking.gen_loopblocking(self.nld['BASE'], self.resource['LG'], self.cost, 1, self.options['BASE']): cnt += 1 self.assertEqual(cnt, exp_cnt)
def _gen_loopblocking(self, wlkey='BASE', rsrckey='BASE', optkey='BASE', cstr=None, skip_invalid=False): ''' gen_loopblocking trampoline. ''' if cstr is None: cstr = self.none_cstr for lbs in loop_blocking.gen_loopblocking(self.nld[wlkey], self.resource[rsrckey], self.part, cstr, self.cost, self.options[optkey]): if not skip_invalid or lbs.is_valid(): yield lbs
def test_gen_loopblocking_byp_sol(self): ''' gen_loopblocking using bypass solvers. ''' cnt = 0 for lbs in loop_blocking.gen_loopblocking(self.nld['BASE'], self.resource['BASE'], self.cost, 1, self.options['BYPSOL']): self.assertTrue(lbs.is_valid()) cnt += 1 self.assertLessEqual(cnt, 8)
def test_accfwd(self): ''' Scheme using accfwd. ''' for part in self._gen_all_partition(): p_nld = self._part_nld(part) filter_size, ifmap_size, ofmap_size = self._total_part_size(part) bufshr = BufShrScheme(self.par_proc_region, part) # Filter may still have redundant fetch. fil_fetch = part.size(pe.BATP, pe.OFMP) // bufshr.size(de.FIL) for lbs in loop_blocking.gen_loopblocking(p_nld, self.resource['PAR'], part, self.none_cstr, self.cost, self.options['ACCFWD']): if not lbs.is_valid(): continue # Ops. self.assertAlmostEqual(lbs.ops, self.total_ops) # Access forwarding reduction. accfwd_red = lbs.accfwd_reduction self.assertEqual(accfwd_red[de.FIL], part.size(pe.BATP, pe.OFMP) // fil_fetch) self.assertEqual(accfwd_red[de.OFM], part.size(pe.INPP)) self.assertEqual(accfwd_red[de.IFM], part.size(pe.OUTP)) # Top fetch and access. top_fetch = lbs.fetch[0] top_access = lbs.access[0] self.assertAlmostEqual( top_access[de.FIL], top_fetch[de.FIL] * filter_size * fil_fetch) self.assertAlmostEqual(top_access[de.OFM], top_fetch[de.OFM] * ofmap_size) self.assertGreaterEqual(top_access[de.IFM], top_fetch[de.IFM] * ifmap_size)
def test_bufshr_localregionlayer(self): ''' Scheme using bufshr for LocalRegionLayer. ''' for part in self._gen_all_partition(layerkey='POOL'): p_nld = self._part_nld(part, layerkey='POOL') for lbs in loop_blocking.gen_loopblocking(p_nld, self.resource['PAR'], part, self.none_cstr, self.cost, self.options['BUFSHR']): if not lbs.is_valid(): continue self.assertTrue( all(gs == 1 for gs in lbs.bufshr_grp_size), 'test_bufshr_localregionlayer: ' 'non-1 bufshr group size {}, part {}'.format( lbs.bufshr_grp_size, part))
def test_bufshr(self): ''' Scheme using bufshr. ''' for part in self._gen_all_partition(): p_nld = self._part_nld(part) bufshr = BufShrScheme(self.par_proc_region, part) # Filter may still have redundant fetch. fil_fetch = part.size(pe.BATP, pe.OFMP) // bufshr.size(de.FIL) for optkey in ['BUFSHR', 'BUFSHR-BYP']: for lbs in loop_blocking.gen_loopblocking( p_nld, self.resource['PAR'], part, self.none_cstr, self.cost, self.options[optkey]): if not lbs.is_valid(): continue # Ops. self.assertAlmostEqual(lbs.ops, self.total_ops) # Buffer sharing uses access forwarding reduction. accfwd_red = lbs.accfwd_reduction self.assertEqual(accfwd_red[de.FIL], part.size(pe.BATP, pe.OFMP) // fil_fetch) self.assertEqual(accfwd_red[de.OFM], part.size(pe.INPP)) self.assertEqual(accfwd_red[de.IFM], part.size(pe.OUTP)) # Buffer sharing group size. bufshr_grp_size = lbs.bufshr_grp_size self.assertSequenceEqual(bufshr_grp_size, accfwd_red) # Buffer sharing subgroup size. bufshr_subgrp_size = lbs.bufshr_subgrp_size self.assertTrue( all(subgrp <= grp for subgrp, grp in zip( bufshr_subgrp_size, bufshr_grp_size)))
def test_bufshr_get_noc_access(self): ''' get_noc_access of scheme using bufshr. ''' for part in self._gen_all_partition(): p_nld = self._part_nld(part) for lbs in loop_blocking.gen_loopblocking(p_nld, self.resource['PAR'], part, self.none_cstr, self.cost, self.options['BUFSHR']): noc_access = lbs.get_noc_access() if not lbs.is_valid(): self.assertIsNone(noc_access) else: for dce in range(de.NUM): self.assertAlmostEqual( lbs.bufshr_rotation_access[dce] + lbs.bufshr_wide_fetch_access[dce], noc_access[dce])