def test_add_same_key(self): ''' Modifier add same key. ''' network = Network('test_net') network.set_input_layer(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_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 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_vertex_no_merge_lr(self): ''' LocalRegionLayer has no previous layer to merge with. ''' net = Network('tmp_net') net.set_input_layer(InputLayer(30, 1)) net.add('0', PoolingLayer(30, 1, 1)) net.add('1', FCLayer(30, 40)) net.add('1p', PoolingLayer(40, 1, 1)) ilp = self._make_ilp(net) for layer in net: vidx = ilp.dag_vertex_dict[layer] self.assertIn(layer, ilp.dag_vertex_list[vidx]) # Layer is named by topological order. self.assertTrue(layer.startswith(str(vidx)))
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 setUp(self): self.alex_net = import_network('alex_net') self.vgg_net = import_network('vgg_net') net = Network('simple') net.set_input_layer(InputLayer(4, 2)) net.add('1', ConvLayer(4, 4, 2, 1)) net.add('2', ConvLayer(4, 4, 2, 1)) # Two more layers to avoid single-segment case. net.add('a1', ConvLayer(4, 1, 1, 1, strd=2)) net.add('a2', ConvLayer(1, 1, 1, 1)) self.simple_net = net net = Network('complex') net.set_input_layer(InputLayer(8, 8)) net.add('1', ConvLayer(8, 8, 8, 1)) net.add('2a', ConvLayer(8, 8, 8, 1), prevs=('1',)) net.add('3a', ConvLayer(8, 8, 8, 1)) net.add('2b', ConvLayer(8, 8, 8, 1), prevs=('1',)) net.add('3b', ConvLayer(8, 8, 8, 1)) net.add('4', ConvLayer(16, 8, 8, 1), prevs=('3a', '3b')) self.complex_net = net self.map_strategy = MapStrategyEyeriss 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=128 * 1024 // 2, # 128 kB size_regf=512 // 2, # 512 B array_bus_width=float('inf'), dram_bandwidth=float('inf'), no_time_mux=False, ) self.cost = Cost(mac_op=1, mem_hier=(200, 6, 2, 1), noc_hop=0, idl_unit=0) self.options = Option()
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)
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 from nn_dataflow.nns import add_lstm_cell ''' LSTM for phoneme classification. Graves and Schmidhuber, 2005 ''' NN = Network('PHONEME') NN.set_input_layer(InputLayer(26, 1)) # Input. NN.add('We', FCLayer(26, 140), prevs=(NN.INPUT_LAYER_KEY, )) # LSTM. C, H = add_lstm_cell(NN, 'cell', 140, 'We') # Output. NN.add('Wd', FCLayer(140, 61), prevs=(H, ))
def setUp(self): self.net = {} net = Network('net1') # Linear. net.set_input_layer(InputLayer(10, 1)) net.add('0', FCLayer(10, 20)) net.add('1', FCLayer(20, 30)) net.add('1p', PoolingLayer(30, 1, 1)) net.add('2', FCLayer(30, 40)) net.add('3', FCLayer(40, 50)) self.net[net.net_name] = net net = Network('net2') # Long linear. net.set_input_layer(InputLayer(1, 1)) for idx in range(16): net.add(str(idx), FCLayer(1, 1)) self.net[net.net_name] = net net = Network('net3') # Fork. # /0-2\ /6- 7- 8\ # x 4-5 12 # \1-3/ \9-10-11/ net.set_input_layer(InputLayer(1, 1)) net.add('0', FCLayer(1, 1), prevs=net.INPUT_LAYER_KEY) net.add('1', FCLayer(1, 1), prevs=net.INPUT_LAYER_KEY) net.add('2', FCLayer(2, 1), prevs=('0', '1')) net.add('2p', PoolingLayer(1, 1, 1)) net.add('3', FCLayer(2, 1), prevs=('0', '1')) net.add('4', FCLayer(2, 1), prevs=('2p', '3')) net.add('5', FCLayer(1, 1)) net.add('5p', PoolingLayer(1, 1, 1)) net.add('6', FCLayer(1, 1), prevs='5p') net.add('7', FCLayer(1, 1)) net.add('8', FCLayer(1, 1)) net.add('9', FCLayer(1, 1), prevs='5p') net.add('10', FCLayer(1, 1)) net.add('11', FCLayer(1, 1)) net.add('12', FCLayer(2, 1), prevs=('8', '11')) self.net[net.net_name] = net net = Network('net4') # Complex fork. # /5 \ # 0-1-2-3-4-6-7-8-10-14 # \9/ # \11-12 / # \13 / net.set_input_layer(InputLayer(1, 1)) net.add('0', FCLayer(1, 1)) net.add('1', FCLayer(1, 1)) net.add('2', FCLayer(1, 1)) net.add('3', FCLayer(1, 1)) net.add('4', FCLayer(1, 1)) net.add('5', FCLayer(1, 1), prevs='4') net.add('6', FCLayer(1, 1), prevs='4') net.add('7', FCLayer(1, 1)) net.add('8', FCLayer(1, 1), prevs='7') net.add('9', FCLayer(1, 1), prevs='7') net.add('10', FCLayer(1, 1)) net.add('10p', PoolingLayer(2, 1, 1), prevs=('8', '10')) net.add('11', PoolingLayer(1, 1, 1), prevs='4') net.add('12', FCLayer(1, 1)) net.add('13', PoolingLayer(1, 1, 1), prevs='4') net.add('14', FCLayer(5, 1), prevs=('5', '10p', '12', '13')) self.net[net.net_name] = net net = Network('net5') # Corner cases. # ----\ # //1-2\ 7-8\ # 0-3-4-x 10-11-12 # \ \5/ 9 / \__/ # 6--/ net.set_input_layer(InputLayer(1, 1)) net.add('0', FCLayer(1, 1)) net.add('1', FCLayer(1, 1), prevs='0') net.add('2', FCLayer(1, 1)) net.add('3', FCLayer(1, 1), prevs='0') net.add('4', FCLayer(1, 1), prevs='3') net.add('5', FCLayer(1, 1), prevs='3') net.add('6', FCLayer(1, 1), prevs='0') net.add('7', FCLayer(5, 1), prevs=('0', '2', '4', '5', '6')) net.add('8', FCLayer(1, 1)) net.add('9', FCLayer(5, 1), prevs=('0', '2', '4', '5', '6')) net.add('10', FCLayer(2, 1), prevs=('8', '9')) net.add('11', FCLayer(1, 1)) net.add('12', FCLayer(2, 1), prevs=('10', '11')) self.net[net.net_name] = net net = Network('net6') # Fmap sizes. net.set_input_layer(InputLayer(1, 24)) net.add('0', ConvLayer(1, 1, 24, 3)) net.add('1', ConvLayer(1, 1, 12, 3, strd=2)) net.add('1p', PoolingLayer(1, 6, 2)) net.add('2', ConvLayer(1, 1, 6, 3)) net.add('3', ConvLayer(1, 1, 6, 3, strd=4), prevs=('0')) self.net[net.net_name] = net net = Network('net7') # Topological order: see a visited vertex again. # /--- # 0-1-\\ # \2--2p net.set_input_layer(InputLayer(1, 1)) net.add('0', FCLayer(1, 1)) net.add('1', FCLayer(1, 1), prevs='0') net.add('2', FCLayer(1, 1), prevs='0') net.add('2p', PoolingLayer(3, 1, 1), prevs=('0', '1', '2')) self.net[net.net_name] = net net = Network('net8') # Forward to the middle. # /-\ # 0-1-2-2p-4-4p # \-3------/ net.set_input_layer(InputLayer(1, 1)) net.add('0', FCLayer(1, 1)) net.add('1', FCLayer(1, 1), prevs='0') net.add('2', FCLayer(1, 1), prevs='1') net.add('2p', PoolingLayer(2, 1, 1), prevs=('1', '2')) net.add('3', FCLayer(1, 1), prevs='0') net.add('4', FCLayer(2, 1), prevs='2p') net.add('4p', PoolingLayer(2, 1, 1), prevs=('3', '4')) self.net[net.net_name] = net net = Network('net9') # Previous layers include input and others. net.set_input_layer(InputLayer(1, 1)) net.add('0', FCLayer(1, 1)) net.add('1', FCLayer(2, 1), prevs=(net.INPUT_LAYER_KEY, '0')) self.net[net.net_name] = net # Real networks. for net_name in all_networks(): self.net[net_name] = import_network(net_name) self.batch_size = 16 self.resource = Resource( proc_region=NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(8, 8), type=NodeRegion.PROC), dram_region=NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(8, 8), type=NodeRegion.DRAM), src_data_region=NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(8, 4), type=NodeRegion.DRAM), dst_data_region=NodeRegion(origin=PhyDim2(0, 4), dim=PhyDim2(8, 4), 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) 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, ))
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)
Copyright (C) 2016-2020 by Tsinghua University and The Board of Trustees of Stanford University This program is free software: you can redistribute it and/or modify it under the terms of the Modified BSD-3 License as published by the Open Source Initiative. 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-S PRIME, 2016 ''' NN = Network('MLP-S') NN.set_input_layer(InputLayer(784, 1)) NN.add('fc1', FCLayer(784, 500)) NN.add('fc2', FCLayer(500, 250)) NN.add('fc3', FCLayer(250, 10))
""" from nn_dataflow.core import Network from nn_dataflow.core import InputLayer, ConvLayer, FCLayer, \ PoolingLayer, EltwiseLayer ''' ResNet-152 He, Zhang, Ren, and Sun, 2015 ''' NN = Network('ResNet') NN.set_input_layer(InputLayer(3, 224)) NN.add('conv1', ConvLayer(3, 64, 112, 7, 2)) NN.add('pool1', PoolingLayer(64, 56, 3, 2)) RES_PREV = 'pool1' for i in range(3): NN.add('conv2_{}_a'.format(i), ConvLayer(64 if i == 0 else 256, 64, 56, 1)) 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 == 0: NN.add('conv2_br', ConvLayer(64, 256, 56, 1), prevs=(RES_PREV, )) RES_PREV = 'conv2_br' NN.add('conv2_{}_res'.format(i), EltwiseLayer(256, 56, 2),
class TestPipelineSegmentTiming(TestPipelineFixture): ''' Tests for PipelineSegmentTiming. ''' def setUp(self): super(TestPipelineSegmentTiming, self).setUp() self.net1 = self.net['net1'] self.net4 = self.net['net4'] self.netlr = Network('net1') self.netlr.set_input_layer(InputLayer(10, 1)) self.netlr.add('0p1', PoolingLayer(10, 1, 1)) self.netlr.add('0p2', PoolingLayer(10, 1, 1)) self.netlr.add('0p3', PoolingLayer(10, 1, 1)) self.netlr.add('1', FCLayer(10, 20)) def test_valid_args(self): ''' Valid arguments. ''' timing = PipelineSegmentTiming(self.net1, 3) self.assertIs(timing.network, self.net1) self.assertEqual(timing.seg_idx, 3) def test_invalid_network(self): ''' Invalid network. ''' with self.assertRaisesRegex(TypeError, 'PipelineSegmentTiming: .*network.*'): _ = PipelineSegmentTiming(self.net1.input_layer(), 3) def test_add(self): ''' add(). ''' # No fused. timing = PipelineSegmentTiming(self.net1, 3) timing.add('0', self._make_sched_res((3, 0, 0), 123, top_to=3, top_tb=2)) self.assertTupleEqual(timing.last_sched_seq, (3, 0, 0)) self.assertEqual(timing.timing_list[-1][-1].ngrp, 3) timing.add('1', self._make_sched_res((3, 1, 0), 141, top_ti=3, top_tb=2)) self.assertTupleEqual(timing.last_sched_seq, (3, 1, 0)) self.assertEqual(timing.timing_list[-1][-1].ngrp, 1) timing.add('1p', self._make_sched_res((3, 1, 1), 12, top_ti=3, top_tb=2)) self.assertTupleEqual(timing.last_sched_seq, (3, 1, 1)) self.assertEqual(timing.timing_list[-1][-1].ngrp, 1) self.assertEqual(timing.bat_ngrp, 2) self.assertEqual(len(timing.timing_list), 2) self.assertEqual(len(timing.timing_list[0]), 1) self.assertEqual(len(timing.timing_list[1]), 2) # Fused. timing = PipelineSegmentTiming(self.net1, 3) timing.add('0', self._make_sched_res((3, 0, 0), 123, top_tb=2)) self.assertTupleEqual(timing.last_sched_seq, (3, 0, 0)) self.assertEqual(timing.timing_list[-1][-1].ngrp, 1) timing.add('1', self._make_sched_res((3, 1, 0), 141, top_to=3, top_tb=2)) self.assertTupleEqual(timing.last_sched_seq, (3, 1, 0)) self.assertEqual(timing.timing_list[-1][-1].ngrp, 3) timing.add('1p', self._make_sched_res((3, 1, 1), 12, top_to=3, top_tb=2)) self.assertTupleEqual(timing.last_sched_seq, (3, 1, 1)) self.assertEqual(timing.timing_list[-1][-1].ngrp, 3) # Unmatched BAT group number. self.assertEqual(timing.bat_ngrp, 2) timing.add('2', self._make_sched_res((3, 2, 0), 123, top_tb=4)) self.assertEqual(timing.bat_ngrp, 1) def test_add_all_lr(self): ''' add() all LocalRegionLayer. ''' timing = PipelineSegmentTiming(self.netlr, 2) timing.add('0p1', self._make_sched_res((2, 0, 0), 40, top_to=4)) self.assertEqual(timing.timing_list[-1][-1].ngrp, 4) timing.add('0p2', self._make_sched_res((2, 0, 1), 80, top_to=4)) self.assertEqual(timing.timing_list[-1][-1].ngrp, 4) timing.add('0p3', self._make_sched_res((2, 0, 2), 60, top_to=4)) self.assertEqual(timing.timing_list[-1][-1].ngrp, 4) timing.add('1', self._make_sched_res((2, 1, 0), 800, top_to=4)) self.assertEqual(timing.timing_list[-1][-1].ngrp, 4) def test_add_invalid_sched_seq(self): ''' add(), invalid sched seq. ''' timing = PipelineSegmentTiming(self.net1, 3) timing.add('0', self._make_sched_res((3, 0, 0), 123)) with self.assertRaisesRegex(ValueError, 'PipelineSegmentTiming: .*belong to.*'): timing.add('1', self._make_sched_res((2, 1, 0), 123)) with self.assertRaisesRegex(ValueError, 'PipelineSegmentTiming: .*follow.*'): timing.add('1p', self._make_sched_res((3, 1, 1), 123)) def test_add_already_in(self): ''' add(), layer already in. ''' timing = PipelineSegmentTiming(self.net1, 3) timing.add('0', self._make_sched_res((3, 0, 0), 123)) with self.assertRaisesRegex(ValueError, 'PipelineSegmentTiming: .*layer 0.*'): timing.add('0', self._make_sched_res((3, 1, 0), 123)) def test_time_bat_ngrp(self): ''' time and critical_time bat_ngrp. ''' timing = PipelineSegmentTiming(self.net1, 3) timing.add('0', self._make_sched_res((3, 0, 0), 120, top_tb=4)) timing.add('1', self._make_sched_res((3, 1, 0), 130, top_tb=4)) timing.add('1p', self._make_sched_res((3, 1, 1), 20, top_tb=4)) timing.add('2', self._make_sched_res((3, 2, 0), 136, top_tb=4)) self.assertEqual(timing.critical_time, 150) self.assertEqual(timing.time, 120 // 4 + 130 + 20 + 136 // 4) self.assertAlmostEqual(timing.time_overhead, timing.time / ((120 + 130 + 20 + 136) / 3.) - 1) # Unmatched BAT group number. timing.add('3', self._make_sched_res((3, 3, 0), 100, top_tb=2)) self.assertEqual(timing.time, 120 + 130 + 20 + 136 + 100) self.assertAlmostEqual(timing.time_overhead, timing.time / ((120 + 130 + 20 + 136 + 100) / 4.) - 1) def test_time_ifm_ofm_ngrp(self): ''' time and critical_time ifm_ngrp and ofm_ngrp. ''' # Single-group wait, first critical. timing = PipelineSegmentTiming(self.net1, 3) timing.add('0', self._make_sched_res((3, 0, 0), 120, top_to=3, top_tb=2)) timing.add('1', self._make_sched_res((3, 1, 0), 90, top_ti=3, top_tb=2)) self.assertEqual(timing.critical_time, 120) # Layer 0 is critical. Layer 0 last BAT group starts at 120 - 120 // 2. # Layer 1 last BAT group starts 120 // 2 // 3 later, which takes 90 // # 2. self.assertEqual(timing.time, 120 - 120 // 2 + 120 // 2 // 3 + 90 // 2) self.assertAlmostEqual(timing.time_overhead, timing.time / ((120 + 90) / 2.) - 1) # Single-group wait, second critical. timing = PipelineSegmentTiming(self.net1, 3) timing.add('0', self._make_sched_res((3, 0, 0), 120, top_to=3, top_tb=2)) timing.add('1', self._make_sched_res((3, 1, 0), 150, top_ti=3, top_tb=2)) self.assertEqual(timing.critical_time, 150) # Layer 1 is critical. Layer 1 first BAT group starts at 120 // 2 // 3, # and takes 150 for all its BAT groups. self.assertEqual(timing.time, 120 // 2 // 3 + 150) self.assertAlmostEqual(timing.time_overhead, timing.time / ((120 + 150) / 2.) - 1) # All-group wait, first critical. timing = PipelineSegmentTiming(self.net1, 3) timing.add('0', self._make_sched_res((3, 0, 0), 120, top_to=3, top_tb=2)) timing.add('1', self._make_sched_res((3, 1, 0), 90, top_to=3, top_tb=2)) self.assertEqual(timing.critical_time, 120) self.assertEqual(timing.time, 120 + 90 // 2) self.assertAlmostEqual(timing.time_overhead, timing.time / ((120 + 90) / 2.) - 1) # All-group wait, second critical. timing = PipelineSegmentTiming(self.net1, 3) timing.add('0', self._make_sched_res((3, 0, 0), 120, top_ti=3, top_tb=2)) timing.add('1', self._make_sched_res((3, 1, 0), 150, top_ti=3, top_tb=2)) self.assertEqual(timing.critical_time, 150) self.assertEqual(timing.time, 120 // 2 + 150) self.assertAlmostEqual(timing.time_overhead, timing.time / ((120 + 150) / 2.) - 1) def test_time_linear(self): ''' time and critical_time linear. ''' timing = PipelineSegmentTiming(self.net1, 3) timing.add('0', self._make_sched_res((3, 0, 0), 120, top_ti=3, top_tb=2)) timing.add('1', self._make_sched_res((3, 1, 0), 129, top_to=3, top_tb=2)) timing.add('1p', self._make_sched_res((3, 1, 1), 21, top_to=3, top_tb=2)) timing.add('2', self._make_sched_res((3, 2, 0), 138, top_ti=3, top_tb=2)) self.assertEqual(timing.critical_time, 150) # Layer 1 is critical. Layer 1+1p first BAT group starts at 120 // 2, # and last BAT group starts at 150 // 2 later. Layer 2 last BAT group # starts 150 // 2 // 3 later, and takes 138 // 2. self.assertEqual(timing.time, 120 // 2 + 150 // 2 + 150 // 2 // 3 + 138 // 2) self.assertAlmostEqual(timing.time_overhead, timing.time / ((120 + 129 + 21 + 138) / 3.) - 1) def test_time_branch(self): ''' time and critical_time branch. ''' # Single-group wait. timing = PipelineSegmentTiming(self.net4, 3) timing.add('6', self._make_sched_res((3, 0, 0), 120, top_ti=3, top_tb=2)) timing.add('7', self._make_sched_res((3, 1, 0), 150, top_to=3, top_tb=2)) timing.add('8', self._make_sched_res((3, 2, 0), 144, top_ti=3, top_tb=2)) timing.add('9', self._make_sched_res((3, 3, 0), 168, top_ti=3, top_tb=2)) self.assertEqual(timing.critical_time, 168) # Layer 9 is critical. Layer 7 first BAT group starts at 120 // 2. # Layer 8 and 9 first BAT group starts at 150 // 2 // 3 later, and all # groups of layer 9 take 168. self.assertEqual(timing.time, 120 // 2 + 150 // 2 // 3 + 168) self.assertAlmostEqual(timing.time_overhead, timing.time / ((120 + 150 + 144 + 168) / 4.) - 1) # All-group wait. timing = PipelineSegmentTiming(self.net4, 3) timing.add('6', self._make_sched_res((3, 0, 0), 120, top_tb=2)) timing.add('7', self._make_sched_res((3, 1, 0), 150, top_tb=2)) timing.add('8', self._make_sched_res((3, 2, 0), 144, top_tb=2)) timing.add('9', self._make_sched_res((3, 3, 0), 132, top_tb=2)) self.assertEqual(timing.critical_time, 150) # Layer 7 is critical. Layer 7 first BAT group starts at 120 // 2, and # layer 7 last BAT group ends at 150 later, at which time layer 8 and 9 # last BAT group starts, and takes 144 // 2. self.assertEqual(timing.time, 120 // 2 + 150 + 144 // 2) self.assertAlmostEqual(timing.time_overhead, timing.time / ((120 + 150 + 144 + 132) / 4.) - 1) def test_time_all_lr(self): ''' time and critical_time all LocalRegionLayer. ''' timing = PipelineSegmentTiming(self.netlr, 2) timing.add('0p1', self._make_sched_res((2, 0, 0), 40, top_to=5, top_tb=2)) timing.add('0p2', self._make_sched_res((2, 0, 1), 80, top_to=5, top_tb=2)) timing.add('0p3', self._make_sched_res((2, 0, 2), 60, top_to=5, top_tb=2)) timing.add('1', self._make_sched_res((2, 1, 0), 800, top_ti=5, top_tb=2)) self.assertEqual(timing.critical_time, 800) # Layer 1 is critical. Layer 1 first BAT group starts at (40 + 80 + 60) # // 2 // 5, and takes 800. self.assertEqual(timing.time, (40 + 80 + 60) // 2 // 5 + 800) self.assertAlmostEqual(timing.time_overhead, timing.time / ((40 + 80 + 60 + 800) / 2.) - 1) def test_time_single_spatial(self): ''' time and critical_time for single-spatial segment. ''' for net_name in self.net: if not net_name.startswith('net'): continue net = self.net[net_name] for seg in self._gen_all_segment(net, temporal=True): if not seg.valid: continue self.assertEqual(len(seg), 1) timing = PipelineSegmentTiming(net, 0) for idx, layer in enumerate(seg[0]): timing.add(layer, self._make_sched_res((0, 0, idx), (40 + idx * 7 % 3) * 16, top_to=4, top_ti=4, top_tb=4)) self.assertEqual(timing.critical_time, timing.time) self.assertAlmostEqual(timing.time_overhead, 0.) def test_time_dram_time(self): ''' time and critical_time dominated by DRAM time. ''' timing = PipelineSegmentTiming(self.net1, 3) timing.add('0', self._make_sched_res((3, 0, 0), 120, dram_time=100, top_ti=3, top_tb=4)) timing.add('1', self._make_sched_res((3, 1, 0), 130, dram_time=140, top_to=3, top_tb=4)) timing.add('1p', self._make_sched_res((3, 1, 1), 20, dram_time=10, top_to=3, top_tb=4)) timing.add('2', self._make_sched_res((3, 2, 0), 138, dram_time=100, top_ti=3, top_tb=4)) self.assertEqual(timing.critical_time, 160) self.assertEqual(timing.time, 100 + 140 + 10 + 100) self.assertEqual(timing.dram_time, timing.time) self.assertLess(timing.node_time, timing.time) def test_time_overhead(self): ''' time_overhead. ''' timing = PipelineSegmentTiming(self.net1, 3) timing.add('0', self._make_sched_res((3, 0, 0), 120, num_nodes=4, top_ti=3, top_tb=4)) timing.add('1', self._make_sched_res((3, 1, 0), 130, num_nodes=6, top_to=3, top_tb=4)) timing.add('1p', self._make_sched_res((3, 1, 1), 20, num_nodes=6, top_to=3, top_tb=4)) timing.add('2', self._make_sched_res((3, 2, 0), 138, num_nodes=3, top_ti=3, top_tb=4)) time_indv = 120 * 4 / 13. + (130 + 20) * 6 / 13. + 138 * 3 / 13. self.assertAlmostEqual(timing.time_overhead, timing.time / time_indv - 1)
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')
program. If not, see <https://opensource.org/licenses/BSD-3-Clause>. """ from nn_dataflow.core import Network from nn_dataflow.core import InputLayer, ConvLayer, FCLayer, PoolingLayer ''' GoogLeNet ILSVRC 2014 ''' NN = Network('GoogLeNet') NN.set_input_layer(InputLayer(3, 224)) NN.add('conv1', ConvLayer(3, 64, 112, 7, 2)) NN.add('pool1', PoolingLayer(64, 56, 3, strd=2)) # Norm layer is ignored. NN.add('conv2_3x3_reduce', ConvLayer(64, 64, 56, 1)) NN.add('conv2_3x3', ConvLayer(64, 192, 56, 3)) # Norm layer is ignored. NN.add('pool2', PoolingLayer(192, 28, 3, strd=2)) def add_inception(network, incp_id, sfmap, nfmaps_in, nfmaps_1, nfmaps_3r, nfmaps_3, nfmaps_5r, nfmaps_5, nfmaps_pool, prevs): ''' Add an inception module to the network. ''' pfx = 'inception_{}_'.format(incp_id) # 1x1 branch. network.add(pfx + '1x1',
""" from nn_dataflow.core import Network from nn_dataflow.core import InputLayer, ConvLayer, FCLayer, PoolingLayer ''' AlexNet Krizhevsky, Sutskever, and Hinton, 2012 ''' NN = Network('AlexNet') NN.set_input(InputLayer(3, 224)) NN.add('conv1_a', ConvLayer(3, 48, 55, 11, 4), prevs=(NN.INPUT_LAYER_KEY,)) NN.add('conv1_b', ConvLayer(3, 48, 55, 11, 4), prevs=(NN.INPUT_LAYER_KEY,)) NN.add('pool1_a', PoolingLayer(48, 27, 3, strd=2), prevs=('conv1_a',)) NN.add('pool1_b', PoolingLayer(48, 27, 3, strd=2), prevs=('conv1_b',)) # Norm layer is ignored. NN.add('conv2_a', ConvLayer(48, 128, 27, 5), prevs=('pool1_a',)) NN.add('conv2_b', ConvLayer(48, 128, 27, 5), prevs=('pool1_b',)) NN.add('pool2_a', PoolingLayer(128, 13, 3, strd=2), prevs=('conv2_a',)) NN.add('pool2_b', PoolingLayer(128, 13, 3, strd=2), prevs=('conv2_b',)) # Norm layer is ignored. NN.add('conv3_a', ConvLayer(256, 192, 13, 3), prevs=('pool2_a', 'pool2_b')) NN.add('conv3_b', ConvLayer(256, 192, 13, 3), prevs=('pool2_a', 'pool2_b')) NN.add('conv4_a', ConvLayer(192, 192, 13, 3), prevs=('conv3_a',)) NN.add('conv4_b', ConvLayer(192, 192, 13, 3), prevs=('conv3_b',))
class TestNNDataflowScheme(unittest.TestCase): ''' Tests for NNDataflowScheme. ''' # pylint: disable=too-many-public-methods # pylint: disable=too-many-public-methods def setUp(self): self.network = Network('test_net') self.network.set_input_layer(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(128, 1000, 7), prevs=['p1', 'p2']) self.batch_size = 4 input_layer = self.network.input_layer() self.input_layout = 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=(NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(2, 1), type=NodeRegion.DRAM), ), parts=(PartitionScheme(order=range(pe.NUM), pdims=[(1, 1)] * pe.NUM), )) c1_layer = self.network['c1'] self.c1res = SchedulingResult( scheme=OrderedDict([ ('cost', 1.5), ('time', 200.), ('ops', 4.), ('num_nodes', 4), ('cost_op', 0.5), ('cost_access', 1.), ('cost_noc', 0), ('cost_static', 0), ('proc_time', 200), ('bus_time', 0), ('dram_time', 0), ('access', [[7, 8, 9]] * me.NUM), ('remote_gbuf_access', [0] * 3), ('total_nhops', [4, 5, 6]), ('fetch', [[1, 1, 1], [2, 2, 2]]), ('ti', [2, 2, 3]), ('to', [1, 2, 3]), ('tb', [1, 2, 3]), ('tvals', [[2, 1, 1], [2, 2, 2], [3, 3, 3]]), ('orders', [range(3)] * 2), ]), ofmap_layout=DataLayout( frngs=(FmapRange( (0, 0, 0, 0), FmapPosition(b=self.batch_size, n=c1_layer.nofm, h=c1_layer.hofm, w=c1_layer.wofm)), ), regions=(NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(1, 2), type=NodeRegion.DRAM), ), parts=(PartitionScheme(order=range(pe.NUM), pdims=[(1, 1)] * pe.NUM), )), sched_seq=(0, 0, 0)) p1_layer = self.network['p1'] self.p1res = SchedulingResult( scheme=OrderedDict([ ('cost', 0.6), ('time', 5), ('ops', 0.1), ('num_nodes', 2), ('cost_op', 0.1), ('cost_access', 0.5), ('cost_noc', 0), ('cost_static', 0), ('proc_time', 5), ('bus_time', 0), ('dram_time', 0), ('access', [[.7, .8, .9]] * me.NUM), ('remote_gbuf_access', [0] * 3), ('total_nhops', [.4, .5, .6]), ('fetch', [[1, 1, 1], [2, 2, 2]]), ('ti', [2, 2, 3]), ('to', [1, 2, 3]), ('tb', [1, 2, 3]), ('tvals', [[2, 1, 1], [2, 2, 2], [3, 3, 3]]), ('orders', [range(3)] * 2), ]), ofmap_layout=DataLayout( frngs=(FmapRange( (0, 0, 0, 0), FmapPosition(b=self.batch_size, n=p1_layer.nofm, h=p1_layer.hofm, w=p1_layer.wofm)), ), regions=(NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(1, 2), type=NodeRegion.DRAM), ), parts=(PartitionScheme(order=range(pe.NUM), pdims=[(1, 1)] * pe.NUM), )), sched_seq=(0, 1, 0)) self.p2res = SchedulingResult(scheme=self.p1res.scheme, ofmap_layout=self.p1res.ofmap_layout, sched_seq=(0, 2, 0)) self.dtfl = NNDataflowScheme(self.network, self.input_layout) self.dtfl['c1'] = self.c1res self.dtfl['p1'] = self.p1res self.dtfl['p2'] = self.p2res 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.assertDictEqual(df.ext_layout_dict, {}) 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_ext(self): ''' Initial with external layers. ''' self.network.add_ext('e0', InputLayer(3, 224)) self.network.add_ext('e1', InputLayer(6, 224)) e0_layout = DataLayout(frngs=(FmapRange( (0, 0, 0, 0), FmapPosition(b=self.batch_size, n=self.network['e0'].nofm, h=self.network['e0'].hofm, w=self.network['e0'].wofm)), ), regions=self.input_layout.regions, parts=self.input_layout.parts) e1_layout = DataLayout(frngs=(FmapRange( (0, 0, 0, 0), FmapPosition(b=self.batch_size, n=self.network['e1'].nofm, h=self.network['e1'].hofm, w=self.network['e1'].wofm)), ), regions=self.input_layout.regions, parts=self.input_layout.parts) ext_layout_dict = {'e0': e0_layout, 'e1': e1_layout} df = NNDataflowScheme(self.network, self.input_layout, ext_layout_dict) self.assertIn('e0', df.ext_layout_dict) self.assertIn('e1', df.ext_layout_dict) self.assertEqual(df.ext_layout_dict['e0'], e0_layout) self.assertEqual(df.ext_layout_dict['e1'], e1_layout) 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.frngs) def test_init_invalid_eld_keys(self): ''' Invalid ext_layout_dict keys. ''' with self.assertRaisesRegexp(ValueError, 'NNDataflowScheme: .*ext_layout_dict*'): _ = NNDataflowScheme(self.network, self.input_layout, {'e0': self.input_layout}) self.network.add_ext('e0', InputLayer(3, 224)) with self.assertRaisesRegexp(ValueError, 'NNDataflowScheme: .*ext_layout_dict*'): _ = NNDataflowScheme(self.network, self.input_layout) def test_init_invalid_eld_type(self): ''' Invalid ext_layout_dict value type. ''' self.network.add_ext('e0', InputLayer(3, 224)) self.network.add_ext('e1', InputLayer(3, 224)) with self.assertRaisesRegexp(TypeError, 'NNDataflowScheme: .*ext_layout*'): _ = NNDataflowScheme(self.network, self.input_layout, { 'e0': self.input_layout, 'e1': self.input_layout.frngs }) 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.scheme 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._replace(sched_seq=(1, 0, 0)) def test_setitem_prev_not_in(self): ''' __setitem__ previous not existing. ''' df = NNDataflowScheme(self.network, self.input_layout) with self.assertRaisesRegexp(KeyError, 'NNDataflowScheme: .*p1*'): df['p1'] = self.p1res def test_setitem_prev_input_ext(self): ''' __setitem__ previous is input or external. ''' df = NNDataflowScheme(self.network, self.input_layout) df['c1'] = self.c1res self.assertAlmostEqual(df.total_cost, self.c1res.total_cost) self.network.add_ext('e0', InputLayer(3, 224)) self.network.add('c2', self.network['c1'], prevs=('e0', )) df = NNDataflowScheme(self.network, self.input_layout, {'e0': self.input_layout}) df['c2'] = self.c1res self.assertAlmostEqual(df.total_cost, self.c1res.total_cost) def test_setitem_invalid_seg_idx(self): ''' __setitem__ invalid segment index. ''' df = NNDataflowScheme(self.network, self.input_layout) with self.assertRaisesRegexp(ValueError, 'NNDataflowScheme: .*segment index*'): df['c1'] = self.c1res._replace(sched_seq=(1, 0, 0)) df = NNDataflowScheme(self.network, self.input_layout) df['c1'] = self.c1res df['p1'] = self.p1res._replace(sched_seq=(1, 0, 0)) with self.assertRaisesRegexp(ValueError, 'NNDataflowScheme: .*segment index*'): df['p2'] = self.p2res._replace(sched_seq=(0, 0, 0)) 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_copy_ext(self): ''' copy external layers. ''' self.network.add_ext('e0', self.network.input_layer()) self.network.add_ext('e1', self.network.input_layer()) df1 = NNDataflowScheme(self.network, self.input_layout, { 'e0': self.input_layout, 'e1': self.input_layout }) df1['c1'] = self.c1res df1['p1'] = self.p1res df1['p2'] = self.p2res df2 = df1.copy() self.assertAlmostEqual(df1.total_cost, df2.total_cost) self.assertAlmostEqual(df1.total_time, df2.total_time) self.assertDictEqual(df1.res_dict, df2.res_dict) self.assertDictEqual(df1.ext_layout_dict, df2.ext_layout_dict) def test_fmap_layout(self): ''' fmap_layout. ''' flayout = self.dtfl.fmap_layout(('c1', )) frng = flayout.complete_fmap_range() self.assertTrue(flayout.is_in(self.c1res.ofmap_layout.regions[0])) self.assertEqual(frng, self.c1res.ofmap_layout.frngs[0]) flayout = self.dtfl.fmap_layout((None, )) frng = flayout.complete_fmap_range() self.assertTrue(flayout.is_in(self.input_layout.regions[0])) self.assertEqual(frng, self.input_layout.frngs[0]) flayout = self.dtfl.fmap_layout(('p1', 'p2')) frng = flayout.complete_fmap_range() self.assertEqual(frng.size('n'), self.network['p1'].nofm + self.network['p2'].nofm) flayout = self.dtfl.fmap_layout((None, 'c1')) frng = flayout.complete_fmap_range() self.assertEqual( frng.size('n'), self.network.input_layer().nofm + self.network['c1'].nofm) def test_fmap_layout_ext(self): ''' fmap_layout external layers. ''' self.network.add_ext('e0', self.network.input_layer()) self.network.add_ext('e1', self.network.input_layer()) df = NNDataflowScheme(self.network, self.input_layout, { 'e0': self.input_layout, 'e1': self.input_layout }) df['c1'] = self.c1res df['p1'] = self.p1res df['p2'] = self.p2res flayout = df.fmap_layout(('e0', )) self.assertEqual(flayout, self.input_layout) flayout = df.fmap_layout(('e1', None)) self.assertTrue(flayout.is_in(self.input_layout.regions[0])) frng = flayout.complete_fmap_range() self.assertEqual( frng.size('n'), self.network['e1'].nofm + self.network.input_layer().nofm) def test_properties(self): ''' Property accessors. ''' self.assertAlmostEqual(self.dtfl.total_cost, 1.5 + 0.6 * 2) self.assertAlmostEqual(self.dtfl.total_time, 200 + 5) 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) def test_time_full_net_single_seg(self): ''' time() when full network fits in a single segment. ''' dtfl = NNDataflowScheme(self.network, self.input_layout) dtfl['c1'] = self.c1res dtfl['p1'] = self.p1res._replace(sched_seq=(0, 1, 0)) dtfl['p2'] = self.p2res._replace(sched_seq=(0, 2, 0)) dtfl['f1'] = self.c1res._replace(sched_seq=(0, 3, 0)) self.assertEqual(dtfl.total_time, 200) def test_static_cost_adjust(self): ''' Adjust static cost portion. ''' # Add static cost. idl_unit_cost = 1e-3 c1scheme = self.c1res.scheme c1static = c1scheme['time'] * idl_unit_cost c1scheme['cost_static'] += c1static c1scheme['cost_access'] -= c1static p1scheme = self.p1res.scheme p1static = p1scheme['time'] * idl_unit_cost p1scheme['cost_static'] += p1static p1scheme['cost_access'] -= p1static # No adjust. dtfl = NNDataflowScheme(self.network, self.input_layout) dtfl['c1'] = self.c1res._replace(scheme=c1scheme) dtfl['p1'] = self.p1res._replace(scheme=p1scheme, sched_seq=(1, 0, 0)) dtfl['p2'] = self.p2res._replace(scheme=p1scheme, sched_seq=(2, 0, 0)) dtfl['f1'] = self.c1res._replace(scheme=c1scheme, sched_seq=(3, 0, 0)) sum_cost = 1.5 + 0.6 + 0.6 + 1.5 sum_time = 200 + 5 + 5 + 200 self.assertAlmostEqual(dtfl.total_cost, sum_cost) self.assertAlmostEqual(dtfl.total_time, sum_time) # With adjust. dtfl = NNDataflowScheme(self.network, self.input_layout) dtfl['c1'] = self.c1res._replace(scheme=c1scheme) dtfl['p1'] = self.p1res._replace(scheme=p1scheme, sched_seq=(0, 1, 0)) dtfl['p2'] = self.p2res._replace(scheme=p1scheme, sched_seq=(0, 2, 0)) dtfl['f1'] = self.c1res._replace(scheme=c1scheme, sched_seq=(1, 0, 0)) diff = (sum_time - dtfl.total_time) * idl_unit_cost self.assertGreater(diff, 0) self.assertAlmostEqual(dtfl.total_cost, sum_cost - diff) # All in one segment. dtfl = NNDataflowScheme(self.network, self.input_layout) dtfl['c1'] = self.c1res._replace(scheme=c1scheme) dtfl['p1'] = self.p1res._replace(scheme=p1scheme, sched_seq=(0, 1, 0)) dtfl['p2'] = self.p2res._replace(scheme=p1scheme, sched_seq=(0, 2, 0)) dtfl['f1'] = self.c1res._replace(scheme=c1scheme, sched_seq=(0, 3, 0)) diff = (sum_time - dtfl.total_time) * idl_unit_cost self.assertGreater(diff, 0) self.assertAlmostEqual(dtfl.total_cost, sum_cost - diff) def test_segment_time_list(self): ''' segment_time_list(). ''' dtfl = NNDataflowScheme(self.network, self.input_layout) dtfl['c1'] = self.c1res dtfl['p1'] = self.p1res dtfl['p2'] = self.p2res._replace(sched_seq=(1, 0, 0)) self.assertListEqual(dtfl.segment_time_list(), [205, 5]) def test_segment_dram_time_list(self): ''' segment_dram_time_list(). ''' c1_scheme = self.c1res.scheme.copy() c1_scheme['dram_time'] = 180 p1_scheme = self.p1res.scheme.copy() p1_scheme['dram_time'] = 5 p2_scheme = self.p2res.scheme.copy() p2_scheme['dram_time'] = 10 dtfl = NNDataflowScheme(self.network, self.input_layout) dtfl['c1'] = self.c1res._replace(scheme=c1_scheme) dtfl['p1'] = self.p1res._replace(scheme=p1_scheme) dtfl['p2'] = self.p2res._replace(sched_seq=(1, 0, 0), scheme=p2_scheme) self.assertListEqual(dtfl.segment_dram_time_list(), [185, 10]) self.assertListEqual(dtfl.segment_time_list(), [205, 10]) 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.005) self.assertAlmostEqual(stats['p1'], 0.01) self.assertAlmostEqual(stats['p2'], 0.01) def test_stats_dram_bandwidth(self): ''' Per-layer stats: DRAM bandwidth. ''' stats = self.dtfl.perlayer_stats('dram_bandwidth') self.assertEqual(len(stats), len(self.dtfl)) self.assertAlmostEqual(stats['c1'], (7. + 8. + 9.) / 200) self.assertAlmostEqual(stats['p1'], (.7 + .8 + .9) / 5) self.assertAlmostEqual(stats['p2'], (.7 + .8 + .9) / 5) def test_stats_not_supported(self): ''' Per-layer stats: not supported. ''' with self.assertRaisesRegexp(AttributeError, 'NNDataflowScheme: .*not_supported.*'): _ = self.dtfl.perlayer_stats('not_supported')
If you use this program in your research, we request that you reference the 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-L PRIME, 2016 ''' NN = Network('MLP-L') NN.set_input(InputLayer(784, 1)) NN.add('fc1', FCLayer(784, 1500)) NN.add('fc2', FCLayer(1500, 1000)) NN.add('fc3', FCLayer(1000, 500)) NN.add('fc4', FCLayer(500, 10))
""" $lic$ Copyright (C) 2016-2019 by The Board of Trustees of Stanford University This program is free software: you can redistribute it and/or modify it under the terms of the Modified BSD-3 License as published by the Open Source Initiative. 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, ConvLayer, FCLayer, PoolingLayer ''' net1 ''' NN = Network('net1') # Linear. NN.set_input_layer(InputLayer(10, 1)) NN.add('0', FCLayer(10, 20)) NN.add('1', FCLayer(20, 30)) NN.add('1p', PoolingLayer(30, 1, 1)) NN.add('2', FCLayer(30, 40)) NN.add('3', FCLayer(40, 50))
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: # Residual does not cross module. _PREVS = None else: _PREVS = ('conv2_{}_c'.format(i), 'conv2_{}_c'.format(i - 1))
from nn_dataflow.core import Network from nn_dataflow.core import InputLayer, EltwiseLayer from nn_dataflow.nns import add_lstm_cell ''' LSTM from GNMT. Sutskever, Vinyals, Le, Google, NIPS 2014 ''' NN = Network('GNMT') NN.set_input_layer(InputLayer(1000, 1)) NL = 4 # Word embedding is a simple lookup. # Exclude or ignore embedding processing. WE = NN.INPUT_LAYER_KEY # layered LSTM. X = WE for l in range(NL): cell = 'cell_l{}'.format(l) C, H = add_lstm_cell(NN, cell, 1000, X) X = H # log(p), softmax. NN.add('Wd', EltwiseLayer(1000, 1, 1), prevs=(X, ))
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))
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, EltwiseLayer from nn_dataflow.nns import add_lstm_cell ''' LSTM from Show and Tell. Vinyals et al., Google, CVPR 2015 ''' NN = Network('ShowTell') NN.set_input_layer(InputLayer(512, 1)) # Word embedding is a simple lookup. # Exclude or ignore embedding processing. WE = NN.INPUT_LAYER_KEY # LSTM. C, H = add_lstm_cell(NN, 'cell', 512, WE) # log(p), softmax. NN.add('Wd', EltwiseLayer(512, 1, 1), prevs=(H, ))
program. If not, see <https://opensource.org/licenses/BSD-3-Clause>. """ from nn_dataflow.core import Network from nn_dataflow.core import InputLayer, ConvLayer, FCLayer, PoolingLayer ''' VGGNet-16 Simonyan and Zisserman, 2014 ''' NN = Network('VGG') NN.set_input_layer(InputLayer(3, 224)) NN.add('conv1', ConvLayer(3, 64, 224, 3)) NN.add('conv2', ConvLayer(64, 64, 224, 3)) NN.add('pool1', PoolingLayer(64, 112, 2)) NN.add('conv3', ConvLayer(64, 128, 112, 3)) NN.add('conv4', ConvLayer(128, 128, 112, 3)) NN.add('pool2', PoolingLayer(128, 56, 2)) NN.add('conv5', ConvLayer(128, 256, 56, 3)) NN.add('conv6', ConvLayer(256, 256, 56, 3)) NN.add('conv7', ConvLayer(256, 256, 56, 3)) NN.add('pool3', PoolingLayer(256, 28, 2)) NN.add('conv8', ConvLayer(256, 512, 28, 3)) NN.add('conv9', ConvLayer(512, 512, 28, 3)) NN.add('conv10', ConvLayer(512, 512, 28, 3))
program. If not, see <https://opensource.org/licenses/BSD-3-Clause>. """ from nn_dataflow.core import Network from nn_dataflow.core import InputLayer, ConvLayer, FCLayer, PoolingLayer ''' ZFNet Zeiler and Fergus, 2013 ''' NN = Network('ZFNet') NN.set_input(InputLayer(3, 224)) NN.add('conv1', ConvLayer(3, 96, 110, 7, 2)) NN.add('pool1', PoolingLayer(96, 55, 3, strd=2)) # Norm layer is ignored. NN.add('conv2', ConvLayer(96, 256, 26, 5, 2)) NN.add('pool2', PoolingLayer(256, 13, 3, strd=2)) # Norm layer is ignored. NN.add('conv3', ConvLayer(256, 512, 13, 3)) NN.add('conv4', ConvLayer(512, 1024, 13, 3)) NN.add('conv5', ConvLayer(1024, 512, 13, 3)) NN.add('pool3', PoolingLayer(512, 6, 3, strd=2)) NN.add('fc1', FCLayer(512, 4096, 6)) NN.add('fc2', FCLayer(4096, 4096)) NN.add('fc3', FCLayer(4096, 1000))