def setUp(self): self.alex_net = import_network('alex_net') self.vgg_net = import_network('vgg_net') self.map_strategy = MapStrategyEyeriss self.resource = Resource( proc_region=NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(1, 1), type=NodeRegion.PROC), data_regions=(NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(1, 1), type=NodeRegion.DATA), ), dim_array=PhyDim2(16, 16), size_gbuf=128 * 1024 // 2, # 128 kB size_regf=512 // 2, # 512 B ) self.cost = Cost(mac_op=1, mem_hier=(200, 6, 2, 1), noc_hop=0, unit_static=0) self.options = Option()
def test_invalid_dist(self): ''' Invalid dist. ''' with self.assertRaisesRegexp(TypeError, 'NodeRegion: .*dist.*'): _ = NodeRegion(dim=PhyDim2(4, 4), origin=PhyDim2(1, 3), dist=(1, 1), type=NodeRegion.PROC)
def setUp(self): self.scheme = OrderedDict([ ('cost', 9.876 + 1.234), ('time', 123.4), ('ops', 1234), ('num_nodes', 4), ('cost_op', 1.234), ('cost_access', 9.876), ('cost_noc', 0), ('cost_static', 0), ('proc_time', 59), ('bus_time', 40), ('dram_time', 120), ('access', [[2, 3, 4], [30, 40, 50], [400, 500, 600], [5000, 6000, 7000]]), ('remote_gbuf_access', [0, 0, 0]), ('total_nhops', [123, 456, 789]), ('fetch', [[1, 2, 1], [3, 4, 5]]), ]) part = PartitionScheme(order=range(pe.NUM), pdims=[(1, 1)] * pe.NUM) self.ofmap_layout = DataLayout( frngs=(FmapRange((0, 0, 0, 0), (2, 4, 16, 16)), ), regions=(NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(1, 1), type=NodeRegion.DRAM), ), parts=(part, )) self.sched_seq = (2, 0, 0)
def test_ofmap_local(self): ''' With locally stored ofmaps. ''' layer = self.layers['BASE'] part = PartitionScheme(order=(pe.BATP, pe.INPP, pe.OUTP, pe.OFMP), pdims=((4, 1), (1, 1), (1, 4), (1, 1))) nr = NodeRegion(origin=PhyDim2(3, 3), dim=part.dim(), type=NodeRegion.PROC) ilayout = self._make_data_layout(layer.nifm, layer.hifm, layer.wifm, PhyDim2(-3, -3), (1, 1), (1, 1), PhyDim2(1, 1)) olayout = DataLayout(frngs=(FmapRange( (0, ) * 4, (self.batch_size, layer.nofm, layer.hofm, layer.wofm)), ), regions=(nr, ), parts=(part, )) filter_nodes = frozenset([PhyDim2(3, -3)]) nhops = partition.unit_nhops_to_proc_region(layer, self.batch_size, nr, part, filter_nodes, ilayout, olayout, self.options['BASE']) self.assertEqual(nhops[de.OFM], 0)
def test_invalid_wbeg_type(self): ''' Invalid wbeg type. ''' with self.assertRaisesRegexp(TypeError, 'NodeRegion: .*wbeg.*'): _ = NodeRegion(dim=PhyDim2(4, 4), origin=PhyDim2(1, 3), type=NodeRegion.PROC, wbeg=1.3)
def test_merge_unmatch(self): ''' Merge unmatch. ''' for fr in [ FmapRange((0, ) * 4, (4, 4, 10, 16)), FmapRange((0, ) * 4, (4, 4, 16, 32)), FmapRange((0, ) * 4, (3, 4, 16, 16)) ]: frm = FmapRangeMap() frm.add(fr, (PhyDim2(1, 1), )) dly = DataLayout(origin=PhyDim2(-1, -1), frmap=frm, type=NodeRegion.DATA) with self.assertRaisesRegexp(ValueError, 'DataLayout: .*match.*'): _ = self.dly.merge('|', dly) with self.assertRaisesRegexp(ValueError, 'DataLayout: .*match.*'): _ = self.dly.merge('+', dly) frm = FmapRangeMap() frm.add(FmapRange((0, ) * 4, (4, 2, 16, 16)), (PhyDim2(1, 1), )) dly = DataLayout(origin=PhyDim2(-1, -1), frmap=frm, type=NodeRegion.DATA) with self.assertRaisesRegexp(ValueError, 'DataLayout: .*match.*'): _ = self.dly.merge('+', dly)
def test_mul(self): ''' Operation mul. ''' dim1 = PhyDim2(14, 12) dim2 = PhyDim2(5, 3) self.assertTupleEqual(dim1 * dim2, (70, 36), 'mul') self.assertTupleEqual(dim1 * 2, (28, 24), 'mul') self.assertTupleEqual(2 * dim1, (28, 24), 'rmul')
def test_args_kwargs(self): ''' Different ways to give args and kwargs. ''' dim = PhyDim2(4, 8) origin = PhyDim2(1, 3) dist = PhyDim2(1, 1) type_ = NodeRegion.PROC wtot = 6 wbeg = 5 nr0 = NodeRegion(dim=dim, origin=origin, dist=dist, type=type_, wtot=wtot, wbeg=wbeg) nr = NodeRegion(dim, origin, dist, type_, wtot, wbeg) self.assertTupleEqual(nr, nr0) nr = NodeRegion(dim, origin, wbeg=wbeg, wtot=wtot, type=type_, dist=dist) self.assertTupleEqual(nr, nr0) nr = NodeRegion(dim, origin, dist, type=type_, wtot=wtot, wbeg=wbeg) self.assertTupleEqual(nr, nr0)
def test_projection_empty_region(self): ''' Get projection with empty region. ''' with self.assertRaisesRegex(ValueError, 'PartitionScheme: .*region.*'): _ = self.ps1.projection( NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(0, 0), type=NodeRegion.DRAM))
def setUp(self): self.layers = {} self.layers['BASE'] = ConvLayer(8, 16, 28, 3) self.layers['POOL'] = PoolingLayer(16, 28, 2) self.layers['LR'] = LocalRegionLayer(16, 28, nreg=3, sreg=1) self.batch_size = 4 self.cost = Cost(mac_op=1, mem_hier=(200, 6, 2, 1), noc_hop=50, unit_static=50) self.resource = Resource( proc_region=NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(4, 4), type=NodeRegion.PROC), data_regions=(NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(4, 1), type=NodeRegion.DATA),), dim_array=PhyDim2(16, 16), size_gbuf=65536, size_regf=64) self.options = Option(partition_hybrid=True, partition_batch=True, partition_ifmaps=True, ntops=10) self.ifmap_layouts = {} part = PartitionScheme(order=(pe.INPP, pe.BATP, pe.OUTP, pe.OFMP), pdims=((1, 2), (2, 1), (1, 2), (2, 1))) for wlkey in self.layers: self.ifmap_layouts[wlkey] = partition.get_ofmap_layout( self.layers[wlkey].input_layer(), self.batch_size, part, self.resource.src_data_region())
def test_larger_wtot(self): ''' wtot > dim.w is valid. ''' nr = NodeRegion(dim=PhyDim2(4, 8), origin=PhyDim2(1, 3), type=NodeRegion.PROC, wtot=20) self.assertEqual(nr.wtot, 20)
def test_fmap_range(self): ''' Get fmap_range. ''' fr1 = FmapRange(FmapPosition(b=0, n=0, h=0, w=0), FmapPosition(b=8, n=64, h=28, w=28)) # Small ranges. fr2 = FmapRange(FmapPosition(b=0, n=0, h=0, w=0), FmapPosition(b=1, n=1, h=1, w=1)) # Irregular values. fr3 = FmapRange(FmapPosition(b=2, n=4, h=2, w=6), FmapPosition(b=5, n=11, h=13, w=13)) ps = self.ps2 # No overlap. for fr in [fr1, fr2, fr3]: pfr_list = [ps.fmap_range(fr, pidx) for pidx in ps.gen_pidx()] for idx, pfr in enumerate(pfr_list): for jdx in range(idx): self.assertEqual(pfr_list[jdx].overlap_size(pfr), 0) pidx = (PhyDim2(1, 0), PhyDim2(4, 3), PhyDim2(0, 2), PhyDim2(0, 0)) self.assertEqual( ps.fmap_range(fr1, pidx), FmapRange(FmapPosition(b=1, n=32, h=22, w=16), FmapPosition(b=2, n=48, h=28, w=22))) self.assertEqual( ps.fmap_range(fr2, pidx), FmapRange(FmapPosition(b=0, n=0, h=0, w=0), FmapPosition(b=0, n=0, h=1, w=0))) self.assertEqual( ps.fmap_range(fr3, pidx), FmapRange(FmapPosition(b=2, n=7, h=10, w=10), FmapPosition(b=3, n=9, h=13, w=11)))
def test_lr_layer(self): ''' LR layers. ''' layer = self.layers['LR'] part = PartitionScheme(order=(pe.BATP, pe.INPP, pe.OUTP, pe.OFMP), pdims=((2, 1), (2, 4), (2, 2), (1, 1))) nr = NodeRegion(origin=PhyDim2(0, 0), dim=part.dim(), type=NodeRegion.PROC) ilayout = self._make_data_layout(layer.nifm, layer.hifm, layer.wifm, PhyDim2(-3, -3), (1, 2), (4, 1), PhyDim2(8, 4)) olayout = self._make_data_layout(layer.nofm, layer.hofm, layer.wofm, PhyDim2(5, 5), (1, 1), (1, 2), PhyDim2(2, 4)) filter_nodes = frozenset() nhops = partition.unit_nhops_to_proc_region(layer, self.batch_size, nr, part, filter_nodes, ilayout, olayout, self.options['BASE']) true_nhops = self._true_unit_nhops(layer, nr, part, filter_nodes, ilayout, olayout) self.assertListEqual(nhops, true_nhops)
def test_invalid_data_region(self): ''' Invalid src/dst_proc_region. ''' with self.assertRaisesRegex(TypeError, 'Resource: .*src_data_.*'): _ = Resource( proc_region=self.proc_region, dram_region=self.dram_region, src_data_region=PhyDim2(2, 1), dst_data_region=self.dst_data_region, dim_array=PhyDim2(16, 16), size_gbuf=131072, size_regf=512, array_bus_width=8, dram_bandwidth=128, no_time_mux=False, ) with self.assertRaisesRegex(TypeError, 'Resource: .*dst_data_.*'): _ = Resource( proc_region=self.proc_region, dram_region=self.dram_region, src_data_region=self.src_data_region, dst_data_region=PhyDim2(2, 1), dim_array=PhyDim2(16, 16), size_gbuf=131072, size_regf=512, array_bus_width=8, dram_bandwidth=128, no_time_mux=False, )
def test_invalid_frmap_incomplete(self): ''' Invalid frmap incomplete. ''' frm = self.frm.copy() frm.add(FmapRange((4, 4, 16, 16), (5, 5, 19, 19)), (PhyDim2(4, 4), )) with self.assertRaisesRegexp(ValueError, 'DataLayout: .*frmap.*'): _ = DataLayout(origin=PhyDim2(2, 3), frmap=frm, type=NodeRegion.DATA)
def test_valid_args(self): ''' Valid arguments. ''' nr = NodeRegion(dim=PhyDim2(4, 4), origin=PhyDim2(1, 3), type=NodeRegion.PROC) self.assertTupleEqual(nr.dim, (4, 4), 'dim') self.assertTupleEqual(nr.origin, (1, 3), 'origin') self.assertEqual(nr.type, NodeRegion.PROC, 'type')
def test_iter_node(self): ''' Get node iterator. ''' nr = NodeRegion(dim=PhyDim2(4, 4), origin=PhyDim2(1, 3), type=NodeRegion.PROC) # No duplicates. self.assertEqual(len(set(nr.iter_node())), nr.dim.size()) # All nodes is contained. for c in nr.iter_node(): self.assertTrue(nr.contains_node(c))
def setUp(self): self.resource = Resource( proc_region=NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(1, 1), type=NodeRegion.PROC), dram_region=NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(1, 1), type=NodeRegion.DRAM), src_data_region=NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(1, 1), type=NodeRegion.DRAM), dst_data_region=NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(1, 1), type=NodeRegion.DRAM), dim_array=PhyDim2(16, 16), size_gbuf=65536, size_regf=64, array_bus_width=float('inf'), dram_bandwidth=float('inf'), no_time_mux=False) self.none_cstr = SchedulingConstraint() part = PartitionScheme(order=range(pe.NUM), pdims=[(1, 1)] * pe.NUM) self.ifmap_layout = DataLayout( frngs=(FmapRange((0, 0, 0, 0), (2, 4, 16, 16)), ), regions=(self.resource.src_data_region, ), parts=(part, )) self.sched_seq = (2, 0, 0)
def setUp(self): self.frm = FmapRangeMap() self.frm.add(FmapRange((0, 0, 0, 0), (2, 4, 8, 16)), (PhyDim2(0, 0), )) self.frm.add(FmapRange((0, 0, 8, 0), (2, 4, 16, 16)), (PhyDim2(1, 0), )) self.frm.add(FmapRange((2, 0, 0, 0), (4, 4, 8, 16)), (PhyDim2(0, 1), )) self.frm.add(FmapRange((2, 0, 8, 0), (4, 4, 16, 16)), (PhyDim2(1, 1), )) self.dly = DataLayout(origin=PhyDim2(1, 1), frmap=self.frm, type=NodeRegion.DATA)
def test_rel2abs_not_in(self): ''' Get rel2abs not in. ''' nr = NodeRegion(dim=PhyDim2(4, 4), origin=PhyDim2(1, 3), type=NodeRegion.PROC) with self.assertRaisesRegexp(ValueError, 'NodeRegion: .*not in.*'): _ = nr.rel2abs(PhyDim2(-1, 0)) with self.assertRaisesRegexp(ValueError, 'NodeRegion: .*not in.*'): _ = nr.rel2abs(PhyDim2(0, 4))
def test_rel2abs_invalid_type(self): ''' Get rel2abs invalid type. ''' nr = NodeRegion(dim=PhyDim2(4, 4), origin=PhyDim2(1, 3), type=NodeRegion.PROC) with self.assertRaisesRegexp(TypeError, 'NodeRegion: .*PhyDim2.*'): _ = nr.rel2abs((0, 0)) with self.assertRaisesRegexp(TypeError, 'NodeRegion: .*PhyDim2.*'): _ = nr.rel2abs(1)
def setUp(self): self.layers = {} self.layers['BASE'] = ConvLayer(8, 16, 28, 3) self.layers['POOL'] = PoolingLayer(16, 28, 2) self.layers['LR'] = LocalRegionLayer(16, 28, nreg=3, sreg=1) self.batch_size = 4 self.cost = Cost(mac_op=1, mem_hier=(200, 6, 2, 1), noc_hop=50, idl_unit=50) self.none_cstr = SchedulingConstraint() self.cstr = SchedulingConstraint(topofm=1, topbat=self.batch_size) self.resource = Resource( proc_region=NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(4, 4), type=NodeRegion.PROC), dram_region=NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(4, 1), type=NodeRegion.DRAM), src_data_region=NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(4, 1), type=NodeRegion.DRAM), dst_data_region=NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(4, 1), type=NodeRegion.DRAM), dim_array=PhyDim2(16, 16), size_gbuf=65536, size_regf=64, array_bus_width=float('inf'), dram_bandwidth=float('inf'), no_time_mux=False) self.options = Option(partition_hybrid=True, partition_batch=True, partition_ifmaps=True, ntops=10) self.ifmap_layouts = {} part = PartitionScheme(order=(pe.INPP, pe.BATP, pe.OUTP, pe.OFMP), pdims=((1, 2), (2, 1), (1, 2), (2, 1))) for wlkey in self.layers: input_layer = self.layers[wlkey].input_layer() self.ifmap_layouts[wlkey] = DataLayout( frngs=(FmapRange((0, 0, 0, 0), FmapPosition(b=self.batch_size, n=input_layer.nofm, h=input_layer.hofm, w=input_layer.wofm)), ), regions=(self.resource.src_data_region, ), parts=(part.projection(self.resource.src_data_region, appl2frng=True), )) self.sched_seq = (2, 0, 1)
def setUp(self): self.ps1 = PartitionScheme(order=[pe.BATP, pe.OUTP, pe.OFMP, pe.INPP], pdims=[(2, 3), (3, 1), (1, 5), (5, 2)]) self.ps2 = PartitionScheme(order=list(range(pe.NUM)), pdims=[(2, 2), (5, 5), (3, 3), (1, 1)]) self.nr1 = NodeRegion(origin=PhyDim2(0, 0), dim=self.ps1.dim(), type=NodeRegion.PROC) self.nr2 = NodeRegion(origin=PhyDim2(0, 0), dim=self.ps2.dim(), type=NodeRegion.PROC)
def test_opt_goal(self): ''' Optimization goal. ''' network = self.alex_net batch_size = 8 resource = self.resource._replace( proc_region=NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(8, 8), type=NodeRegion.PROC) ) nnd = NNDataflow(network, batch_size, resource, self.cost, self.map_strategy) options_e = Option(sw_gbuf_bypass=(True, True, True), sw_solve_loopblocking=True, partition_hybrid=True, partition_batch=True, opt_goal='e', ntops=16) tops_e, _ = nnd.schedule_search(options_e) self.assertTrue(tops_e) options_d = Option(sw_gbuf_bypass=(True, True, True), sw_solve_loopblocking=True, partition_hybrid=True, partition_batch=True, opt_goal='d', ntops=16) tops_d, _ = nnd.schedule_search(options_d) self.assertTrue(tops_d) options_ed = Option(sw_gbuf_bypass=(True, True, True), sw_solve_loopblocking=True, partition_hybrid=True, partition_batch=True, opt_goal='ed', ntops=16) tops_ed, _ = nnd.schedule_search(options_ed) self.assertTrue(tops_ed) self.assertLess(tops_e[0].total_cost, tops_d[0].total_cost) self.assertLess(tops_e[0].total_cost, tops_ed[0].total_cost) self.assertLess(tops_d[0].total_time, tops_e[0].total_time) self.assertLess(tops_d[0].total_time, tops_ed[0].total_time) # Sum of the smallest ED may not be the smallest; allow for error. self.assertLess(tops_ed[0].total_cost * tops_ed[0].total_time, tops_e[0].total_cost * tops_e[0].total_time * 1.05) self.assertLess(tops_ed[0].total_cost * tops_ed[0].total_time, tops_d[0].total_cost * tops_d[0].total_time * 1.05)
def setUp(self): self.layers = {} self.layers['BASE'] = ConvLayer(64, 64, 28, 3) self.layers['FC'] = FCLayer(4096, 1000, 6) self.layers['POOL'] = PoolingLayer(32, 7, 3, strd=2) self.layers['LR'] = LocalRegionLayer(32, 7, nreg=5, sreg=1) # With irregular nifm/nofm. self.layers['IRR'] = ConvLayer(255, 383, 13, 3) # With small numbers of fmaps. self.layers['SM'] = ConvLayer(5, 3, 13, 3) # Super small networks. No partitioning schemes. self.layers['SSM1'] = ConvLayer(1, 1, 2, 3) self.layers['SSM2'] = FCLayer(2, 2) self.layers['SSM3'] = PoolingLayer(1, 2, 2) self.batch_size = 8 self.dim_nodes = {} self.dim_nodes['BASE'] = PhyDim2(4, 4) self.dim_nodes['LG'] = PhyDim2(10, 10) self.dim_nodes['PRIME'] = PhyDim2(3, 3) self.options = {} # Irrelevant options. optdict = {'ntops': 10000} self.options['BASE'] = Option(partition_hybrid=True, partition_batch=True, partition_ifmaps=True, **optdict) self.options['NOBATP'] = Option(partition_hybrid=True, partition_batch=False, partition_ifmaps=True, **optdict) self.options['NOINPP'] = Option(partition_hybrid=True, partition_batch=True, partition_ifmaps=False, **optdict) self.options['NOHYB'] = Option(partition_hybrid=False, partition_batch=True, partition_ifmaps=False, **optdict) self.options['ACCFWD'] = Option(partition_hybrid=True, partition_batch=True, partition_ifmaps=True, hw_access_forwarding=True, **optdict) self.options['BUFSHR'] = Option(partition_hybrid=True, partition_batch=True, partition_ifmaps=True, hw_gbuf_sharing=True, **optdict)
def test_rel2abs(self): ''' Get rel2abs. ''' nr = NodeRegion(dim=PhyDim2(4, 4), origin=PhyDim2(1, 3), type=NodeRegion.PROC) self.assertTupleEqual(nr.rel2abs(PhyDim2(0, 3)), (1, 6)) self.assertTupleEqual(nr.rel2abs(PhyDim2(2, 1)), (3, 4)) self.assertSetEqual( set( nr.rel2abs(PhyDim2(h, w)) for h in range(nr.dim.h) for w in range(nr.dim.w)), set(nr.iter_node()))
def test_zero_region(self): ''' Zero dim region. ''' layer = self.layers['BASE'] part = PartitionScheme(order=(pe.BATP, pe.INPP, pe.OUTP, pe.OFMP), pdims=((2, 3), (1, 5), (4, 4), (1, 1))) omr = NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(0, 0), type=NodeRegion.DATA) with self.assertRaisesRegexp(ValueError, 'partition .*empty.*'): _ = partition.get_ofmap_layout(layer, self.batch_size, part, omr)
def test_invalid_frmap_value_type(self): ''' Invalid frmap value type. ''' frm = FmapRangeMap() frm.add(FmapRange((0, ) * 4, (5, 5, 19, 19)), PhyDim2(4, 4)) with self.assertRaisesRegexp(TypeError, 'DataLayout: .*frmap.*'): _ = DataLayout(origin=PhyDim2(2, 3), frmap=frm, type=NodeRegion.DATA) frm = FmapRangeMap() frm.add(FmapRange((0, ) * 4, (5, 5, 19, 19)), (PhyDim2(4, 4), 4)) with self.assertRaisesRegexp(TypeError, 'DataLayout: .*frmap.*'): _ = DataLayout(origin=PhyDim2(2, 3), frmap=frm, type=NodeRegion.DATA)
def test_invalid_data_regions_len(self): ''' Invalid data_regions len. ''' with self.assertRaisesRegexp(ValueError, 'Resource: .*data_regions.*'): _ = Resource( proc_region=NodeRegion(dim=PhyDim2(2, 2), origin=PhyDim2(0, 0), type=NodeRegion.PROC), data_regions=(NodeRegion(dim=PhyDim2(2, 1), origin=PhyDim2(0, 0), type=NodeRegion.DATA), ) * 3, dim_array=PhyDim2(16, 16), size_gbuf=131072, size_regf=(512, ), )
def test_contains_node(self): ''' Whether contains node. ''' nr = NodeRegion(dim=PhyDim2(4, 4), origin=PhyDim2(1, 3), type=NodeRegion.PROC) for h in range(1, 5): for w in range(3, 7): self.assertTrue(nr.contains_node(PhyDim2(h, w))) num = 0 for h in range(-2, 10): for w in range(-2, 10): num += 1 if nr.contains_node(PhyDim2(h, w)) else 0 self.assertEqual(num, nr.dim.size())