""" $lic$
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>.
"""

import unittest

from nn_dataflow.core import Network
from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, \
        PoolingLayer, EltwiseLayer

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_layer(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_layer(self):
        ''' Modifier set_input_layer. '''
        network = Network('test_net')
        network.set_input_layer(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_layer_type(self):
        ''' Modifier set_input_layer type. '''
        network = Network('test_net')
        with self.assertRaisesRegex(TypeError, 'Network: .*input_layer.*'):
            network.set_input_layer(Layer(3, 24))
        with self.assertRaisesRegex(TypeError, 'Network: .*input_layer.*'):
            network.set_input_layer(ConvLayer(3, 8, 24, 3))

    def test_set_input_layer_duplicate(self):
        ''' Modifier set_input_layer duplicate. '''
        network = Network('test_net')
        network.set_input_layer(InputLayer(3, 24))
        with self.assertRaisesRegex(KeyError, 'Network: .*input.*'):
            network.set_input_layer(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('e4', EltwiseLayer(1000, 1, 2), prevs=('f1', 'f3'))
        self.network.add('f4', FCLayer(1000, 1000), prevs='e4')
        self.assertEqual(len(self.network), 7)

    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.assertRaisesRegex(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.assertRaisesRegex(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_layer(InputLayer(3, 224))

        network.add('c1', ConvLayer(3, 64, 224, 3))
        with self.assertRaisesRegex(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_layer(InputLayer(3, 224))

        with self.assertRaisesRegex(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_layer(InputLayer(3, 224))
        network.add('c1', ConvLayer(3, 64, 224, 3))

        with self.assertRaisesRegex(ValueError,
                                    'Network: .*c1.*p1.*mismatch fmap.*'):
            network.add('p1', PoolingLayer(64, 7, 2))
        self.assertEqual(len(network), 1)
        with self.assertRaisesRegex(ValueError,
                                    'Network: .*c1.*c2.*mismatch fmap.*'):
            network.add('c2', ConvLayer(64, 128, 220, 3))
        self.assertEqual(len(network), 1)

        with self.assertRaisesRegex(ValueError, 'Network: .*c1.*prev.*p1.*'):
            network.add('p1', PoolingLayer(32, 7, 32))
        self.assertEqual(len(network), 1)
        with self.assertRaisesRegex(ValueError, 'Network: .*c1.*prev.*c2.*'):
            network.add('c2', ConvLayer(32, 128, 224, 3))
        self.assertEqual(len(network), 1)

        network.add('c2', ConvLayer(64, 128, 224, 3))

        with self.assertRaisesRegex(ValueError,
                                    r'Network: .*c1 | c2.*prev.*p1.*'):
            network.add('p1', PoolingLayer(128, 7, 32), prevs=('c1', 'c2'))
        self.assertEqual(len(network), 2)

    def test_add_ext(self):
        ''' Modifier add_ext. '''
        self.assertEqual(len(self.network), 3)

        self.network.add_ext('e0', InputLayer(3, 24))
        self.assertIsInstance(self.network['e0'], InputLayer)
        self.assertEqual(self.network['e0'].nofm, 3)
        self.assertEqual(self.network['e0'].hofm, 24)
        self.assertEqual(self.network['e0'].wofm, 24)

        self.network.add_ext('e1', InputLayer(5, (16, 20)))
        self.assertIsInstance(self.network['e1'], InputLayer)
        self.assertEqual(self.network['e1'].nofm, 5)
        self.assertEqual(self.network['e1'].hofm, 16)
        self.assertEqual(self.network['e1'].wofm, 20)

        self.assertEqual(len(self.network), 3)

    def test_add_ext_same_key(self):
        ''' Modifier add_ext same key. '''
        network = Network('test_net')

        network.add_ext('e0', InputLayer(3, 24))
        with self.assertRaisesRegex(KeyError, 'Network: .*ext.*'):
            network.add_ext('e0', InputLayer(3, 24))

    def test_add_ext_invalid_type(self):
        ''' Modifier add_ext invalid type. '''
        network = Network('test_net')

        with self.assertRaisesRegex(TypeError, 'Network: .*external layer.*'):
            network.add_ext('e0', Layer(3, 24))
        with self.assertRaisesRegex(TypeError, 'Network: .*external layer.*'):
            network.add_ext('e0', ConvLayer(3, 8, 24, 3))

    def test_prevs(self):
        ''' Get prevs. '''
        self.network.add('f2', FCLayer(64, 2000, 7), prevs='p1')
        self.network.add('f3', FCLayer(3000, 1000), prevs=('f1', 'f2'))

        prevs = self.network.prevs('f1')
        self.assertTupleEqual(prevs, ('p1',))

        prevs = self.network.prevs('f2')
        self.assertTupleEqual(prevs, ('p1',))
        prevs = self.network.prevs('f3')
        self.assertTupleEqual(prevs, ('f1', 'f2'))

    def test_prevs_first(self):
        ''' Get prevs first layer. '''
        self.network.add('c2', ConvLayer(3, 3, 224, 1),
                         prevs=self.network.INPUT_LAYER_KEY)

        prevs = self.network.prevs('c1')
        self.assertTupleEqual(prevs, (None,))

        prevs = self.network.prevs('c2')
        self.assertTupleEqual(prevs, (None,))

    def test_prevs_input(self):
        ''' Get prevs input layer. '''
        with self.assertRaisesRegex(ValueError, 'Network: .*input.*'):
            _ = self.network.prevs(self.network.INPUT_LAYER_KEY)

    def test_prevs_ext_next(self):
        ''' Get prevs next layer of an external layer. '''
        self.network.add_ext('e0', InputLayer(3, 224))

        self.network.add('n', ConvLayer(6, 3, 224, 1),
                         prevs=(self.network.INPUT_LAYER_KEY, 'e0'))

        prevs = self.network.prevs('n')
        self.assertTupleEqual(prevs, (None, 'e0'))

    def test_prevs_ext(self):
        ''' Get prevs external layer. '''
        self.network.add_ext('e0', InputLayer(3, 3))
        with self.assertRaisesRegex(ValueError, 'Network: .*ext.*'):
            _ = self.network.prevs('e0')

    def test_nexts(self):
        ''' Get nexts. '''
        self.network.add('f2', FCLayer(64, 2000, 7), prevs='p1')
        self.network.add('f3', FCLayer(3000, 1000), prevs=('f1', 'f2'))
        self.network.add('e4', EltwiseLayer(1000, 1, 2), prevs=('f1', 'f3'))
        self.network.add('f4', FCLayer(1000, 1000), prevs='e4')

        nexts = self.network.nexts('p1')
        self.assertTupleEqual(nexts, ('f1', 'f2'))

        nexts = self.network.nexts('f1')
        self.assertTupleEqual(nexts, ('f3', 'e4'))

        nexts = self.network.nexts('f2')
        self.assertTupleEqual(nexts, ('f3',))

        nexts = self.network.nexts('f3')
        self.assertTupleEqual(nexts, ('e4',))

    def test_nexts_last(self):
        ''' Get nexts first layer. '''
        nexts = self.network.nexts('f1')
        self.assertTupleEqual(nexts, (None,))

        self.network.add('f2', FCLayer(64, 2000, 7), prevs='p1')

        nexts = self.network.nexts('f1')
        self.assertTupleEqual(nexts, (None,))
        nexts = self.network.nexts('f2')
        self.assertTupleEqual(nexts, (None,))

    def test_nexts_input(self):
        ''' Get nexts input layer. '''
        nexts = self.network.nexts(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(6, 4, 224, 1),
                         prevs=(self.network.INPUT_LAYER_KEY, 'c2'))
        nexts = self.network.nexts(self.network.INPUT_LAYER_KEY)
        self.assertTupleEqual(nexts, ('c1', 'c2', 'c3'))

    def test_firsts(self):
        ''' Get firsts. '''
        firsts = self.network.firsts()
        self.assertTupleEqual(firsts, ('c1',))

        self.network.add('c2', ConvLayer(3, 3, 224, 1),
                         prevs=self.network.INPUT_LAYER_KEY)
        self.network.add('c3', ConvLayer(6, 4, 224, 1),
                         prevs=(self.network.INPUT_LAYER_KEY, 'c2'))

        firsts = self.network.firsts()
        self.assertTupleEqual(firsts, ('c1', 'c2'))
        self.assertIn('c1', firsts)
        self.assertNotIn('c3', firsts)

    def test_firsts_ext(self):
        ''' Get firsts with external layers. '''
        self.network.add_ext('e0', InputLayer(3, 224))

        self.network.add('c2', ConvLayer(3, 3, 224, 1), prevs=('e0',))
        self.network.add('c3', ConvLayer(67, 3, 224, 1), prevs=('e0', 'c1'))
        self.network.add('c4', ConvLayer(6, 3, 224, 1),
                         prevs=(self.network.INPUT_LAYER_KEY, 'e0',))

        firsts = self.network.firsts()
        self.assertIn('c2', firsts)
        self.assertNotIn('c3', firsts)
        self.assertIn('c4', firsts)

    def test_lasts(self):
        ''' Get lasts. '''
        lasts = self.network.lasts()
        self.assertTupleEqual(lasts, ('f1',))

        self.network.add('f2', FCLayer(64, 2000, 7), prevs='p1')

        lasts = self.network.lasts()
        self.assertTupleEqual(lasts, ('f1', 'f2'))

    def test_ext_layers(self):
        ''' Get external layers. '''
        self.assertTupleEqual(self.network.ext_layers(), tuple())

        self.network.add_ext('e0', InputLayer(3, 224))
        self.assertTupleEqual(self.network.ext_layers(), ('e0',))

        self.network.add_ext('e1', InputLayer(3, 224))
        self.assertTupleEqual(self.network.ext_layers(), ('e0', 'e1'))

    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_layer(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('e4', EltwiseLayer(1000, 1, 2), prevs=('f1', 'f3'))
        self.assertEqual(len(self.network), 6)
        self.network.add('f4', FCLayer(1000, 1000), prevs='e4')
        self.assertEqual(len(self.network), 7)

    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_layer(InputLayer(3, 224))
        with self.assertRaises(StopIteration):
            _ = next(iter(network))

    def test_contains_ext(self):
        ''' Whether contains external layer. '''
        self.assertNotIn('e0', self.network)
        self.network.add_ext('e0', InputLayer(3, 224))
        self.assertIn('e0', self.network)

    def test_len_ext(self):
        ''' Accessor len external layer. '''
        self.assertEqual(len(self.network), 3)
        self.network.add_ext('e0', InputLayer(3, 224))
        self.assertEqual(len(self.network), 3)

    def test_iter_ext(self):
        ''' Accessor iter external layer. '''
        self.network.add_ext('e0', InputLayer(3, 224))
        for layer in self.network:
            self.assertNotEqual(layer, 'e0')

    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.assertRaisesRegex(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)


[((987, 1006), 'nn_dataflow.core.Network', 'Network', (['"""test_net"""'], {}), "('test_net')\n", (994, 1006), False, 'from nn_dataflow.core import Network\n'), ((1327, 1346), 'nn_dataflow.core.Network', 'Network', (['"""test_net"""'], {}), "('test_net')\n", (1334, 1346), False, 'from nn_dataflow.core import Network\n'), ((1782, 1801), 'nn_dataflow.core.Network', 'Network', (['"""test_net"""'], {}), "('test_net')\n", (1789, 1801), False, 'from nn_dataflow.core import Network\n'), ((2181, 2200), 'nn_dataflow.core.Network', 'Network', (['"""test_net"""'], {}), "('test_net')\n", (2188, 2200), False, 'from nn_dataflow.core import Network\n'), ((2895, 2914), 'nn_dataflow.core.Network', 'Network', (['"""test_net"""'], {}), "('test_net')\n", (2902, 2914), False, 'from nn_dataflow.core import Network\n'), ((3235, 3254), 'nn_dataflow.core.Network', 'Network', (['"""test_net"""'], {}), "('test_net')\n", (3242, 3254), False, 'from nn_dataflow.core import Network\n'), ((3475, 3494), 'nn_dataflow.core.Network', 'Network', (['"""test_net"""'], {}), "('test_net')\n", (3482, 3494), False, 'from nn_dataflow.core import Network\n'), ((3838, 3857), 'nn_dataflow.core.Network', 'Network', (['"""test_net"""'], {}), "('test_net')\n", (3845, 3857), False, 'from nn_dataflow.core import Network\n'), ((4128, 4147), 'nn_dataflow.core.Network', 'Network', (['"""test_net"""'], {}), "('test_net')\n", (4135, 4147), False, 'from nn_dataflow.core import Network\n'), ((6162, 6181), 'nn_dataflow.core.Network', 'Network', (['"""test_net"""'], {}), "('test_net')\n", (6169, 6181), False, 'from nn_dataflow.core import Network\n'), ((6459, 6478), 'nn_dataflow.core.Network', 'Network', (['"""test_net"""'], {}), "('test_net')\n", (6466, 6478), False, 'from nn_dataflow.core import Network\n'), ((12274, 12293), 'nn_dataflow.core.Network', 'Network', (['"""test_net"""'], {}), "('test_net')\n", (12281, 12293), False, 'from nn_dataflow.core import Network\n'), ((13296, 13315), 'nn_dataflow.core.Network', 'Network', (['"""test_net"""'], {}), "('test_net')\n", (13303, 13315), False, 'from nn_dataflow.core import Network\n'), ((1044, 1062), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(224)'], {}), '(3, 224)\n', (1054, 1062), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((1095, 1119), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(3)', '(64)', '(224)', '(3)'], {}), '(3, 64, 224, 3)\n', (1104, 1119), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((1152, 1175), 'nn_dataflow.core.PoolingLayer', 'PoolingLayer', (['(64)', '(7)', '(32)'], {}), '(64, 7, 32)\n', (1164, 1175), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((1208, 1228), 'nn_dataflow.core.FCLayer', 'FCLayer', (['(64)', '(1000)', '(7)'], {}), '(64, 1000, 7)\n', (1215, 1228), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((1379, 1396), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(24)'], {}), '(3, 24)\n', (1389, 1396), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((2233, 2250), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(24)'], {}), '(3, 24)\n', (2243, 2250), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((2510, 2530), 'nn_dataflow.core.FCLayer', 'FCLayer', (['(64)', '(2000)', '(7)'], {}), '(64, 2000, 7)\n', (2517, 2530), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((2575, 2594), 'nn_dataflow.core.FCLayer', 'FCLayer', (['(3000)', '(1000)'], {}), '(3000, 1000)\n', (2582, 2594), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((2647, 2671), 'nn_dataflow.core.EltwiseLayer', 'EltwiseLayer', (['(1000)', '(1)', '(2)'], {}), '(1000, 1, 2)\n', (2659, 2671), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((2724, 2743), 'nn_dataflow.core.FCLayer', 'FCLayer', (['(1000)', '(1000)'], {}), '(1000, 1000)\n', (2731, 2743), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((2947, 2965), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(224)'], {}), '(3, 224)\n', (2957, 2965), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((2994, 3018), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(3)', '(64)', '(224)', '(3)'], {}), '(3, 64, 224, 3)\n', (3003, 3018), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((3527, 3545), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(224)'], {}), '(3, 224)\n', (3537, 3545), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((3574, 3598), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(3)', '(64)', '(224)', '(3)'], {}), '(3, 64, 224, 3)\n', (3583, 3598), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((3890, 3908), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(224)'], {}), '(3, 224)\n', (3900, 3908), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((4180, 4198), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(224)'], {}), '(3, 224)\n', (4190, 4198), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((4226, 4250), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(3)', '(64)', '(224)', '(3)'], {}), '(3, 64, 224, 3)\n', (4235, 4250), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((5076, 5102), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(64)', '(128)', '(224)', '(3)'], {}), '(64, 128, 224, 3)\n', (5085, 5102), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((5489, 5506), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(24)'], {}), '(3, 24)\n', (5499, 5506), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((5767, 5790), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(5)', '(16, 20)'], {}), '(5, (16, 20))\n', (5777, 5790), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((6213, 6230), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(24)'], {}), '(3, 24)\n', (6223, 6230), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((6829, 6849), 'nn_dataflow.core.FCLayer', 'FCLayer', (['(64)', '(2000)', '(7)'], {}), '(64, 2000, 7)\n', (6836, 6849), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((6894, 6913), 'nn_dataflow.core.FCLayer', 'FCLayer', (['(3000)', '(1000)'], {}), '(3000, 1000)\n', (6901, 6913), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((7306, 7329), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(3)', '(3)', '(224)', '(1)'], {}), '(3, 3, 224, 1)\n', (7315, 7329), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((7906, 7924), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(224)'], {}), '(3, 224)\n', (7916, 7924), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((7957, 7980), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(6)', '(3)', '(224)', '(1)'], {}), '(6, 3, 224, 1)\n', (7966, 7980), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((8251, 8267), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(3)'], {}), '(3, 3)\n', (8261, 8267), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((8464, 8484), 'nn_dataflow.core.FCLayer', 'FCLayer', (['(64)', '(2000)', '(7)'], {}), '(64, 2000, 7)\n', (8471, 8484), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((8529, 8548), 'nn_dataflow.core.FCLayer', 'FCLayer', (['(3000)', '(1000)'], {}), '(3000, 1000)\n', (8536, 8548), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((8601, 8625), 'nn_dataflow.core.EltwiseLayer', 'EltwiseLayer', (['(1000)', '(1)', '(2)'], {}), '(1000, 1, 2)\n', (8613, 8625), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((8678, 8697), 'nn_dataflow.core.FCLayer', 'FCLayer', (['(1000)', '(1000)'], {}), '(1000, 1000)\n', (8685, 8697), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((9263, 9283), 'nn_dataflow.core.FCLayer', 'FCLayer', (['(64)', '(2000)', '(7)'], {}), '(64, 2000, 7)\n', (9270, 9283), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((9687, 9710), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(3)', '(3)', '(224)', '(1)'], {}), '(3, 3, 224, 1)\n', (9696, 9710), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((9804, 9827), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(6)', '(4)', '(224)', '(1)'], {}), '(6, 4, 224, 1)\n', (9813, 9827), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((10194, 10217), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(3)', '(3)', '(224)', '(1)'], {}), '(3, 3, 224, 1)\n', (10203, 10217), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((10311, 10334), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(6)', '(4)', '(224)', '(1)'], {}), '(6, 4, 224, 1)\n', (10320, 10334), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((10688, 10706), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(224)'], {}), '(3, 224)\n', (10698, 10706), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((10740, 10763), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(3)', '(3)', '(224)', '(1)'], {}), '(3, 3, 224, 1)\n', (10749, 10763), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((10811, 10835), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(67)', '(3)', '(224)', '(1)'], {}), '(67, 3, 224, 1)\n', (10820, 10835), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((10888, 10911), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(6)', '(3)', '(224)', '(1)'], {}), '(6, 3, 224, 1)\n', (10897, 10911), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((11303, 11323), 'nn_dataflow.core.FCLayer', 'FCLayer', (['(64)', '(2000)', '(7)'], {}), '(64, 2000, 7)\n', (11310, 11323), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((11597, 11615), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(224)'], {}), '(3, 224)\n', (11607, 11615), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((11719, 11737), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(224)'], {}), '(3, 224)\n', (11729, 11737), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((12077, 12097), 'nn_dataflow.core.FCLayer', 'FCLayer', (['(64)', '(2000)', '(7)'], {}), '(64, 2000, 7)\n', (12084, 12097), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((12368, 12386), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(224)'], {}), '(3, 224)\n', (12378, 12386), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((12456, 12479), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(3)', '(4)', '(224)', '(1)'], {}), '(3, 4, 224, 1)\n', (12465, 12479), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((12555, 12575), 'nn_dataflow.core.FCLayer', 'FCLayer', (['(64)', '(2000)', '(7)'], {}), '(64, 2000, 7)\n', (12562, 12575), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((12667, 12686), 'nn_dataflow.core.FCLayer', 'FCLayer', (['(3000)', '(1000)'], {}), '(3000, 1000)\n', (12674, 12686), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((12786, 12810), 'nn_dataflow.core.EltwiseLayer', 'EltwiseLayer', (['(1000)', '(1)', '(2)'], {}), '(1000, 1, 2)\n', (12798, 12810), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((12910, 12929), 'nn_dataflow.core.FCLayer', 'FCLayer', (['(1000)', '(1000)'], {}), '(1000, 1000)\n', (12917, 12929), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((13348, 13366), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(224)'], {}), '(3, 224)\n', (13358, 13366), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((13614, 13632), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(224)'], {}), '(3, 224)\n', (13624, 13632), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((13832, 13850), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(224)'], {}), '(3, 224)\n', (13842, 13850), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((14010, 14028), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(224)'], {}), '(3, 224)\n', (14020, 14028), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((1914, 1926), 'nn_dataflow.core.Layer', 'Layer', (['(3)', '(24)'], {}), '(3, 24)\n', (1919, 1926), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((2040, 2062), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(3)', '(8)', '(24)', '(3)'], {}), '(3, 8, 24, 3)\n', (2049, 2062), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((2357, 2374), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(24)'], {}), '(3, 24)\n', (2367, 2374), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((3116, 3142), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(64)', '(128)', '(224)', '(3)'], {}), '(64, 128, 224, 3)\n', (3125, 3142), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((3359, 3383), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(3)', '(64)', '(224)', '(3)'], {}), '(3, 64, 224, 3)\n', (3368, 3383), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((3702, 3725), 'nn_dataflow.core.PoolingLayer', 'PoolingLayer', (['(64)', '(7)', '(32)'], {}), '(64, 7, 32)\n', (3714, 3725), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((4406, 4428), 'nn_dataflow.core.PoolingLayer', 'PoolingLayer', (['(64)', '(7)', '(2)'], {}), '(64, 7, 2)\n', (4418, 4428), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((4625, 4651), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(64)', '(128)', '(220)', '(3)'], {}), '(64, 128, 220, 3)\n', (4634, 4651), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((4804, 4827), 'nn_dataflow.core.PoolingLayer', 'PoolingLayer', (['(32)', '(7)', '(32)'], {}), '(32, 7, 32)\n', (4816, 4827), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((4979, 5005), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(32)', '(128)', '(224)', '(3)'], {}), '(32, 128, 224, 3)\n', (4988, 5005), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((5255, 5279), 'nn_dataflow.core.PoolingLayer', 'PoolingLayer', (['(128)', '(7)', '(32)'], {}), '(128, 7, 32)\n', (5267, 5279), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((6333, 6350), 'nn_dataflow.core.InputLayer', 'InputLayer', (['(3)', '(24)'], {}), '(3, 24)\n', (6343, 6350), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((6593, 6605), 'nn_dataflow.core.Layer', 'Layer', (['(3)', '(24)'], {}), '(3, 24)\n', (6598, 6605), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n'), ((6720, 6742), 'nn_dataflow.core.ConvLayer', 'ConvLayer', (['(3)', '(8)', '(24)', '(3)'], {}), '(3, 8, 24, 3)\n', (6729, 6742), False, 'from nn_dataflow.core import Layer, InputLayer, ConvLayer, FCLayer, PoolingLayer, EltwiseLayer\n')]