Esempio n. 1
0
    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))
Esempio n. 2
0
    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
Esempio n. 4
0
    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)))
Esempio n. 5
0
    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()
Esempio n. 7
0
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)
Esempio n. 8
0
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, ))
Esempio n. 10
0
    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)
Esempio n. 11
0
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))
Esempio n. 12
0
"""

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),
Esempio n. 13
0
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')
Esempio n. 15
0
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',
Esempio n. 16
0
"""

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')
Esempio n. 18
0
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))
Esempio n. 19
0
""" $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))
Esempio n. 20
0
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))
Esempio n. 21
0
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, ))
Esempio n. 22
0
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))

Esempio n. 23
0
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, ))
Esempio n. 24
0
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))
Esempio n. 25
0
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))