コード例 #1
0
    def _make_data_layout(self, nfm, hfm, wfm, origin, nums, dims):
        ''' Make a DataLayout instance. '''
        assert util.prod(nums) == dims.size()

        def _coord(idxs):
            # In the order of n, b, w, h, i.e., 1, 0, 3, 2.
            cflat = 0
            for i in [1, 0, 3, 2]:
                cflat = cflat * nums[i] + idxs[i]
            assert cflat < dims.size()
            return PhyDim2(*divmod(cflat, dims.w))

        sizes = (self.batch_size, nfm, hfm, wfm)

        frmap = FmapRangeMap()

        for idxs in itertools.product(*[range(n) for n in nums]):

            begs = [i * s // n for i, n, s in zip(idxs, nums, sizes)]
            ends = [(i + 1) * s // n for i, n, s in zip(idxs, nums, sizes)]

            frmap.add(FmapRange(begs, ends), (_coord(idxs), ))

        dl = DataLayout(frmap=frmap, origin=origin, type=NodeRegion.DATA)
        assert dl.frmap.complete_fmap_range().size() == util.prod(sizes)

        return dl
コード例 #2
0
 def setUp(self):
     self.frm = FmapRangeMap()
     self.frm.add(FmapRange((0, 0, 0, 0), (2, 4, 8, 16)), 0)
     self.frm.add(FmapRange((0, 0, 8, 0), (2, 4, 16, 16)), 1)
     self.frm.add(FmapRange((0, 4, 0, 0), (2, 8, 8, 16)), 2)
     self.frm.add(FmapRange((0, 4, 8, 0), (2, 8, 16, 16)), 3)
     self.frm.add(FmapRange((2, 0, 0, 0), (4, 4, 8, 16)), 4)
     self.frm.add(FmapRange((2, 0, 8, 0), (4, 4, 16, 16)), 5)
     self.frm.add(FmapRange((2, 4, 0, 0), (4, 8, 8, 16)), 6)
     self.frm.add(FmapRange((2, 4, 8, 0), (4, 8, 16, 16)), 7)
コード例 #3
0
 def setUp(self):
     self.frm = FmapRangeMap()
     self.frm.add(FmapRange((0, 0, 0, 0), (2, 4, 8, 16)), (PhyDim2(0, 0), ))
     self.frm.add(FmapRange((0, 0, 8, 0), (2, 4, 16, 16)),
                  (PhyDim2(1, 0), ))
     self.frm.add(FmapRange((2, 0, 0, 0), (4, 4, 8, 16)), (PhyDim2(0, 1), ))
     self.frm.add(FmapRange((2, 0, 8, 0), (4, 4, 16, 16)),
                  (PhyDim2(1, 1), ))
     self.dly = DataLayout(origin=PhyDim2(1, 1),
                           frmap=self.frm,
                           type=NodeRegion.DATA)
コード例 #4
0
    def test_merge(self):
        ''' Merge. '''
        fr = FmapRange((0, ) * 4, (30, ) * 4)

        frm = FmapRangeMap()
        frm.add(FmapRange((0, 0, 0, 0), (4, 1, 16, 16)),
                (PhyDim2(0, 0), PhyDim2(1, 1)))
        frm.add(FmapRange((0, 1, 0, 0), (4, 3, 16, 16)),
                (PhyDim2(1, 0), PhyDim2(2, 2)))
        dly = DataLayout(origin=PhyDim2(-1, -1),
                         frmap=frm,
                         type=NodeRegion.DATA)

        mdly1 = self.dly.merge('|', dly)
        mdly2 = dly.merge('|', self.dly)
        self.assertEqual(mdly1.type, self.dly.type, 'merge |: type')
        self.assertEqual(mdly2.type, dly.type, 'merge |: type')
        self.assertEqual(mdly1.frmap.complete_fmap_range(),
                         mdly2.frmap.complete_fmap_range(),
                         'merge |: complete_fmap_range')
        self.assertEqual(
            mdly1.frmap.complete_fmap_range().size(),
            self.frm.complete_fmap_range().size() +
            frm.complete_fmap_range().size(),
            'merge |: complete_fmap_range: size')
        self.assertEqual(mdly1.total_transfer_nhops(fr, PhyDim2(0, 0)),
                         mdly2.total_transfer_nhops(fr, PhyDim2(0, 0)),
                         'merge |: nhops')
        self.assertEqual(
            mdly1.total_transfer_nhops(fr, PhyDim2(0, 0)),
            self.dly.total_transfer_nhops(fr, PhyDim2(0, 0)) +
            dly.total_transfer_nhops(fr, PhyDim2(0, 0)), 'merge |: nhops')

        frm.add(FmapRange((0, 3, 0, 0), (4, 4, 16, 16)),
                (PhyDim2(1, 3), PhyDim2(2, 1), PhyDim2(-1, -2)))
        # Only type differs from self.dly.
        sdly = DataLayout(origin=self.dly.origin,
                          frmap=self.dly.frmap,
                          type=NodeRegion.PROC)
        dly = DataLayout(origin=PhyDim2(-1, -1),
                         frmap=frm,
                         type=NodeRegion.PROC)
        mdly1 = sdly.merge('+', dly)
        mdly2 = dly.merge('+', sdly)
        self.assertEqual(mdly1.type, sdly.type, 'merge +: type')
        self.assertEqual(mdly2.type, dly.type, 'merge +: type')
        self.assertEqual(mdly1.frmap.complete_fmap_range(),
                         mdly2.frmap.complete_fmap_range(),
                         'merge +: complete_fmap_range')
        self.assertEqual(mdly1.frmap.complete_fmap_range().size(),
                         self.frm.complete_fmap_range().size(),
                         'merge +: complete_fmap_range: size')
        self.assertEqual(mdly1.total_transfer_nhops(fr, PhyDim2(0, 0)),
                         mdly2.total_transfer_nhops(fr, PhyDim2(0, 0)),
                         'merge +: nhops')
        self.assertEqual(
            mdly1.total_transfer_nhops(fr, PhyDim2(0, 0)),
            sdly.total_transfer_nhops(fr, PhyDim2(0, 0)) +
            dly.total_transfer_nhops(fr, PhyDim2(0, 0)), 'merge +: nhops')
コード例 #5
0
    def setUp(self):

        self.resource = Resource(
            proc_region=NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(1, 1),
                                   type=NodeRegion.PROC),
            data_regions=(NodeRegion(origin=PhyDim2(0, 0), dim=PhyDim2(1, 1),
                                     type=NodeRegion.DATA),),
            dim_array=PhyDim2(16, 16), size_gbuf=65536, size_regf=64)

        frmap = FmapRangeMap()
        frmap.add(FmapRange((0, 0, 0, 0), (2, 4, 16, 16)), (PhyDim2(0, 0),))
        self.ifmap_layout = DataLayout(origin=PhyDim2(0, 0), frmap=frmap,
                                       type=NodeRegion.DATA)
コード例 #6
0
    def test_merge_unmatch(self):
        ''' Merge unmatch. '''
        for fr in [
                FmapRange((0, ) * 4, (4, 4, 10, 16)),
                FmapRange((0, ) * 4, (4, 4, 16, 32)),
                FmapRange((0, ) * 4, (3, 4, 16, 16))
        ]:
            frm = FmapRangeMap()
            frm.add(fr, (PhyDim2(1, 1), ))
            dly = DataLayout(origin=PhyDim2(-1, -1),
                             frmap=frm,
                             type=NodeRegion.DATA)

            with self.assertRaisesRegexp(ValueError, 'DataLayout: .*match.*'):
                _ = self.dly.merge('|', dly)
            with self.assertRaisesRegexp(ValueError, 'DataLayout: .*match.*'):
                _ = self.dly.merge('+', dly)

        frm = FmapRangeMap()
        frm.add(FmapRange((0, ) * 4, (4, 2, 16, 16)), (PhyDim2(1, 1), ))
        dly = DataLayout(origin=PhyDim2(-1, -1),
                         frmap=frm,
                         type=NodeRegion.DATA)

        with self.assertRaisesRegexp(ValueError, 'DataLayout: .*match.*'):
            _ = self.dly.merge('+', dly)
コード例 #7
0
    def setUp(self):

        self.dict_loop = OrderedDict([
            ('cost', 1.234),
            ('time', 123.4),
            ('ops', 1234),
            ('access', [[2, 3, 4], [30, 40, 50], [400, 500, 600],
                        [5000, 6000, 7000]]),
        ])
        self.dict_part = OrderedDict([
            ('cost', 9.876),
            ('total_nhops', [123, 456, 789]),
        ])

        frmap = FmapRangeMap()
        frmap.add(FmapRange((0, 0, 0, 0), (2, 4, 16, 16)), (PhyDim2(0, 0), ))
        self.ofmap_layout = DataLayout(origin=PhyDim2(0, 0),
                                       frmap=frmap,
                                       type=NodeRegion.DATA)
コード例 #8
0
    def test_o_full_layer(self):
        ''' ofmap full layer. '''
        for wlkey in self.layers:
            layer = self.layers[wlkey]

            for dnkey in self.dim_nodes:

                for part in self._gen_partition(wlkey=wlkey,
                                                dnkey=dnkey,
                                                optkey='NOINPP'):

                    frmap = FmapRangeMap()

                    for pidx in part.gen_pidx():

                        fr = partition.part_layer_ofmap_range(
                            layer, self.batch_size, part, pidx)
                        frmap.add(fr, 0)

                    self.assertTrue(frmap.is_complete())

                    cfr = frmap.complete_fmap_range()
                    self.assertEqual(cfr.size('b'), self.batch_size)
                    self.assertEqual(cfr.size('n'), layer.nofm)
                    self.assertEqual(cfr.size('h'), layer.hofm)
                    self.assertEqual(cfr.size('w'), layer.wofm)
コード例 #9
0
 def test_invalid_frmap_value_type(self):
     ''' Invalid frmap value type. '''
     frm = FmapRangeMap()
     frm.add(FmapRange((0, ) * 4, (5, 5, 19, 19)), PhyDim2(4, 4))
     with self.assertRaisesRegexp(TypeError, 'DataLayout: .*frmap.*'):
         _ = DataLayout(origin=PhyDim2(2, 3),
                        frmap=frm,
                        type=NodeRegion.DATA)
     frm = FmapRangeMap()
     frm.add(FmapRange((0, ) * 4, (5, 5, 19, 19)), (PhyDim2(4, 4), 4))
     with self.assertRaisesRegexp(TypeError, 'DataLayout: .*frmap.*'):
         _ = DataLayout(origin=PhyDim2(2, 3),
                        frmap=frm,
                        type=NodeRegion.DATA)
コード例 #10
0
    def test_complete_fmap_range(self):
        ''' Get complete_fmap_range. '''
        self.assertTrue(self.frm.is_complete(), 'is_complete')
        self.assertEqual(self.frm.complete_fmap_range().size(), 4 * 8 * 16 * 16,
                         'complete_fmap_range')

        fr = FmapRange((0, 0, 0, 0), (3, 5, 7, 9))
        frm = FmapRangeMap()
        frm.add(fr, 3.4)
        self.assertTrue(frm.is_complete(), 'is_complete')
        self.assertEqual(frm.complete_fmap_range(), fr, 'complete_fmap_range')
コード例 #11
0
    def test_is_complete_incomplete(self):
        ''' Get complete_fmap_range incomplete. '''
        self.frm.add(FmapRange((4, 8, 16, 16), (5, 9, 17, 17)), 10)
        self.assertFalse(self.frm.is_complete(), 'is_complete: incomplete')
        with self.assertRaisesRegex(ValueError, 'FmapRangeMap: .*complete.*'):
            _ = self.frm.complete_fmap_range()

        fr = FmapRange((1, 0, 0, 0), (3, 5, 7, 9))
        frm = FmapRangeMap()
        frm.add(fr, 3.4)
        self.assertFalse(frm.is_complete(), 'is_complete: incomplete')
        with self.assertRaisesRegex(ValueError, 'FmapRangeMap: .*complete.*'):
            _ = frm.complete_fmap_range()
コード例 #12
0
    def test_io_full_layer(self):
        ''' i/ofmap full layer. '''
        for wlkey in ['SM', 'POOL']:
            layer = self.layers[wlkey]

            for dnkey in self.dim_nodes:

                for part in self._gen_partition(wlkey=wlkey,
                                                dnkey=dnkey,
                                                optkey='NOINPP'):

                    # Remove ifmap point from full set.
                    ifp_set = set(
                        FmapRange(fp_beg=(0, 0, 0, 0),
                                  fp_end=(self.batch_size, layer.nifm,
                                          layer.hifm, layer.wifm)).range())
                    # Add ofmap ranges to a map.
                    ofrmap = FmapRangeMap()

                    for pidx in part.gen_pidx():

                        _, ifrng, ofrng = partition.proc_data_range(
                            layer, self.batch_size, part, pidx)

                        for ifp in ifrng.range():
                            ifp_set.discard(ifp)

                        ofrmap.add(ofrng, 0)

                    # Ifmap point set should be empty now.
                    self.assertFalse(ifp_set)

                    # Ofmap range map should be full now.
                    self.assertTrue(ofrmap.is_complete())
                    cfr = ofrmap.complete_fmap_range()
                    self.assertEqual(cfr.size('b'), self.batch_size)
                    self.assertEqual(cfr.size('n'), layer.nofm)
                    self.assertEqual(cfr.size('h'), layer.hofm)
                    self.assertEqual(cfr.size('w'), layer.wofm)
コード例 #13
0
class TestFmapRangeMap(unittest.TestCase):
    ''' Tests for FmapRangeMap. '''

    def setUp(self):
        self.frm = FmapRangeMap()
        self.frm.add(FmapRange((0, 0, 0, 0), (2, 4, 8, 16)), 0)
        self.frm.add(FmapRange((0, 0, 8, 0), (2, 4, 16, 16)), 1)
        self.frm.add(FmapRange((0, 4, 0, 0), (2, 8, 8, 16)), 2)
        self.frm.add(FmapRange((0, 4, 8, 0), (2, 8, 16, 16)), 3)
        self.frm.add(FmapRange((2, 0, 0, 0), (4, 4, 8, 16)), 4)
        self.frm.add(FmapRange((2, 0, 8, 0), (4, 4, 16, 16)), 5)
        self.frm.add(FmapRange((2, 4, 0, 0), (4, 8, 8, 16)), 6)
        self.frm.add(FmapRange((2, 4, 8, 0), (4, 8, 16, 16)), 7)

    def test_add(self):
        ''' Modifier add. '''
        self.frm.add(FmapRange((4, 8, 16, 16), (5, 9, 17, 17)), 10)
        self.assertEqual(self.frm.get(FmapPosition(4, 8, 16, 16)), 10, 'add')
        self.frm.add(FmapRange((10, 10, 20, 20), (15, 19, 27, 27)), 11)
        self.assertEqual(self.frm.get(FmapPosition(14, 15, 22, 24)), 11, 'add')

    def test_add_zero_fr(self):
        ''' Modifier add zero FmapRange. '''
        num_items = len(list(self.frm.items()))
        self.frm.add(FmapRange((5, 9, 17, 17), (5, 9, 17, 17)), 10)
        self.assertEqual(len(list(self.frm.items())), num_items)

    def test_add_overlap_fr(self):
        ''' Modifier add overlapping FmapRange. '''
        with self.assertRaisesRegex(ValueError, 'FmapRangeMap: .*overlap.*'):
            self.frm.add(FmapRange((3, 7, 15, 15), (5, 9, 17, 17)), 10)

    def test_get(self):
        ''' Get. '''
        self.assertEqual(self.frm.get(FmapPosition(3, 5, 7, 9)), 6, 'get')
        self.assertEqual(self.frm.get(FmapPosition(0, 0, 0, 0)), 0, 'get')
        self.assertEqual(self.frm.get(FmapPosition(2, 1, 1, 12)), 4, 'get')
        self.assertEqual(self.frm.get(FmapPosition(3, 7, 15, 15)), 7, 'get')

    def test_get_not_in(self):
        ''' Get not in. '''
        with self.assertRaisesRegex(KeyError, 'FmapRangeMap: .*key.*'):
            _ = self.frm.get(FmapPosition(4, 8, 16, 16))

    def test_complete_fmap_range(self):
        ''' Get complete_fmap_range. '''
        self.assertTrue(self.frm.is_complete(), 'is_complete')
        self.assertEqual(self.frm.complete_fmap_range().size(), 4 * 8 * 16 * 16,
                         'complete_fmap_range')

        fr = FmapRange((0, 0, 0, 0), (3, 5, 7, 9))
        frm = FmapRangeMap()
        frm.add(fr, 3.4)
        self.assertTrue(frm.is_complete(), 'is_complete')
        self.assertEqual(frm.complete_fmap_range(), fr, 'complete_fmap_range')

    def test_is_complete_incomplete(self):
        ''' Get complete_fmap_range incomplete. '''
        self.frm.add(FmapRange((4, 8, 16, 16), (5, 9, 17, 17)), 10)
        self.assertFalse(self.frm.is_complete(), 'is_complete: incomplete')
        with self.assertRaisesRegex(ValueError, 'FmapRangeMap: .*complete.*'):
            _ = self.frm.complete_fmap_range()

        fr = FmapRange((1, 0, 0, 0), (3, 5, 7, 9))
        frm = FmapRangeMap()
        frm.add(fr, 3.4)
        self.assertFalse(frm.is_complete(), 'is_complete: incomplete')
        with self.assertRaisesRegex(ValueError, 'FmapRangeMap: .*complete.*'):
            _ = frm.complete_fmap_range()

    def test_items(self):
        ''' Accessor items. '''
        size = 0
        for k, v in self.frm.items():
            size += k.size()
            self.assertEqual(self.frm.get(k.fp_beg), v, 'items: keyval')
        self.assertEqual(size, 4 * 8 * 16 * 16, 'items: size')

    def test_copy(self):
        ''' Copy. '''
        frm = self.frm.copy()
        self.assertListEqual(list(frm.items()), list(self.frm.items()),
                             'copy: equal')

        fr1 = FmapRange((10, 10, 10, 10), (11, 11, 11, 11))
        frm.add(fr1, 10)
        self.assertEqual(frm.get(fr1.fp_beg), 10, 'copy: in')
        with self.assertRaisesRegex(KeyError, 'FmapRangeMap: .*key.*'):
            _ = self.frm.get(fr1.fp_beg)

        fr2 = FmapRange((20, 20, 20, 20), (21, 21, 21, 21))
        self.frm.add(fr2, 20)
        self.assertEqual(self.frm.get(fr2.fp_beg), 20, 'copy: in')
        with self.assertRaisesRegex(KeyError, 'FmapRangeMap: .*key.*'):
            _ = frm.get(fr2.fp_beg)

    def test_rget_counter(self):
        ''' Get rget_counter. '''
        fr = FmapRange((1, 3, 9, 11), (3, 5, 13, 15))
        counters = self.frm.rget_counter(fr)
        self.assertEqual(sum(counters.values()), fr.size(), 'rget_counter')

        fr = FmapRange((0, 0, 0, 0), (0, 0, 0, 0))
        counters = self.frm.rget_counter(fr)
        self.assertEqual(sum(counters.values()), 0, 'rget_counter')

        fr = FmapRange((1, 3, 9, 11), (3, 5, 13, 17))
        counters = self.frm.rget_counter(fr)
        self.assertLess(sum(counters.values()), fr.size(), 'rget_counter')
        self.assertEqual(sum(counters.values()),
                         self.frm.complete_fmap_range().overlap(fr).size(),
                         'rget_counter')

    def test_rget_counter_same_vals(self):
        ''' Get rget_counter when there are same values in FmapRangeMap. '''
        self.frm.add(FmapRange((0, 0, 0, 16), (4, 8, 16, 32)), 2)
        fr = FmapRange((1, 3, 9, 11), (3, 5, 13, 17))
        counters = self.frm.rget_counter(fr)
        self.assertEqual(sum(counters.values()), fr.size())

    def test_rget_single(self):
        ''' Get rget_single. '''
        for k, v in self.frm.items():
            self.assertEqual(self.frm.rget_single(k), v, 'rget_single')

        val = self.frm.rget_single(FmapRange((0, 0, 0, 0), (1, 1, 1, 1)))
        self.assertEqual(val, 0, 'rget_single')

        val = self.frm.rget_single(FmapRange((3, 1, 10, 3), (4, 3, 13, 7)))
        self.assertEqual(val, 5, 'rget_single')

    def test_rget_single_multi(self):
        ''' Get rget_single with . '''
        with self.assertRaisesRegex(ValueError, 'FmapRangeMap: .*single.*'):
            _ = self.frm.rget_single(FmapRange((3, 1, 10, 3), (4, 6, 13, 7)))

    def test_str(self):
        ''' Get string. '''
        string = str(self.frm)
        for k, v in self.frm.items():
            self.assertIn(str(k), string)
            self.assertIn(str(v), string)
コード例 #14
0
class TestDataLayout(unittest.TestCase):
    ''' Tests for DataLayout. '''
    def setUp(self):
        self.frm = FmapRangeMap()
        self.frm.add(FmapRange((0, 0, 0, 0), (2, 4, 8, 16)), (PhyDim2(0, 0), ))
        self.frm.add(FmapRange((0, 0, 8, 0), (2, 4, 16, 16)),
                     (PhyDim2(1, 0), ))
        self.frm.add(FmapRange((2, 0, 0, 0), (4, 4, 8, 16)), (PhyDim2(0, 1), ))
        self.frm.add(FmapRange((2, 0, 8, 0), (4, 4, 16, 16)),
                     (PhyDim2(1, 1), ))
        self.dly = DataLayout(origin=PhyDim2(1, 1),
                              frmap=self.frm,
                              type=NodeRegion.DATA)

    def test_valid_args(self):
        ''' Valid arguments. '''
        self.assertEqual(self.dly.frmap.complete_fmap_range(),
                         FmapRange((0, 0, 0, 0), (4, 4, 16, 16)))

    def test_invalid_origin(self):
        ''' Invalid origin. '''
        with self.assertRaisesRegexp(TypeError, 'DataLayout: .*origin.*'):
            _ = DataLayout(origin=(2, 3), frmap=self.frm, type=NodeRegion.DATA)

    def test_invalid_frmap_type(self):
        ''' Invalid frmap type. '''
        with self.assertRaisesRegexp(TypeError, 'DataLayout: .*frmap.*'):
            _ = DataLayout(origin=PhyDim2(2, 3),
                           frmap=FmapRange((0, ) * 4, (1, ) * 4),
                           type=NodeRegion.DATA)

    def test_invalid_frmap_incomplete(self):
        ''' Invalid frmap incomplete. '''
        frm = self.frm.copy()
        frm.add(FmapRange((4, 4, 16, 16), (5, 5, 19, 19)), (PhyDim2(4, 4), ))
        with self.assertRaisesRegexp(ValueError, 'DataLayout: .*frmap.*'):
            _ = DataLayout(origin=PhyDim2(2, 3),
                           frmap=frm,
                           type=NodeRegion.DATA)

    def test_invalid_frmap_value_type(self):
        ''' Invalid frmap value type. '''
        frm = FmapRangeMap()
        frm.add(FmapRange((0, ) * 4, (5, 5, 19, 19)), PhyDim2(4, 4))
        with self.assertRaisesRegexp(TypeError, 'DataLayout: .*frmap.*'):
            _ = DataLayout(origin=PhyDim2(2, 3),
                           frmap=frm,
                           type=NodeRegion.DATA)
        frm = FmapRangeMap()
        frm.add(FmapRange((0, ) * 4, (5, 5, 19, 19)), (PhyDim2(4, 4), 4))
        with self.assertRaisesRegexp(TypeError, 'DataLayout: .*frmap.*'):
            _ = DataLayout(origin=PhyDim2(2, 3),
                           frmap=frm,
                           type=NodeRegion.DATA)

    def test_invalid_type(self):
        ''' Invalid type. '''
        with self.assertRaisesRegexp(ValueError, 'DataLayout: .*type.*'):
            _ = DataLayout(origin=PhyDim2(2, 3),
                           frmap=self.frm,
                           type=NodeRegion.NUM)

    def test_is_in_region(self):
        ''' Whether is in region. '''
        nr1 = NodeRegion(dim=PhyDim2(2, 2),
                         origin=PhyDim2(1, 1),
                         type=NodeRegion.DATA)
        self.assertTrue(self.dly.is_in_region(nr1))
        nr2 = NodeRegion(dim=PhyDim2(3, 3),
                         origin=PhyDim2(0, 0),
                         type=NodeRegion.DATA)
        self.assertTrue(self.dly.is_in_region(nr2))
        nr3 = NodeRegion(dim=PhyDim2(2, 2),
                         origin=PhyDim2(0, 0),
                         type=NodeRegion.DATA)
        self.assertFalse(self.dly.is_in_region(nr3))
        nr4 = NodeRegion(dim=PhyDim2(3, 3),
                         origin=PhyDim2(0, 0),
                         type=NodeRegion.PROC)
        self.assertFalse(self.dly.is_in_region(nr4))

        frm = self.frm.copy()
        frm.add(FmapRange((0, 0, 0, 16), (4, 4, 16, 20)),
                (PhyDim2(2, 2), PhyDim2(3, 3)))
        dly = DataLayout(origin=PhyDim2(1, 1), frmap=frm, type=NodeRegion.DATA)

        nr4 = NodeRegion(dim=PhyDim2(3, 3),
                         origin=PhyDim2(1, 1),
                         type=NodeRegion.DATA)
        self.assertFalse(dly.is_in_region(nr4))
        nr5 = NodeRegion(dim=PhyDim2(4, 4),
                         origin=PhyDim2(1, 1),
                         type=NodeRegion.DATA)
        self.assertTrue(dly.is_in_region(nr5))

        frm.add(FmapRange((0, 0, 16, 0), (4, 4, 20, 20)),
                (PhyDim2(1, 1), PhyDim2(3, 3), PhyDim2(5, 5)))
        dly = DataLayout(origin=PhyDim2(1, 1), frmap=frm, type=NodeRegion.DATA)

        self.assertFalse(dly.is_in_region(nr5))
        nr6 = NodeRegion(dim=PhyDim2(7, 7),
                         origin=PhyDim2(0, 0),
                         type=NodeRegion.DATA)
        self.assertTrue(dly.is_in_region(nr6))

    def test_total_transfer_nhops(self):
        ''' Get total_transfer_nhops. '''
        fr = FmapRange((0, ) * 4, (4, 4, 16, 16))
        nhops = 2 * 4 * 8 * 16 * (5 + 6 + 6 + 7)
        self.assertEqual(self.dly.total_transfer_nhops(fr, PhyDim2(-1, -2)),
                         nhops, 'total_transfer_nhops')

        frm = self.frm.copy()
        frm.add(FmapRange((0, 0, 0, 16), (4, 4, 16, 20)),
                (PhyDim2(2, 2), PhyDim2(3, 3)))
        frm.add(FmapRange((0, 0, 16, 0), (4, 4, 20, 20)),
                (PhyDim2(1, 1), PhyDim2(3, 3), PhyDim2(5, 5)))
        dly = DataLayout(origin=PhyDim2(1, 1), frmap=frm, type=NodeRegion.DATA)

        self.assertEqual(dly.total_transfer_nhops(fr, PhyDim2(-1, -2)), nhops,
                         'total_transfer_nhops')

        nhops += 4 * 4 * 16 * 4 * (9 + 11) + 4 * 4 * 4 * 20 * (7 + 11 + 15)
        fr = FmapRange((0, ) * 4, (20, ) * 4)
        self.assertEqual(dly.total_transfer_nhops(fr, PhyDim2(-1, -2)), nhops,
                         'total_transfer_nhops')

    def test_view(self):
        ''' Get view. '''
        frm = self.frm.copy()
        frm.add(FmapRange((0, 0, 0, 16), (4, 4, 16, 20)),
                (PhyDim2(2, 2), PhyDim2(3, 3)))
        frm.add(FmapRange((0, 0, 16, 0), (4, 4, 20, 20)),
                (PhyDim2(1, 1), PhyDim2(3, 3), PhyDim2(5, 5)))
        dly = DataLayout(origin=PhyDim2(1, 1), frmap=frm, type=NodeRegion.DATA)

        cfr = dly.frmap.complete_fmap_range()
        counters = dly.frmap.rget_counter(cfr)
        nhops = dly.total_transfer_nhops(cfr, PhyDim2(1, 2))

        dly1 = dly.view(PhyDim2(-1, -1))
        self.assertEqual(dly1.origin, PhyDim2(0, 0), 'view: origin')
        self.assertEqual(dly1.type, dly.type, 'view: type')
        self.assertEqual(dly1.frmap.complete_fmap_range(), cfr,
                         'view: complete_fmap_range')
        self.assertDictEqual(dly1.frmap.rget_counter(cfr), counters,
                             'view: counter')
        self.assertEqual(
            dly1.total_transfer_nhops(cfr,
                                      PhyDim2(1, 2) + PhyDim2(-1, -1)), nhops,
            'view: nhops')

        dly2 = dly.view(PhyDim2(3, 1))
        self.assertEqual(dly2.type, dly.type, 'view: type')
        self.assertEqual(dly2.frmap.complete_fmap_range(), cfr,
                         'view: complete_fmap_range')
        self.assertDictEqual(dly2.frmap.rget_counter(cfr), counters,
                             'view: counter')
        self.assertEqual(
            dly2.total_transfer_nhops(cfr,
                                      PhyDim2(1, 2) + PhyDim2(3, 1)), nhops,
            'view: nhops')

    def test_merge(self):
        ''' Merge. '''
        fr = FmapRange((0, ) * 4, (30, ) * 4)

        frm = FmapRangeMap()
        frm.add(FmapRange((0, 0, 0, 0), (4, 1, 16, 16)),
                (PhyDim2(0, 0), PhyDim2(1, 1)))
        frm.add(FmapRange((0, 1, 0, 0), (4, 3, 16, 16)),
                (PhyDim2(1, 0), PhyDim2(2, 2)))
        dly = DataLayout(origin=PhyDim2(-1, -1),
                         frmap=frm,
                         type=NodeRegion.DATA)

        mdly1 = self.dly.merge('|', dly)
        mdly2 = dly.merge('|', self.dly)
        self.assertEqual(mdly1.type, self.dly.type, 'merge |: type')
        self.assertEqual(mdly2.type, dly.type, 'merge |: type')
        self.assertEqual(mdly1.frmap.complete_fmap_range(),
                         mdly2.frmap.complete_fmap_range(),
                         'merge |: complete_fmap_range')
        self.assertEqual(
            mdly1.frmap.complete_fmap_range().size(),
            self.frm.complete_fmap_range().size() +
            frm.complete_fmap_range().size(),
            'merge |: complete_fmap_range: size')
        self.assertEqual(mdly1.total_transfer_nhops(fr, PhyDim2(0, 0)),
                         mdly2.total_transfer_nhops(fr, PhyDim2(0, 0)),
                         'merge |: nhops')
        self.assertEqual(
            mdly1.total_transfer_nhops(fr, PhyDim2(0, 0)),
            self.dly.total_transfer_nhops(fr, PhyDim2(0, 0)) +
            dly.total_transfer_nhops(fr, PhyDim2(0, 0)), 'merge |: nhops')

        frm.add(FmapRange((0, 3, 0, 0), (4, 4, 16, 16)),
                (PhyDim2(1, 3), PhyDim2(2, 1), PhyDim2(-1, -2)))
        # Only type differs from self.dly.
        sdly = DataLayout(origin=self.dly.origin,
                          frmap=self.dly.frmap,
                          type=NodeRegion.PROC)
        dly = DataLayout(origin=PhyDim2(-1, -1),
                         frmap=frm,
                         type=NodeRegion.PROC)
        mdly1 = sdly.merge('+', dly)
        mdly2 = dly.merge('+', sdly)
        self.assertEqual(mdly1.type, sdly.type, 'merge +: type')
        self.assertEqual(mdly2.type, dly.type, 'merge +: type')
        self.assertEqual(mdly1.frmap.complete_fmap_range(),
                         mdly2.frmap.complete_fmap_range(),
                         'merge +: complete_fmap_range')
        self.assertEqual(mdly1.frmap.complete_fmap_range().size(),
                         self.frm.complete_fmap_range().size(),
                         'merge +: complete_fmap_range: size')
        self.assertEqual(mdly1.total_transfer_nhops(fr, PhyDim2(0, 0)),
                         mdly2.total_transfer_nhops(fr, PhyDim2(0, 0)),
                         'merge +: nhops')
        self.assertEqual(
            mdly1.total_transfer_nhops(fr, PhyDim2(0, 0)),
            sdly.total_transfer_nhops(fr, PhyDim2(0, 0)) +
            dly.total_transfer_nhops(fr, PhyDim2(0, 0)), 'merge +: nhops')

    def test_merge_invalid_type(self):
        ''' Merge invalid. '''
        with self.assertRaisesRegexp(TypeError, 'DataLayout: .*other.*'):
            _ = self.dly.merge('|', self.frm)
        with self.assertRaisesRegexp(TypeError, 'DataLayout: .*other.*'):
            _ = self.dly.merge('+', PhyDim2(1, 3))

    def test_merge_invalid_region_type(self):
        ''' Merge invalid region type. '''
        dly = DataLayout(origin=self.dly.origin,
                         frmap=self.dly.frmap,
                         type=NodeRegion.PROC)
        with self.assertRaisesRegexp(ValueError, 'DataLayout: .*type.*'):
            _ = self.dly.merge('|', dly)
        with self.assertRaisesRegexp(ValueError, 'DataLayout: .*type.*'):
            _ = self.dly.merge('+', dly)

    def test_merge_invalid_merge_symbol(self):
        ''' Merge invalid merge symbol. '''
        with self.assertRaisesRegexp(ValueError, 'DataLayout: .*symbol.*'):
            _ = self.dly.merge('*', self.dly)
        with self.assertRaisesRegexp(ValueError, 'DataLayout: .*symbol.*'):
            _ = self.dly.merge('^', self.dly)

    def test_merge_unmatch(self):
        ''' Merge unmatch. '''
        for fr in [
                FmapRange((0, ) * 4, (4, 4, 10, 16)),
                FmapRange((0, ) * 4, (4, 4, 16, 32)),
                FmapRange((0, ) * 4, (3, 4, 16, 16))
        ]:
            frm = FmapRangeMap()
            frm.add(fr, (PhyDim2(1, 1), ))
            dly = DataLayout(origin=PhyDim2(-1, -1),
                             frmap=frm,
                             type=NodeRegion.DATA)

            with self.assertRaisesRegexp(ValueError, 'DataLayout: .*match.*'):
                _ = self.dly.merge('|', dly)
            with self.assertRaisesRegexp(ValueError, 'DataLayout: .*match.*'):
                _ = self.dly.merge('+', dly)

        frm = FmapRangeMap()
        frm.add(FmapRange((0, ) * 4, (4, 2, 16, 16)), (PhyDim2(1, 1), ))
        dly = DataLayout(origin=PhyDim2(-1, -1),
                         frmap=frm,
                         type=NodeRegion.DATA)

        with self.assertRaisesRegexp(ValueError, 'DataLayout: .*match.*'):
            _ = self.dly.merge('+', dly)