def test_invalid_seg(self): ''' Invalid seg. ''' with self.assertRaisesRegex(TypeError, 'PipelineSegment: .*seg.*tuple.*'): _ = PipelineSegment([('0',), ('1', '1p')], self.net['net1'], self.batch_size, self.resource) with self.assertRaisesRegex(TypeError, 'PipelineSegment: .*seg.*sub-tuple.*'): _ = PipelineSegment(('0', '1', '1p'), self.net['net1'], self.batch_size, self.resource)
def test_gen_constraint(self): ''' gen_constraint(). ''' # Single vertex. for net_name in self.net: net = self.net[net_name] ilp = self._make_ilp(net) for idx in range(len(ilp.dag_vertex_list)): segment = self._make_segment((idx,), ilp.network) self.assertTrue(segment.valid) for constraint, _ in segment.gen_constraint(): self._validate_constraint(segment, constraint) # No top loop constraint for single-layer segment. if len(constraint) == 1 and len(constraint[0]) == 1: for c in itertools.chain.from_iterable(constraint): self.assertTrue(c.topifm == 0 and c.topofm == 0 and c.topbat == 0) # Spatial pipelining. for net_name in self.net: if not net_name.startswith('net') and net_name != 'zfnet': continue net = self.net[net_name] for segment in self._gen_all_segment(net): if not segment.valid: continue for constraint, _ in segment.gen_constraint(): self._validate_constraint(segment, constraint) # Special cases. net = self.net['net2'] segment = PipelineSegment((('0', '1'), ('2', '3')), net, self.batch_size, self.resource) for constraint, _ in segment.gen_constraint(): self._validate_constraint(segment, constraint)
def test_gen_segment_lstm(self): ''' gen_segment() with LSTM cell. ''' net = self.net['lstm_phoneme'] ilp = self._make_ilp(net) options = Option(partition_interlayer=True) # Find a cell. cname = None for l in net: if l[-6:] == '_igate': cname = l[:-6] self.assertIsNotNone(cname) # One LSTM cell fits. segment = PipelineSegment( ((cname + '_cand',), (cname + '_igate', cname + '_cout_i'), (cname + '_fgate', cname + '_cout_f', cname + '_cout'), (cname + '_ogate', cname + '_hout')), ilp.network, ilp.batch_size, ilp.resource) self.assertTrue(segment.valid) segs = set(seg.seg for seg in ilp.gen_segment(options)) self.assertIn(segment.seg, segs)
def test_invalid_resource(self): ''' Invalid resource. ''' with self.assertRaisesRegex(TypeError, 'PipelineSegment: .*resource.*'): _ = PipelineSegment((('0',), ('1', '1p')), self.net['net1'], self.batch_size, PhyDim2(1, 1))
def test_invalid_network(self): ''' Invalid network. ''' with self.assertRaisesRegex(TypeError, 'PipelineSegment: .*network.*'): _ = PipelineSegment((('0',), ('1', '1p')), self.net['net1'].input_layer(), self.batch_size, self.resource)
def test_valid_args(self): ''' Valid arguments. ''' segment = PipelineSegment((('0',), ('1', '1p')), self.net['net1'], self.batch_size, self.resource) self.assertTrue(segment.valid) self.assertTupleEqual(segment.seg, (('0',), ('1', '1p'))) self.assertIs(segment.network, self.net['net1']) self.assertEqual(segment.batch_size, self.batch_size) self.assertIs(segment.resource, self.resource)
def test_gen_segment(self): ''' gen_segment(). ''' for net_name in self.net: net = self.net[net_name] ilp = self._make_ilp(net) # No pipelining. options = Option() segs_n_lst = list(ilp.gen_segment(options)) segs_n = set(segs_n_lst) self.assertEqual(len(segs_n_lst), len(segs_n)) for seg in segs_n: self.assertEqual(len(seg), 1) self.assertEqual(len(seg[0]), 1) self.assertIn(seg[0][0], net) # Spatial pipelining. options = Option(partition_interlayer=True) segs_sp_lst = list(ilp.gen_segment(options)) segs_sp = set(segs_sp_lst) self.assertEqual(len(segs_sp_lst), len(segs_sp)) for seg in segs_sp: for ltpl in seg: self.assertLessEqual(sum(1 for l in ltpl if isinstance(l, ConvLayer)), 1) self.assertTrue(segs_sp.issuperset(segs_n)) # Temporal pipelining. options = Option(hw_gbuf_save_writeback=True) segs_tp_lst = list(ilp.gen_segment(options)) segs_tp = set(segs_tp_lst) self.assertEqual(len(segs_tp_lst), len(segs_tp)) for seg in segs_tp: self.assertEqual(len(seg), 1) self.assertTrue(segs_tp.issuperset(segs_n)) # Spatial and temporal pipelining. options = Option(partition_interlayer=True, hw_gbuf_save_writeback=True) segs_stp_lst = list(ilp.gen_segment(options)) segs_stp = set(segs_stp_lst) self.assertEqual(len(segs_stp_lst), len(segs_stp)) self.assertSetEqual(segs_stp, segs_tp | segs_sp) # Only single-layer and single-vertex segments have the same # spatial and temporal pipelining. segs_intersect = segs_tp & segs_sp segs_single = segs_n segs_single |= set(PipelineSegment((v,), ilp.network, ilp.batch_size, ilp.resource) for v in ilp.dag_vertex_list) self.assertTrue(segs_intersect.issubset(segs_single))
def _gen_all_segment(self, network, **kwargs): ''' Generate all segments directly from all layers and all vertex segments. ''' # pylint: disable=protected-access ilp = self._make_ilp(network) for layer in network: yield PipelineSegment(((layer, ), ), ilp.network, ilp.batch_size, ilp.resource) for vseg in ilp._gen_vseg(): segment = self._make_segment(vseg, network, **kwargs) if len(segment) == 1 and len(segment[0]) == 1: continue yield segment
def _make_segment(self, vseg, network, temporal=False, max_util_drop=None, with_opt=True): ''' Convert vertex segment to (layer) segment. ''' kwargs = {} if max_util_drop is not None: kwargs['max_util_drop'] = max_util_drop if not with_opt: kwargs['with_opt'] = False ilp = self._make_ilp(network) seg = tuple(ilp.dag_vertex_list[vidx] for vidx in vseg) if temporal: seg = (sum(seg, tuple()), ) return PipelineSegment(seg, ilp.network, ilp.batch_size, ilp.resource, **kwargs)
def test_gen_segment_resnet(self): ''' gen_segment() with ResNet. ''' net = self.net['resnet152'] ilp = self._make_ilp(net) options = Option(partition_interlayer=True) # One residual module fits. segment = PipelineSegment( (('conv3_2_a',), ('conv3_2_b',), ('conv3_2_c', 'conv3_2_res')), ilp.network, ilp.batch_size, ilp.resource) self.assertTupleEqual(net.prevs('conv3_2_res'), ('conv3_1_res', 'conv3_2_c')) self.assertTrue(segment.valid) segs = set(seg.seg for seg in ilp.gen_segment(options)) self.assertIn(segment.seg, segs)
def test_gen_constraint_fbofm_init(self): ''' gen_constraint() deciding fbofm_init. ''' net = self.net['zfnet'] # Two spatial, fbofm_init == False. segment = PipelineSegment((('fc2',), ('fc3',)), net, self.batch_size, self.resource) self.assertTrue(segment.valid) self.assertFalse(segment.cstr_symargs[0][0].get('fbofm', False)) self.assertFalse(segment.cstr_symargs[1][0].get('fbifm', False)) # Two spatial, fbofm_init == False. segment = PipelineSegment((('conv5', 'pool3'), ('fc1',)), net, self.batch_size, self.resource) self.assertTrue(segment.valid) self.assertFalse(segment.cstr_symargs[0][0].get('fbofm', False)) self.assertFalse(segment.cstr_symargs[0][1].get('fbofm', False)) self.assertFalse(segment.cstr_symargs[1][0].get('fbifm', False)) # Four spatial, fbofm_init == False. segment = PipelineSegment((('conv1', 'pool1'), ('conv2', 'pool2'), ('conv3',), ('conv4',)), net, self.batch_size, self.resource) self.assertTrue(segment.valid) self.assertFalse(segment.cstr_symargs[0][0].get('fbofm', False)) self.assertFalse(segment.cstr_symargs[0][1].get('fbofm', False)) self.assertFalse(segment.cstr_symargs[1][0].get('fbifm', False)) self.assertTrue(segment.cstr_symargs[1][0]['fbofm']) self.assertTrue(segment.cstr_symargs[1][1]['fbofm']) self.assertTrue(segment.cstr_symargs[2][0]['fbifm']) self.assertFalse(segment.cstr_symargs[2][0].get('fbofm', False)) self.assertFalse(segment.cstr_symargs[3][0].get('fbifm', False)) # Three spatial, fbofm_init == False. segment = PipelineSegment((('conv4',), ('conv5', 'pool3'), ('fc1',)), net, self.batch_size, self.resource) self.assertTrue(segment.valid) self.assertFalse(segment.cstr_symargs[0][0].get('fbofm', False)) self.assertFalse(segment.cstr_symargs[1][0].get('fbifm', False)) self.assertTrue(segment.cstr_symargs[1][0]['fbofm']) self.assertTrue(segment.cstr_symargs[1][1]['fbofm']) self.assertTrue(segment.cstr_symargs[2][0]['fbifm']) # Three spatial, fbofm_init == False. segment = PipelineSegment((('conv2', 'pool2'), ('conv3',), ('conv4',)), net, self.batch_size, self.resource) self.assertTrue(segment.valid) self.assertFalse(segment.cstr_symargs[0][0].get('fbofm', False)) self.assertFalse(segment.cstr_symargs[0][1].get('fbofm', False)) self.assertFalse(segment.cstr_symargs[1][0].get('fbifm', False)) self.assertTrue(segment.cstr_symargs[1][0]['fbofm']) self.assertTrue(segment.cstr_symargs[2][0]['fbifm']) # Three spatial, fbofm_init == True. segment = PipelineSegment((('conv3',), ('conv4',), ('conv5', 'pool3')), net, self.batch_size, self.resource) self.assertTrue(segment.valid) self.assertTrue(segment.cstr_symargs[0][0]['fbofm']) self.assertTrue(segment.cstr_symargs[1][0]['fbifm']) self.assertFalse(segment.cstr_symargs[1][0].get('fbofm', False)) self.assertFalse(segment.cstr_symargs[2][0].get('fbifm', False))