def test_add_invalid_type(self): ''' Modifier add invalid type. ''' network = Network('test_net') network.set_input(InputLayer(3, 224)) with self.assertRaisesRegexp(TypeError, 'Network: .*Layer.*'): network.add('c1', (3, 64, 224, 3))
def test_set_input_type(self): ''' Modifier set_input type. ''' network = Network('test_net') with self.assertRaisesRegexp(TypeError, 'Network: .*input_layer.*'): network.set_input(Layer(3, 24)) with self.assertRaisesRegexp(TypeError, 'Network: .*input_layer.*'): network.set_input(ConvLayer(3, 8, 24, 3))
def test_add_unmatch_prev(self): ''' Modifier add unmatch prevs. ''' network = Network('test_net') network.set_input(InputLayer(3, 224)) network.add('c1', ConvLayer(3, 64, 224, 3)) with self.assertRaisesRegexp(ValueError, 'Network: .*c1.*p1.*mismatch fmap.*'): network.add('p1', PoolingLayer(64, 7, 2)) self.assertEqual(len(network), 1) with self.assertRaisesRegexp(ValueError, 'Network: .*c1.*c2.*mismatch fmap.*'): network.add('c2', ConvLayer(64, 128, 220, 3)) self.assertEqual(len(network), 1) with self.assertRaisesRegexp(ValueError, 'Network: .*merge.*c1.*p1.*'): network.add('p1', PoolingLayer(32, 7, 32)) self.assertEqual(len(network), 1) with self.assertRaisesRegexp(ValueError, 'Network: .*merge.*c1.*c2.*'): network.add('c2', ConvLayer(32, 128, 224, 3)) self.assertEqual(len(network), 1) network.add('c2', ConvLayer(64, 128, 224, 3)) with self.assertRaisesRegexp(ValueError, r'Network: .*merge.*c1\s*c2.*p1.*'): network.add('p1', PoolingLayer(128, 7, 32), prevs=('c1', 'c2')) self.assertEqual(len(network), 2)
def test_add_no_prev(self): ''' Modifier add no prevs. ''' network = Network('test_net') network.set_input(InputLayer(3, 224)) network.add('c1', ConvLayer(3, 64, 224, 3)) with self.assertRaisesRegexp(KeyError, 'Network: .*prev.*p1.*'): network.add('p1', PoolingLayer(64, 7, 32), prevs='p1')
def test_add_same_key(self): ''' Modifier add same key. ''' network = Network('test_net') network.set_input(InputLayer(3, 224)) network.add('c1', ConvLayer(3, 64, 224, 3)) with self.assertRaisesRegexp(KeyError, 'Network: .*c1.*'): network.add('c1', ConvLayer(64, 128, 224, 3))
def test_set_input(self): ''' Modifier set_input. ''' network = Network('test_net') network.set_input(InputLayer(3, 24)) self.assertIsInstance(network.input_layer(), InputLayer) self.assertEqual(network.input_layer().nofm, 3) self.assertEqual(network.input_layer().hofm, 24) self.assertEqual(network.input_layer().wofm, 24) self.assertEqual(len(network), 0)
def MLP_network(input_size, hiden_fc1, hiden_fc2, hiden_fc3, output_size): NN = Network('MLP_L') NN.set_input(InputLayer(input_size, 1)) NN.add('fc1', FCLayer(input_size, hiden_fc1)) NN.add('fc2', FCLayer(hiden_fc1, hiden_fc2)) NN.add('fc3', FCLayer(hiden_fc2, hiden_fc3)) NN.add('fc4', FCLayer(hiden_fc3, output_size)) return NN
def test_iter(self): ''' Accessor iter. ''' num = 0 for layer in self.network: self.assertIn(layer, self.network) self.assertIsInstance(self.network[layer], Layer) num += 1 self.assertEqual(len(self.network), num) network = Network('test_net') network.set_input(InputLayer(3, 224)) with self.assertRaises(StopIteration): _ = next(iter(network))
def test_len(self): ''' Accessor len. ''' self.assertEqual(len(self.network), 3) network = Network('test_net') self.assertEqual(len(network), 0) network.set_input(InputLayer(3, 224)) self.assertEqual(len(network), 0) network.add('c1', ConvLayer(3, 4, 224, 1)) self.assertEqual(len(network), 1) self.network.add('f2', FCLayer(64, 2000, 7), prevs='p1') self.assertEqual(len(self.network), 4) self.network.add('f3', FCLayer(3000, 1000), prevs=('f1', 'f2')) self.assertEqual(len(self.network), 5) self.network.add('f4', FCLayer(1000, 1000), prevs=('f1', 'f3')) self.assertEqual(len(self.network), 6)
TETRIS paper ("TETRIS: Scalable and Efficient Neural Network Acceleration with 3D Memory", in ASPLOS'17. April, 2017), and that you send us a citation of your work. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the BSD-3 License for more details. You should have received a copy of the Modified BSD-3 License along with this program. If not, see <https://opensource.org/licenses/BSD-3-Clause>. """ from nn_dataflow.core import Network from nn_dataflow.core import InputLayer, FCLayer ''' MLP-M PRIME, 2016 ''' NN = Network('MLP-M') NN.set_input(InputLayer(784, 1)) NN.add('fc1', FCLayer(784, 1000)) NN.add('fc2', FCLayer(1000, 500)) NN.add('fc3', FCLayer(500, 250)) NN.add('fc4', FCLayer(250, 10))
You should have received a copy of the Modified BSD-3 License along with this program. If not, see <https://opensource.org/licenses/BSD-3-Clause>. """ from nn_dataflow.core import Network from nn_dataflow.core import InputLayer, ConvLayer, PoolingLayer ''' ResNet-152 He, Zhang, Ren, and Sun, 2015 ''' NN = Network('ResNet') NN.set_input(InputLayer(3, 224)) _PREVS = None NN.add('conv1', ConvLayer(3, 64, 112, 7, 2)) NN.add('pool1', PoolingLayer(64, 56, 2)) for i in range(1, 4): NN.add('conv2_{}_a'.format(i), ConvLayer(64, 64, 56, 1) if i == 1 else ConvLayer(256, 64, 56, 1), prevs=_PREVS) NN.add('conv2_{}_b'.format(i), ConvLayer(64, 64, 56, 3)) NN.add('conv2_{}_c'.format(i), ConvLayer(64, 256, 56, 1)) # With residual shortcut. if i == 1:
def test_set_input_duplicate(self): ''' Modifier set_input duplicate. ''' network = Network('test_net') network.set_input(InputLayer(3, 24)) with self.assertRaisesRegexp(KeyError, 'Network: .*input.*'): network.set_input(InputLayer(3, 24))
class TestNetwork(unittest.TestCase): ''' Tests for Network. ''' # pylint: disable=too-many-public-methods def setUp(self): ''' Set up. ''' self.network = Network('test_net') self.network.set_input(InputLayer(3, 224)) self.network.add('c1', ConvLayer(3, 64, 224, 3)) self.network.add('p1', PoolingLayer(64, 7, 32)) self.network.add('f1', FCLayer(64, 1000, 7)) def test_set_input(self): ''' Modifier set_input. ''' network = Network('test_net') network.set_input(InputLayer(3, 24)) self.assertIsInstance(network.input_layer(), InputLayer) self.assertEqual(network.input_layer().nofm, 3) self.assertEqual(network.input_layer().hofm, 24) self.assertEqual(network.input_layer().wofm, 24) self.assertEqual(len(network), 0) def test_set_input_type(self): ''' Modifier set_input type. ''' network = Network('test_net') with self.assertRaisesRegexp(TypeError, 'Network: .*input_layer.*'): network.set_input(Layer(3, 24)) with self.assertRaisesRegexp(TypeError, 'Network: .*input_layer.*'): network.set_input(ConvLayer(3, 8, 24, 3)) def test_set_input_duplicate(self): ''' Modifier set_input duplicate. ''' network = Network('test_net') network.set_input(InputLayer(3, 24)) with self.assertRaisesRegexp(KeyError, 'Network: .*input.*'): network.set_input(InputLayer(3, 24)) def test_add(self): ''' Modifier add. ''' self.assertEqual(len(self.network), 3) self.network.add('f2', FCLayer(64, 2000, 7), prevs='p1') self.network.add('f3', FCLayer(3000, 1000), prevs=('f1', 'f2')) self.network.add('f4', FCLayer(1000, 1000), prevs=('f1', 'f3')) self.assertEqual(len(self.network), 6) def test_add_same_key(self): ''' Modifier add same key. ''' network = Network('test_net') network.set_input(InputLayer(3, 224)) network.add('c1', ConvLayer(3, 64, 224, 3)) with self.assertRaisesRegexp(KeyError, 'Network: .*c1.*'): network.add('c1', ConvLayer(64, 128, 224, 3)) def test_add_no_input(self): ''' Modifier add no input. ''' network = Network('test_net') with self.assertRaisesRegexp(RuntimeError, 'Network: .*input.*'): network.add('c1', ConvLayer(3, 64, 224, 3)) def test_add_no_prev(self): ''' Modifier add no prevs. ''' network = Network('test_net') network.set_input(InputLayer(3, 224)) network.add('c1', ConvLayer(3, 64, 224, 3)) with self.assertRaisesRegexp(KeyError, 'Network: .*prev.*p1.*'): network.add('p1', PoolingLayer(64, 7, 32), prevs='p1') def test_add_invalid_type(self): ''' Modifier add invalid type. ''' network = Network('test_net') network.set_input(InputLayer(3, 224)) with self.assertRaisesRegexp(TypeError, 'Network: .*Layer.*'): network.add('c1', (3, 64, 224, 3)) def test_add_unmatch_prev(self): ''' Modifier add unmatch prevs. ''' network = Network('test_net') network.set_input(InputLayer(3, 224)) network.add('c1', ConvLayer(3, 64, 224, 3)) with self.assertRaisesRegexp(ValueError, 'Network: .*c1.*p1.*mismatch fmap.*'): network.add('p1', PoolingLayer(64, 7, 2)) self.assertEqual(len(network), 1) with self.assertRaisesRegexp(ValueError, 'Network: .*c1.*c2.*mismatch fmap.*'): network.add('c2', ConvLayer(64, 128, 220, 3)) self.assertEqual(len(network), 1) with self.assertRaisesRegexp(ValueError, 'Network: .*merge.*c1.*p1.*'): network.add('p1', PoolingLayer(32, 7, 32)) self.assertEqual(len(network), 1) with self.assertRaisesRegexp(ValueError, 'Network: .*merge.*c1.*c2.*'): network.add('c2', ConvLayer(32, 128, 224, 3)) self.assertEqual(len(network), 1) network.add('c2', ConvLayer(64, 128, 224, 3)) with self.assertRaisesRegexp(ValueError, r'Network: .*merge.*c1\s*c2.*p1.*'): network.add('p1', PoolingLayer(128, 7, 32), prevs=('c1', 'c2')) self.assertEqual(len(network), 2) def test_prev_layers(self): ''' Get prev_layers. ''' self.network.add('f2', FCLayer(64, 2000, 7), prevs='p1') self.network.add('f3', FCLayer(3000, 1000), prevs=('f1', 'f2')) self.network.add('f4', FCLayer(1000, 1000), prevs=('f1', 'f3')) prevs, symbol = self.network.prev_layers('f1') self.assertTupleEqual(prevs, ('p1', )) self.assertEqual(symbol, '|') prevs, symbol = self.network.prev_layers('f2') self.assertTupleEqual(prevs, ('p1', )) self.assertEqual(symbol, '|') prevs, symbol = self.network.prev_layers('f3') self.assertTupleEqual(prevs, ('f1', 'f2')) self.assertEqual(symbol, '|') prevs, symbol = self.network.prev_layers('f4') self.assertTupleEqual(prevs, ('f1', 'f3')) self.assertEqual(symbol, '+') def test_prev_layers_first(self): ''' Get prev_layers first layer. ''' self.network.add('c2', ConvLayer(3, 3, 224, 1), prevs=self.network.INPUT_LAYER_KEY) self.network.add('c3', ConvLayer(3, 4, 224, 1), prevs=(self.network.INPUT_LAYER_KEY, 'c2')) prevs, symbol = self.network.prev_layers('c1') self.assertTupleEqual(prevs, (None, )) self.assertEqual(symbol, '|') prevs, symbol = self.network.prev_layers('c2') self.assertTupleEqual(prevs, (None, )) self.assertEqual(symbol, '|') prevs, symbol = self.network.prev_layers('c3') self.assertTupleEqual(prevs, (None, 'c2')) self.assertEqual(symbol, '+') def test_prev_layers_input(self): ''' Get prev_layers input layer. ''' with self.assertRaisesRegexp(ValueError, 'Network: .*input.*'): _ = self.network.prev_layers(self.network.INPUT_LAYER_KEY) def test_next_layers(self): ''' Get next_layers. ''' self.network.add('f2', FCLayer(64, 2000, 7), prevs='p1') self.network.add('f3', FCLayer(3000, 1000), prevs=('f1', 'f2')) self.network.add('f4', FCLayer(1000, 1000), prevs=('f1', 'f3')) nexts = self.network.next_layers('p1') self.assertTupleEqual(nexts, ('f1', 'f2')) nexts = self.network.next_layers('f1') self.assertTupleEqual(nexts, ('f3', 'f4')) nexts = self.network.next_layers('f2') self.assertTupleEqual(nexts, ('f3', )) nexts = self.network.next_layers('f3') self.assertTupleEqual(nexts, ('f4', )) def test_next_layers_last(self): ''' Get next_layers first layer. ''' nexts = self.network.next_layers('f1') self.assertTupleEqual(nexts, (None, )) self.network.add('f2', FCLayer(64, 2000, 7), prevs='p1') nexts = self.network.next_layers('f1') self.assertTupleEqual(nexts, (None, )) nexts = self.network.next_layers('f2') self.assertTupleEqual(nexts, (None, )) def test_next_layers_input(self): ''' Get next_layers input layer. ''' nexts = self.network.next_layers(self.network.INPUT_LAYER_KEY) self.assertTupleEqual(nexts, ('c1', )) self.network.add('c2', ConvLayer(3, 3, 224, 1), prevs=self.network.INPUT_LAYER_KEY) self.network.add('c3', ConvLayer(3, 4, 224, 1), prevs=(self.network.INPUT_LAYER_KEY, 'c2')) nexts = self.network.next_layers(self.network.INPUT_LAYER_KEY) self.assertTupleEqual(nexts, ('c1', 'c2', 'c3')) def test_first_layers(self): ''' Get first_layers. ''' firsts = self.network.first_layers() self.assertTupleEqual(firsts, ('c1', )) self.network.add('c2', ConvLayer(3, 3, 224, 1), prevs=self.network.INPUT_LAYER_KEY) self.network.add('c3', ConvLayer(3, 4, 224, 1), prevs=(self.network.INPUT_LAYER_KEY, 'c2')) firsts = self.network.first_layers() self.assertTupleEqual(firsts, ('c1', 'c2')) self.assertIn('c1', firsts) self.assertNotIn('c3', firsts) def test_last_layers(self): ''' Get last_layers. ''' lasts = self.network.last_layers() self.assertTupleEqual(lasts, ('f1', )) self.network.add('f2', FCLayer(64, 2000, 7), prevs='p1') lasts = self.network.last_layers() self.assertTupleEqual(lasts, ('f1', 'f2')) def test_contains(self): ''' Whether contains. ''' self.assertIn('c1', self.network) self.assertIn('p1', self.network) self.assertIn('f1', self.network) self.assertNotIn('f2', self.network) self.network.add('f2', FCLayer(64, 2000, 7), prevs='p1') self.assertIn('f2', self.network) def test_len(self): ''' Accessor len. ''' self.assertEqual(len(self.network), 3) network = Network('test_net') self.assertEqual(len(network), 0) network.set_input(InputLayer(3, 224)) self.assertEqual(len(network), 0) network.add('c1', ConvLayer(3, 4, 224, 1)) self.assertEqual(len(network), 1) self.network.add('f2', FCLayer(64, 2000, 7), prevs='p1') self.assertEqual(len(self.network), 4) self.network.add('f3', FCLayer(3000, 1000), prevs=('f1', 'f2')) self.assertEqual(len(self.network), 5) self.network.add('f4', FCLayer(1000, 1000), prevs=('f1', 'f3')) self.assertEqual(len(self.network), 6) def test_iter(self): ''' Accessor iter. ''' num = 0 for layer in self.network: self.assertIn(layer, self.network) self.assertIsInstance(self.network[layer], Layer) num += 1 self.assertEqual(len(self.network), num) network = Network('test_net') network.set_input(InputLayer(3, 224)) with self.assertRaises(StopIteration): _ = next(iter(network)) def test_getitem(self): ''' Accessor getitem. ''' self.assertIsInstance(self.network['c1'], ConvLayer) self.assertIsInstance(self.network['p1'], PoolingLayer) self.assertIsInstance(self.network['f1'], FCLayer) def test_getitem_error(self): ''' Accessor getitem. ''' with self.assertRaisesRegexp(KeyError, 'Network: .*c2.*'): _ = self.network['c2'] def test_str(self): ''' Accessor str. ''' string = str(self.network) for layer in self.network: self.assertIn(layer, string)
class TestNNDataflowScheme(unittest.TestCase): ''' Tests for NNDataflowScheme. ''' def setUp(self): self.network = Network('test_net') self.network.set_input(InputLayer(3, 224)) self.network.add('c1', ConvLayer(3, 64, 224, 3)) self.network.add('p1', PoolingLayer(64, 7, 32), prevs='c1') self.network.add('p2', PoolingLayer(64, 7, 32), prevs='c1') self.network.add('f1', FCLayer(64, 1000, 7), prevs=['p1', 'p2']) self.batch_size = 4 self.input_layout = partition.get_ofmap_layout( self.network.input_layer(), self.batch_size, PartitionScheme(order=range(pe.NUM), pdims=[(1, 1)] * pe.NUM), NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(2, 1), type=NodeRegion.DATA)) self.c1res = SchedulingResult( dict_loop=OrderedDict([('cost', 1.), ('time', 2.), ('ops', 4.), ('access', [[7, 8, 9]] * me.NUM), ]), dict_part=OrderedDict([('cost', 0.5), ('total_nhops', [4, 5, 6]), ('num_nodes', 4), ]), ofmap_layout=partition.get_ofmap_layout( self.network['c1'], self.batch_size, PartitionScheme(order=range(pe.NUM), pdims=[(1, 1)] * pe.NUM), NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(1, 2), type=NodeRegion.DATA))) self.pres = SchedulingResult( dict_loop=OrderedDict([('cost', 0.1), ('time', 0.05), ('ops', 0.1), ('access', [[.7, .8, .9]] * me.NUM), ]), dict_part=OrderedDict([('cost', 0.5), ('total_nhops', [.4, .5, .6]), ('num_nodes', 2), ]), ofmap_layout=partition.get_ofmap_layout( self.network['p1'], self.batch_size, PartitionScheme(order=range(pe.NUM), pdims=[(1, 1)] * pe.NUM), NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(1, 2), type=NodeRegion.DATA))) self.dtfl = NNDataflowScheme(self.network, self.input_layout) self.dtfl['c1'] = self.c1res self.dtfl['p1'] = self.pres self.dtfl['p2'] = self.pres def test_init(self): ''' Initial. ''' df = NNDataflowScheme(self.network, self.input_layout) self.assertEqual(df.network, self.network) self.assertEqual(df.input_layout, self.input_layout) self.assertEqual(df.total_cost, 0) self.assertEqual(df.total_time, 0) self.assertFalse(df.res_dict) self.assertFalse(df) self.assertEqual(df.total_ops, 0) self.assertSequenceEqual(df.total_accesses, [0] * me.NUM) self.assertEqual(df.total_noc_hops, 0) def test_init_invalid_network(self): ''' Invalid network. ''' with self.assertRaisesRegexp(TypeError, 'NNDataflowScheme: .*network*'): _ = NNDataflowScheme(self.network['c1'], self.input_layout) def test_init_invalid_input_layout(self): ''' Invalid input_layout. ''' with self.assertRaisesRegexp(TypeError, 'NNDataflowScheme: .*input_layout*'): _ = NNDataflowScheme(self.network, self.input_layout.frmap) def test_setgetitem(self): ''' __set/getitem__. ''' df = NNDataflowScheme(self.network, self.input_layout) df['c1'] = self.c1res self.assertEqual(df['c1'], self.c1res) def test_getitem_not_in(self): ''' __getitem__ not in. ''' df = NNDataflowScheme(self.network, self.input_layout) with self.assertRaises(KeyError): _ = df['c1'] def test_setitem_not_in_network(self): ''' __setitem__ not in network. ''' df = NNDataflowScheme(self.network, self.input_layout) with self.assertRaisesRegexp(KeyError, 'NNDataflowScheme: .*cc.*'): df['cc'] = self.c1res def test_setitem_invalid_value(self): ''' __setitem__ invalid value. ''' df = NNDataflowScheme(self.network, self.input_layout) with self.assertRaisesRegexp(TypeError, 'NNDataflowScheme: .*SchedulingResult*'): df['c1'] = self.c1res.dict_loop def test_setitem_already_exists(self): ''' __setitem__ already exists. ''' df = NNDataflowScheme(self.network, self.input_layout) df['c1'] = self.c1res with self.assertRaisesRegexp(KeyError, 'NNDataflowScheme: .*c1*'): df['c1'] = self.c1res def test_setitem_prev_not_in(self): ''' __setitem__ already exists. ''' df = NNDataflowScheme(self.network, self.input_layout) with self.assertRaisesRegexp(KeyError, 'NNDataflowScheme: .*p1*'): df['p1'] = self.pres def test_delitem(self): ''' __delitem__. ''' df = NNDataflowScheme(self.network, self.input_layout) df['c1'] = self.c1res with self.assertRaisesRegexp(KeyError, 'NNDataflowScheme: .*'): del df['c1'] def test_iter_len(self): ''' __iter__ and __len__. ''' self.assertEqual(len(self.dtfl), 3) lst = [l for l in self.dtfl] self.assertIn('c1', lst) self.assertIn('p1', lst) self.assertIn('p2', lst) self.assertNotIn('f1', lst) def test_copy(self): ''' copy. ''' df = self.dtfl df2 = df.copy() self.assertAlmostEqual(df.total_cost, df2.total_cost) self.assertAlmostEqual(df.total_time, df2.total_time) self.assertDictEqual(df.res_dict, df2.res_dict) # Shallow copy. for layer_name in df: self.assertEqual(id(df[layer_name]), id(df2[layer_name])) def test_properties(self): ''' Property accessors. ''' self.assertAlmostEqual(self.dtfl.total_cost, 1.5 + 0.6 * 2) self.assertAlmostEqual(self.dtfl.total_time, 2 + 0.05 * 2) self.assertAlmostEqual(self.dtfl.total_ops, 4 + 0.1 * 2) for a in self.dtfl.total_accesses: self.assertAlmostEqual(a, (7 + 8 + 9) + (.7 + .8 + .9) * 2) self.assertAlmostEqual(self.dtfl.total_noc_hops, (4 + 5 + 6) + (.4 + .5 + .6) * 2) self.assertAlmostEqual(self.dtfl.total_node_time, 2 * 4 + 0.05 * 2 * 2) def test_stats_active_node_pes(self): ''' Per-layer stats: active node PEs. ''' stats = self.dtfl.perlayer_stats('active_node_pes') self.assertEqual(len(stats), len(self.dtfl)) self.assertAlmostEqual(stats['c1'], 0.5) self.assertAlmostEqual(stats['p1'], 1) self.assertAlmostEqual(stats['p2'], 1) def test_stats_total_dram_bw(self): ''' Per-layer stats: total DRAM bandwidth. ''' stats = self.dtfl.perlayer_stats('total_dram_bandwidth') self.assertEqual(len(stats), len(self.dtfl)) self.assertAlmostEqual(stats['c1'], (7 + 8 + 9) / 2.) self.assertAlmostEqual(stats['p1'], (.7 + .8 + .9) / 0.05) self.assertAlmostEqual(stats['p2'], (.7 + .8 + .9) / 0.05) def test_stats_not_supported(self): ''' Per-layer stats: not supported. ''' with self.assertRaisesRegexp(AttributeError, 'NNDataflowScheme: .*not_supported.*'): _ = self.dtfl.perlayer_stats('not_supported')