Esempio n. 1
0
    def test_get_distributed_slice_simple(self):
        ompi = OcgDist()
        dim = ompi.create_dimension('five', 5, dist=True, src_idx='auto')
        ompi.update_dimension_bounds(min_elements=1)

        with vm.scoped_by_emptyable('simple slice test', dim):
            if not vm.is_null:
                sub = dim.get_distributed_slice(slice(2, 4))
            else:
                sub = None

        if sub is not None and not sub.is_empty:
            self.assertEqual(sub.bounds_global, (0, 2))
        else:
            if dim.is_empty:
                self.assertIsNone(sub)
            else:
                self.assertEqual(sub.bounds_global, (0, 0))
                self.assertEqual(sub.bounds_local, (0, 0))

        # Test global bounds are updated.
        ompi = OcgDist()
        dim = ompi.create_dimension('tester', 768, dist=False)
        ompi.update_dimension_bounds()

        sub = dim.get_distributed_slice(slice(73, 157))
        self.assertEqual(sub.size, 84)
        self.assertEqual(sub.bounds_global, (0, 84))
        self.assertEqual(sub.bounds_local, (0, 84))
Esempio n. 2
0
    def test_create_index_variable_global(self):
        raise SkipTest('not implemented')

        dsrc_size = 5
        ddst_size = 7

        dsrc = Dimension('dsrc', dsrc_size, dist=True)
        src_dist = OcgDist()
        src_dist.add_dimension(dsrc)
        src_dist.update_dimension_bounds()

        ddst = Dimension('ddst', ddst_size, dist=True)
        dst_dist = OcgDist()
        dst_dist.add_dimension(ddst)
        dst_dist.update_dimension_bounds()

        if vm.rank == 0:
            np.random.seed(1)
            dst = np.random.rand(ddst_size)
            src = np.random.choice(dst, size=dsrc_size, replace=False)

            src = Variable(name='src', value=src, dimensions=dsrc.name)
            # TODO: move create_ugid_global to create_global_index on a standard variable object
            dst = GeometryVariable(name='dst', value=dst, dimensions=ddst.name)
        else:
            src, dst = [None] * 2

        src = variable_scatter(src, src_dist)
        dst = variable_scatter(dst, dst_dist)

        actual = create_index_variable_global('index_array', src, dst)

        self.assertNumpyAll(dst.get_value()[actual.get_value()],
                            src.get_value())
Esempio n. 3
0
    def test(self):
        ompi = OcgDist()
        src_idx = np.array([2, 3, 4, 5, 6])
        dim = ompi.create_dimension('foo', size=5, group='subroot', dist=True, src_idx=src_idx)
        self.assertEqual(dim, ompi.get_dimension(dim.name, group='subroot'))
        self.assertEqual(dim.bounds_local, (0, len(dim)))
        self.assertFalse(dim.is_empty)
        ompi.update_dimension_bounds()
        with self.assertRaises(ValueError):
            ompi.update_dimension_bounds()

        if ompi.size == 2:
            if MPI_RANK == 0:
                self.assertEqual(dim.bounds_local, (0, 3))
                self.assertEqual(dim._src_idx.tolist(), [2, 3, 4])
            elif MPI_RANK == 1:
                self.assertEqual(dim.bounds_local, (3, 5))
                self.assertEqual(dim._src_idx.tolist(), [5, 6])
        elif ompi.size == 8:
            if MPI_RANK <= 1:
                self.assertTrue(len(dim) >= 2)
            else:
                self.assertTrue(dim.is_empty)

        # Test with multiple dimensions.
        d1 = Dimension('d1', size=5, dist=True, src_idx=np.arange(5, dtype=np.int32))
        d2 = Dimension('d2', size=10, dist=False)
        d3 = Dimension('d3', size=3, dist=True)
        dimensions = [d1, d2, d3]
        ompi = OcgDist()
        for dim in dimensions:
            ompi.add_dimension(dim)
        ompi.update_dimension_bounds()
        bounds_local = ompi.get_bounds_local()
        if ompi.size <= 2:
            desired = {(1, 0): ((0, 5), (0, 10), (0, 3)),
                       (2, 0): ((0, 3), (0, 10), (0, 3)),
                       (2, 1): ((3, 5), (0, 10), (0, 3))}
            self.assertAsSetEqual(bounds_local, desired[(ompi.size, MPI_RANK)])
        else:
            if MPI_RANK <= 1:
                self.assertTrue(dimensions[0]._src_idx.shape[0] <= 3)
            for dim in dimensions:
                if MPI_RANK >= 2:
                    if dim.name == 'd1':
                        self.assertTrue(dim.is_empty)
                    else:
                        self.assertFalse(dim.is_empty)
                else:
                    self.assertFalse(dim.is_empty)

        # Test adding an existing dimension.
        ompi = OcgDist()
        ompi.create_dimension('one')
        with self.assertRaises(ValueError):
            ompi.create_dimension('one')
Esempio n. 4
0
    def test_get_distributed_slice(self):
        self.add_barrier = False
        for d in [True, False]:
            dist = OcgDist()
            dim = dist.create_dimension('five', 5, dist=d, src_idx='auto')
            dist.update_dimension_bounds()
            if not dim.is_empty:
                self.assertEqual(dim.bounds_global, (0, 5))

            if dim.dist:
                if MPI_RANK > 1:
                    self.assertTrue(dim.is_empty)
                else:
                    self.assertFalse(dim.is_empty)
            with vm.scoped_by_emptyable('dim slice', dim):
                if not vm.is_null:
                    sub = dim.get_distributed_slice(slice(1, 3))
                else:
                    sub = None

            if dim.dist:
                if not dim.is_empty:
                    self.assertIsNotNone(dim._src_idx)
                else:
                    self.assertIsNone(sub)

                if MPI_SIZE == 2:
                    desired_emptiness = {0: False, 1: True}[MPI_RANK]
                    desired_bounds_local = {0: (0, 2), 1: (0, 0)}[MPI_RANK]
                    self.assertEqual(sub.is_empty, desired_emptiness)
                    self.assertEqual(sub.bounds_local, desired_bounds_local)
                if MPI_SIZE >= 5 and 0 < MPI_RANK > 2:
                    self.assertTrue(sub is None or sub.is_empty)
            else:
                self.assertEqual(len(dim), 5)
                self.assertEqual(dim.bounds_global, (0, 5))
                self.assertEqual(dim.bounds_local, (0, 5))

        dist = OcgDist()
        dim = dist.create_dimension('five', 5, dist=True, src_idx='auto')
        dist.update_dimension_bounds()
        with vm.scoped_by_emptyable('five slice', dim):
            if not vm.is_null:
                sub2 = dim.get_distributed_slice(slice(2, 4))
            else:
                sub2 = None
        if MPI_SIZE == 3 and MPI_RANK == 2:
            self.assertIsNone(sub2)
Esempio n. 5
0
    def test_init(self):
        ompi = OcgDist(size=2)
        self.assertEqual(len(ompi.mapping), 2)

        dim_x = Dimension('x', 5, dist=False)
        dim_y = Dimension('y', 11, dist=True)
        var_tas = Variable('tas', value=np.arange(0, 5 * 11).reshape(5, 11), dimensions=(dim_x, dim_y))
        thing = Variable('thing', value=np.arange(11) * 10, dimensions=(dim_y,))

        vc = VariableCollection(variables=[var_tas, thing])
        child = VariableCollection(name='younger')
        vc.add_child(child)
        childer = VariableCollection(name='youngest')
        child.add_child(childer)
        dim_six = Dimension('six', 6)
        hidden = Variable('hidden', value=[6, 7, 8, 9, 0, 10], dimensions=dim_six)
        childer.add_variable(hidden)

        ompi.add_dimensions([dim_x, dim_y])
        ompi.add_dimension(dim_six, group=hidden.group)
        ompi.add_variables([var_tas, thing])
        ompi.add_variable(hidden)

        var = ompi.get_variable(hidden)
        self.assertIsInstance(var, dict)
Esempio n. 6
0
    def test_create_or_get_group(self):
        ocmpi = OcgDist()
        _ = ocmpi._create_or_get_group_(['moon', 'base'])
        _ = ocmpi._create_or_get_group_(None)
        _ = ocmpi._create_or_get_group_('flower')
        ocmpi.create_dimension('foo', group=['moon', 'base'])
        ocmpi.create_dimension('end_of_days')
        ocmpi.create_dimension('start_of_days')

        actual = ocmpi.get_dimension('foo', ['moon', 'base'])
        desired = Dimension('foo')
        self.assertEqual(actual, desired)

        desired = {0: {None: {'variables': {},
                              'dimensions': {'end_of_days': Dimension(name='end_of_days', size=None, size_current=None),
                                             'start_of_days': Dimension(name='start_of_days', size=None,
                                                                        size_current=None)},
                              'groups': {'flower': {'variables': {}, 'dimensions': {}, 'groups': {}},
                                         'moon': {'variables': {}, 'dimensions': {},
                                                  'groups': {'base': {'variables': {},
                                                                      'dimensions': {
                                                                          'foo': Dimension(
                                                                              name='foo',
                                                                              size=None,
                                                                              size_current=None)},
                                                                      'groups': {}}}}}}}}

        self.assertDictEqual(ocmpi.mapping, desired)
Esempio n. 7
0
    def test_create_unique_global_array(self):
        dist = OcgDist()
        dist.create_dimension('dim', 9, dist=True)
        dist.update_dimension_bounds()

        values = [[4, 2, 1, 2, 1, 4, 1, 4, 2],
                  [44, 25, 16, 27, 18, 49, 10, 41, 22],
                  [44, 25, 16, 27, 44, 49, 10, 41, 44],
                  [1, 1, 1, 1, 1, 1, 1, 1, 1]]

        for v in values:
            if vm.rank == 0:
                index = Variable(name='cindex', value=v, dimensions='dim')
                desired = np.unique(index.get_value())
                desired_length = len(desired)
            else:
                index = None
            index = variable_scatter(index, dist)

            with vm.scoped_by_emptyable('not empty', index):
                if not vm.is_null:
                    uvar = create_unique_global_array(index.get_value())
                    uvar_gathered = vm.gather(uvar)

                    if vm.rank == 0:
                        uvar_gathered = hgather(uvar_gathered)
                        self.assertEqual(len(uvar_gathered), desired_length)
                        self.assertEqual(set(uvar_gathered), set(desired))
Esempio n. 8
0
    def test_variable_gather(self):
        dist = OcgDist()
        three = dist.create_dimension('three', 3, src_idx=np.arange(3) * 10)
        four = dist.create_dimension('four', 4, src_idx=np.arange(4, dtype=np.int32), dist=True)
        dist.create_variable('four', dimensions=[three, four])
        dist.update_dimension_bounds()

        if MPI_RANK == 0:
            np.random.seed(1)
            mask_value = np.random.random(12).reshape(3, 4)
            mask = Variable('mask', value=mask_value, dimensions=['three', 'four'])
        else:
            mask = None

        mask = variable_scatter(mask, dist)
        with vm.scoped('mask gather', dist.get_empty_ranks(inverse=True)):
            if not vm.is_null:
                mask_gather = variable_gather(mask)
            else:
                mask_gather = None

        if MPI_RANK == 0:
            self.assertNumpyAll(mask_gather.get_value(), mask_value)
            self.assertNumpyAll(mask_gather.dimensions[0]._src_idx, np.arange(3) * 10)
            self.assertNumpyAll(mask_gather.dimensions[1]._src_idx, np.arange(4, dtype=DataType.DIMENSION_SRC_INDEX))
            for dim in mask_gather.dimensions:
                self.assertFalse(dim.dist)
        else:
            self.assertIsNone(mask_gather)
Esempio n. 9
0
    def test_write_variable_collection_object_arrays(self):
        """Test writing variable length arrays in parallel."""

        with vm.scoped('write', [0]):
            if not vm.is_null:
                path_actual = self.get_temporary_file_path('in.nc')
                path_desired = self.get_temporary_file_path('out.nc')

                value = [[1, 3, 5], [7, 9], [11]]
                v = Variable(name='objects',
                             value=value,
                             fill_value=4,
                             dtype=ObjectType(int),
                             dimensions='values')
                v.write(path_desired)
            else:
                v, path_actual, path_desired = [None] * 3
        path_actual = MPI_COMM.bcast(path_actual)
        path_desired = MPI_COMM.bcast(path_desired)

        dest_mpi = OcgDist()
        dest_mpi.create_dimension('values', 3, dist=True)
        dest_mpi.update_dimension_bounds()

        scattered = variable_scatter(v, dest_mpi)
        outvc = VariableCollection(variables=[scattered])

        with vm.scoped_by_emptyable('write', outvc):
            if not vm.is_null:
                outvc.write(path_actual)

        if MPI_RANK == 0:
            self.assertNcEqual(path_actual, path_desired)
Esempio n. 10
0
    def test_variable_scatter(self):
        var_value = np.arange(5, dtype=float) + 50
        var_mask = np.array([True, True, False, True, False])

        dest_dist = OcgDist()
        five = dest_dist.create_dimension('five', 5, src_idx=np.arange(5), dist=True)
        bounds = dest_dist.create_dimension('bounds', 2)
        dest_dist.update_dimension_bounds()

        if MPI_RANK == 0:
            local_dim = Dimension('local', 5, src_idx=np.arange(5))
            dim_src_idx = local_dim._src_idx.copy()

            var = Variable('the_five', value=var_value, mask=var_mask, dimensions=five.name)
            var.set_extrapolated_bounds('the_five_bounds', 'bounds')
            var_bounds_value = var.bounds.get_value()
        else:
            var, var_bounds_value, dim_src_idx = [None] * 3

        svar = variable_scatter(var, dest_dist)

        var_bounds_value = MPI_COMM.bcast(var_bounds_value)
        dim_src_idx = MPI_COMM.bcast(dim_src_idx)

        if MPI_RANK > 1:
            self.assertIsNone(svar.get_value())
            self.assertTrue(svar.is_empty)
        else:
            dest_dim = dest_dist.get_dimension('five')
            self.assertNumpyAll(var_value[slice(*dest_dim.bounds_local)], svar.get_value())
            self.assertNumpyAll(var_mask[slice(*dest_dim.bounds_local)], svar.get_mask())
            self.assertNumpyAll(var_bounds_value[slice(*dest_dim.bounds_local)], svar.bounds.get_value())
            self.assertNumpyAll(dim_src_idx[slice(*dest_dim.bounds_local)], svar.dimensions[0]._src_idx)
            self.assertNumpyAll(dim_src_idx[slice(*dest_dim.bounds_local)], svar.bounds.dimensions[0]._src_idx)
Esempio n. 11
0
    def test_variable_gather_bounded_source_index(self):
        self.add_barrier = False
        dist = OcgDist()
        dist.create_dimension('long', 7, dist=True, src_idx='auto')
        dist.create_dimension('short', 3, src_idx='auto')
        dist.update_dimension_bounds()

        if vm.rank == 0:
            var = Variable(name='test',
                           value=np.arange(21).reshape(7, 3),
                           dimensions=['long', 'short'])
        else:
            var = None
        svar = variable_scatter(var, dist)

        with vm.scoped_by_emptyable('gather test', svar):
            if vm.is_null:
                return
            gvar = variable_gather(svar)

            if vm.rank == 0:
                actual = gvar.dimensions[0]._src_idx
                desired = (0, 7)
                self.assertEqual(actual, desired)
            else:
                self.assertIsNone(gvar)
Esempio n. 12
0
    def test_variable_scatter_ndimensions(self):

        r = Dimension('realization', 3)
        t = Dimension('time', 365)
        l = Dimension('level', 10)
        y = Dimension('y', 90, dist=True)
        x = Dimension('x', 360, dist=True)

        dimensions = [r, t, l, y, x]

        dest_mpi = OcgDist()
        for d in dimensions:
            dest_mpi.add_dimension(d)
        dest_mpi.update_dimension_bounds()

        if MPI_RANK == 0:
            local_dimensions = deepcopy(dimensions)
            for l in local_dimensions:
                l.dist = False
            var = Variable('tas', dimensions=local_dimensions)
        else:
            var = None

        svar = variable_scatter(var, dest_mpi)

        self.assertTrue(svar.dist)
        self.assertIsNotNone(svar)

        if MPI_SIZE == 2:
            self.assertEqual(svar.shape, (3, 365, 10, 90, 180))
Esempio n. 13
0
    def get_wrap_field(crs=None, unwrapped=True):
        ompi = OcgDist()
        ompi.create_dimension('x', 5, dist=False)
        ompi.create_dimension('y', 7, dist=True)
        ompi.create_dimension('time', size_current=4, dist=False)
        ompi.update_dimension_bounds()

        if MPI_RANK == 0:
            row = Variable(value=[-60, -40, -20, 0, 20, 40, 60], name='y', dimensions='y')
            if unwrapped:
                col_value = [1, 90, 180, 225, 270]
            else:
                col_value = [-170, -85, 0, 85, 170]
            col = Variable(value=col_value, name='x', dimensions='x')
            grid = Grid(col, row)
            value = np.zeros((4, 7, 5))
            for col_idx in range(value.shape[-1]):
                value[:, :, col_idx] = col_idx
            time = TemporalVariable(name='time', value=[1, 2, 3, 4], dimensions='time')
            var = Variable(name='foo', value=value, dimensions=['time', 'y', 'x'])
            field = Field(grid=grid, is_data=var, crs=crs, time=time)
        else:
            field = None
        field = variable_collection_scatter(field, ompi)

        return field
Esempio n. 14
0
    def test_system_parallel_write_ndvariable(self):
        """Test a parallel CSV write with a n-dimensional variable."""

        ompi = OcgDist()
        ompi.create_dimension('time', 3)
        ompi.create_dimension('extra', 2)
        ompi.create_dimension('x', 4)
        ompi.create_dimension('y', 7, dist=True)
        ompi.update_dimension_bounds()

        if MPI_RANK == 0:
            path = self.get_temporary_file_path('foo.csv')

            t = TemporalVariable(name='time',
                                 value=[1, 2, 3],
                                 dtype=float,
                                 dimensions='time')
            t.set_extrapolated_bounds('the_time_bounds', 'bounds')

            extra = Variable(name='extra', value=[7, 8], dimensions='extra')

            x = Variable(name='x',
                         value=[9, 10, 11, 12],
                         dimensions='x',
                         dtype=float)
            x.set_extrapolated_bounds('x_bounds', 'bounds')

            # This will have the distributed dimension.
            y = Variable(name='y',
                         value=[13, 14, 15, 16, 17, 18, 19],
                         dimensions='y',
                         dtype=float)
            y.set_extrapolated_bounds('y_bounds', 'bounds')

            data = Variable(name='data',
                            value=np.random.rand(3, 2, 7, 4),
                            dimensions=['time', 'extra', 'y', 'x'])

            vc = VariableCollection(variables=[t, extra, x, y, data])
        else:
            path, vc = [None] * 2

        path = MPI_COMM.bcast(path)
        vc = variable_collection_scatter(vc, ompi)

        with vm.scoped_by_emptyable('write', vc):
            if not vm.is_null:
                vc.write(path,
                         iter_kwargs={
                             'variable': 'data',
                             'followers': ['time', 'extra', 'y', 'x']
                         },
                         driver=DriverCSV)

        if MPI_RANK == 0:
            desired = 169
            with open(path, 'r') as f:
                lines = f.readlines()
            self.assertEqual(len(lines), desired)
Esempio n. 15
0
    def test_redistribute_by_src_idx(self):
        if vm.size != 4:
            raise SkipTest('vm.size != 4')

        dist = OcgDist()
        dim1 = dist.create_dimension('dim1', 5 * vm.size, dist=True)
        dim2 = dist.create_dimension('dim2', 2, dist=False)
        dist.update_dimension_bounds()

        rank_value = np.arange(5) + (10 * (vm.rank + 1))
        var1 = Variable(name='dvar1', value=rank_value, dimensions=dim1)
        var2 = Variable(name='dvar2', dimensions=[dim1, dim2])
        var1.parent.add_variable(var2)
        path = self.get_temporary_file_path('out.nc')
        var1.parent.write(path)

        desired_idx = np.array([1, 7, 9, 10, 14])
        vdesired_value = variable_gather(var1)
        if vm.rank == 0:
            desired_value = vdesired_value.get_value()[desired_idx]

        desired_idx_ranks = {0: slice(1, 2),
                             1: [2, 4],
                             2: [0, 4]}

        rd = RequestDataset(path)
        rd.metadata['dimensions'][dim1.name]['dist'] = True
        field = rd.create_field()

        indvar = field[var1.name]
        field[var2.name].load()

        try:
            rank_slice = desired_idx_ranks[vm.rank]
        except KeyError:
            sub = Variable(is_empty=True)
        else:
            sub = indvar[rank_slice]

        self.barrier_print(sub.is_empty)

        redistribute_by_src_idx(indvar, dim1.name, sub.dimensions_dict.get(dim1.name))

        with vm.scoped_by_emptyable('gather for test', indvar):
            if vm.is_null:
                self.assertIn(vm.rank_global, [2, 3])
            else:
                self.assertIn(vm.rank_global, [0, 1])
                for v in [indvar, indvar.parent[var2.name]]:
                    self.assertIsNone(v._value)
                    self.assertIsNone(v._mask)
                    self.assertIsNone(v._is_empty)
                    self.assertFalse(v._has_initialized_value)
                self.rank_print(indvar)
                actual_value = variable_gather(indvar)
                if vm.rank == 0:
                    actual_value = actual_value.get_value()
                    self.assertNumpyAll(actual_value, desired_value)
Esempio n. 16
0
    def test_update_dimension_bounds(self):
        ompi = OcgDist()
        dim1 = ompi.create_dimension('five', 5, dist=True)
        ompi.update_dimension_bounds()

        if dim1.is_empty:
            desired = (0, 0)
        else:
            desired = (0, 5)
        self.assertEqual(dim1.bounds_global, desired)
        if MPI_SIZE > 1:
            if MPI_SIZE == 2:
                if MPI_RANK == 0:
                    self.assertEqual(dim1.bounds_local, (0, 3))
                else:
                    self.assertEqual(dim1.bounds_local, (3, 5))

        # Test updating on single processor.
        if MPI_SIZE == 1:
            ompi = OcgDist(size=2)
            ompi.create_dimension('five', 5, dist=True)
            ompi.update_dimension_bounds()
            dim = ompi.get_dimension('five')
            self.assertEqual(dim.bounds_global, (0, 5))
            for rank in range(2):
                actual = ompi.get_dimension('five', rank=rank)
                self.assertEqual(actual.bounds_global, (0, 5))
                if rank == 0:
                    self.assertEqual(actual.bounds_local, (0, 3))
                else:
                    self.assertEqual(actual.bounds_local, (3, 5))

            # Test two dimensions.
            ompi = OcgDist(size=2)
            ompi.create_dimension('lat', 64, dist=True)
            ompi.create_dimension('lon', 128, dist=True)
            ompi.update_dimension_bounds()
            for rank in range(2):
                lat = ompi.get_dimension('lat', rank=rank)
                self.assertEqual(lat.bounds_local, (0, 64))
                lon = ompi.get_dimension('lon', rank=rank)
                if rank == 0:
                    self.assertEqual(lon.bounds_local, (0, 64))
                else:
                    self.assertEqual(lon.bounds_local, (64, 128))
Esempio n. 17
0
    def test_get_mask_from_intersects(self):
        poly = wkt.loads(
            'POLYGON((-98.26574367088608142 40.19952531645570559,-98.71764240506330168 39.54825949367089066,-99.26257911392406186 39.16281645569620906,-99.43536392405064817 38.64446202531645724,-98.78409810126584034 38.33876582278481493,-98.23916139240508016 37.71408227848101546,-97.77397151898735217 37.67420886075949937,-97.62776898734178133 38.15268987341772799,-98.39865506329114453 38.52484177215190186,-98.23916139240508016 39.33560126582278826,-97.73409810126582897 39.58813291139241386,-97.52143987341773368 40.27927215189873777,-97.52143987341773368 40.27927215189873777,-98.26574367088608142 40.19952531645570559))'
        )
        desired_mask = np.array([[True, True, False, True],
                                 [True, False, True, True],
                                 [True, True, False, True]])

        dist = OcgDist()
        xdim = dist.create_dimension('x', 4, dist=True)
        ydim = dist.create_dimension('y', 3)
        dist.create_dimension('bounds', 2)
        dist.update_dimension_bounds()

        if MPI_RANK == 0:
            x = self.get_variable_x()
            y = self.get_variable_y()
            grid = Grid(x=x, y=y, abstraction='point', crs=WGS84())
            pa = get_geometry_variable(grid)
        else:
            pa = None
        pa = variable_scatter(pa, dist)

        vm.create_subcomm_by_emptyable('test_get_mask_from_intersects',
                                       pa,
                                       is_current=True)
        if vm.is_null:
            self.assertTrue(pa.is_empty)
            return

        usi = [False]
        if env.USE_SPATIAL_INDEX:
            usi.append(True)

        keywords = dict(use_spatial_index=usi)
        for k in self.iter_product_keywords(keywords):
            ret = pa.get_mask_from_intersects(
                poly, use_spatial_index=k.use_spatial_index)
            desired_mask_local = desired_mask[slice(*ydim.bounds_local),
                                              slice(*xdim.bounds_local)]
            if MPI_RANK > 1:
                self.assertIsNone(ret)
            else:
                self.assertNumpyAll(desired_mask_local, ret)

            # This does not test a parallel operation.
            if MPI_RANK == 0:
                # Test pre-masked values in geometry are okay for intersects operation.
                value = [Point(1, 1), Point(2, 2), Point(3, 3)]
                value = np.ma.array(value,
                                    mask=[False, True, False],
                                    dtype=object)
                pa2 = GeometryVariable(value=value, dimensions='ngeom')
                b = box(0, 0, 5, 5)
                res = pa2.get_mask_from_intersects(
                    b, use_spatial_index=k.use_spatial_index)
                self.assertNumpyAll(res, value.mask)
Esempio n. 18
0
 def get_OcgDist_01(self):
     s = Dimension('first_dist', size=5, dist=True, src_idx='auto')
     ompi = OcgDist()
     ompi.add_dimension(s)
     ompi.create_dimension('not_dist', size=8, dist=False)
     ompi.create_dimension('another_dist', size=6, dist=True)
     ompi.create_dimension('another_not_dist', size=100, dist=False)
     ompi.create_dimension('coordinate_reference_system', size=0)
     self.assertIsNotNone(s._src_idx)
     return ompi
Esempio n. 19
0
def create_slices_for_dimension(size, splits):
    ompi = OcgDist(size=splits)
    dimname = 'foo'
    ompi.create_dimension(dimname, size, dist=True)
    ompi.update_dimension_bounds()
    slices = []
    for rank in range(splits):
        dimension = ompi.get_dimension(dimname, rank=rank)
        slices.append(dimension.bounds_local)
    return slices
Esempio n. 20
0
    def test_system_grid_chunking(self):
        if vm.size != 4:
            raise SkipTest('vm.size != 4')

        from ocgis.spatial.grid_chunker import GridChunker
        path = self.path_esmf_unstruct
        rd_dst = RequestDataset(uri=path,
                                driver=DriverESMFUnstruct,
                                crs=Spherical(),
                                grid_abstraction='point',
                                grid_is_isomorphic=True)
        rd_src = deepcopy(rd_dst)
        resolution = 0.28125
        chunk_wd = os.path.join(self.current_dir_output, 'chunks')
        if vm.rank == 0:
            os.mkdir(chunk_wd)
        vm.barrier()
        paths = {'wd': chunk_wd}
        gc = GridChunker(rd_src,
                         rd_dst,
                         nchunks_dst=[8],
                         src_grid_resolution=resolution,
                         dst_grid_resolution=resolution,
                         optimized_bbox_subset=True,
                         paths=paths,
                         genweights=True)
        gc.write_chunks()

        dist = OcgDist()
        local_ctr = Dimension(name='ctr', size=8, dist=True)
        dist.add_dimension(local_ctr)
        dist.update_dimension_bounds()
        for ctr in range(local_ctr.bounds_local[0], local_ctr.bounds_local[1]):
            ctr += 1
            s = os.path.join(chunk_wd, 'split_src_{}.nc'.format(ctr))
            d = os.path.join(chunk_wd, 'split_dst_{}.nc'.format(ctr))
            sf = Field.read(s, driver=DriverESMFUnstruct)
            df = Field.read(d, driver=DriverESMFUnstruct)
            self.assertGreater(sf.grid.shape[0], df.grid.shape[0])

            wgt = os.path.join(chunk_wd, 'esmf_weights_{}.nc'.format(ctr))
            f = Field.read(wgt)
            S = f['S'].v()
            self.assertAlmostEqual(S.min(), 1.0)
            self.assertAlmostEqual(S.max(), 1.0)

        with vm.scoped('merge weights', [0]):
            if not vm.is_null:
                merged_weights = self.get_temporary_file_path(
                    'merged_weights.nc')
                gc.create_merged_weight_file(merged_weights, strict=False)
                f = Field.read(merged_weights)
                S = f['S'].v()
                self.assertAlmostEqual(S.min(), 1.0)
                self.assertAlmostEqual(S.max(), 1.0)
Esempio n. 21
0
    def test_arange_from_dimension(self):
        dist = OcgDist()
        dim = dist.create_dimension('dim', size=7, dist=True)
        dist.update_dimension_bounds()

        actual = arange_from_dimension(dim, start=2, dtype=np.int64)
        actual = vm.gather(actual)
        if vm.rank == 0:
            actual = hgather(actual)
            desired = np.arange(2, 9, dtype=np.int64)
            self.assertNumpyAll(actual, desired)
Esempio n. 22
0
    def create_dist(self, metadata=None):
        """
        Create a distribution from global metadata. In general, this should not be overloaded by subclasses.

        :param dict metadata: Global metadata to use for creating a distribution.

        :rtype: :class:`ocgis.OcgDist`
        """
        ompi = OcgDist(size=vm.size, ranks=vm.ranks)

        # Convert metadata into a grouping consistent with the MPI dimensions.
        if metadata is None:
            metadata = self.metadata_source
        metadata = {None: metadata}
        for group_index in iter_all_group_keys(metadata):
            group_meta = get_group(metadata, group_index)

            # Add the dimensions to the distribution object.
            dimensions = self.create_dimensions(group_meta)

            # Only build a distribution if the group has more than one dimension.
            if len(dimensions) == 0:
                _ = ompi.get_group(group=group_index)
            else:
                for dimension_name, dimension_meta in list(
                        group_meta['dimensions'].items()):
                    target_dimension = dimensions[dimension_name]
                    target_dimension.dist = group_meta['dimensions'][
                        dimension_name].get('dist', False)
                    ompi.add_dimension(target_dimension, group=group_index)
                try:
                    dimension_map = self.rd.dimension_map.get_group(
                        group_index)
                except DimensionMapError:
                    # Likely a user-provided dimension map.
                    continue

                # dimension_map = get_group(self.rd.dimension_map, group_index, has_root=False)
                distributed_dimension_name = self.get_distributed_dimension_name(
                    dimension_map,
                    group_meta['dimensions'],
                    decomp_type=self.rd.decomp_type)
                # Allow no distributed dimensions to be returned.
                if distributed_dimension_name is not None:
                    for target_rank in range(ompi.size):
                        distributed_dimension = ompi.get_dimension(
                            distributed_dimension_name,
                            group=group_index,
                            rank=target_rank)
                        distributed_dimension.dist = True

        ompi.update_dimension_bounds()
        return ompi
Esempio n. 23
0
    def test_get_wrapped_state(self):
        if sys.version_info.major == 3 and sys.version_info.minor == 5:
            raise SkipTest('undefined behavior with Python 3.5')

        ompi = OcgDist()
        ompi.create_dimension('x', 5, dist=True)
        ompi.create_dimension('y', 1)
        ompi.update_dimension_bounds()

        values = [{
            'value': [-179, -90, 0, 90, 180],
            'desired': WrappedState.WRAPPED
        }, {
            'value': [0, 90, 180, 270, 360],
            'desired': WrappedState.UNWRAPPED
        }, {
            'value': [1, 2, 3, 4, 5],
            'desired': WrappedState.UNKNOWN
        }]
        kwds = {'values': values, 'crs': [Spherical(), None]}

        for k in self.iter_product_keywords(kwds):
            ompi = deepcopy(ompi)
            if MPI_RANK == 0:
                vx = Variable(name='x',
                              value=k.values['value'],
                              dimensions='x')
                vy = Variable(name='y', value=[0], dimensions='y')
            else:
                vx, vy = [None] * 2
            vx = variable_scatter(vx, ompi)
            vy = variable_scatter(vy, ompi)

            grid = Grid(vx, vy)
            field = Field(grid=grid, crs=k.crs)

            with vm.scoped_by_emptyable('wrap', field):
                if not vm.is_null:
                    wrapped_state = field.wrapped_state
                else:
                    wrapped_state = None

            if not field.is_empty:
                if k.crs is None:
                    self.assertIsNone(wrapped_state)
                else:
                    self.assertIsNotNone(wrapped_state)

            if k.crs is None or field.is_empty:
                self.assertIsNone(wrapped_state)
            else:
                self.assertEqual(wrapped_state, k.values['desired'])
Esempio n. 24
0
    def test_reduce_global(self):
        pt = self.fixture(cindex=self.fixture_cindex(1), start_index=1)
        self.assertEqual(pt.start_index, 1)

        dist = OcgDist()
        for d in pt.parent.dimensions.values():
            d = d.copy()
            if d.name == self.fixture_element_dimension.name:
                d.dist = True
            dist.add_dimension(d)
        dist.update_dimension_bounds()

        new_parent = variable_collection_scatter(pt.parent, dist)

        vm.create_subcomm_by_emptyable('coordinate reduction',
                                       new_parent,
                                       is_current=True)
        if vm.is_null:
            return

        pt.parent = new_parent
        sub = pt.get_distributed_slice(slice(2, 5))

        vm.create_subcomm_by_emptyable('distributed slice',
                                       sub,
                                       is_current=True)
        if vm.is_null:
            return

        actual = sub.reduce_global()

        actual_cindex = actual.cindex.extract()
        actual_cindex = variable_gather(actual_cindex)
        if vm.rank == 0:
            actual_cindex = actual_cindex.get_value().flatten().tolist()
            self.assertEqual(actual_cindex, [1, 2, 3])

        gathered = [
            variable_gather(c.extract()) for c in actual.coordinate_variables
        ]
        if vm.rank == 0:
            actual_coords = []
            for c in gathered:
                actual_coords.append(c.get_value().tolist())
            desired = [[2.0, 3.0, 4.0], [8.0, 9.0, 10.0], [14.0, 15.0, 16.0]]
            self.assertEqual(actual_coords, desired)

        path = self.get_temporary_file_path('foo.nc')
        actual.parent.write(path)

        actual = Field.read(path)
        self.assertEqual(actual['cindex'].attrs['start_index'], 1)
Esempio n. 25
0
    def test_update_dimension_bounds_with_source_indexing(self):
        dist_size = 5
        dist = OcgDist(size=dist_size)
        dist.create_dimension('dim', 11, dist=True, src_idx='auto')
        dist.update_dimension_bounds()

        actual = []
        for rank in range(dist_size):
            rank_dim = dist.get_dimension('dim', rank=rank)
            actual.append(rank_dim._src_idx)

        desired = [(0, 3), (3, 5), (5, 7), (7, 9), (9, 11)]
        self.assertEqual(actual, desired)
Esempio n. 26
0
    def test_reduce_reindex_coordinate_variables(self):
        self.add_barrier = False
        dist = OcgDist()
        dist.create_dimension('dim', 12, dist=True)
        dist.update_dimension_bounds()

        global_cindex_arr = np.array([4, 2, 1, 2, 1, 4, 1, 4, 2, 5, 6, 7])

        if vm.rank == 0:
            var_cindex = Variable('cindex',
                                  value=global_cindex_arr,
                                  dimensions='dim')
        else:
            var_cindex = None
        var_cindex = variable_scatter(var_cindex, dist)

        vm.create_subcomm_by_emptyable('test', var_cindex, is_current=True)
        if vm.is_null:
            return

        raise_if_empty(var_cindex)

        coords = np.array([
            0, 11, 22, 33, 44, 55, 66, 77, 88, 99, 100, 110, 120, 130, 140, 150
        ])
        coords = Variable(name='coords', value=coords, dimensions='coord_dim')

        new_cindex, u_indices = reduce_reindex_coordinate_variables(var_cindex)

        desired = coords[global_cindex_arr].get_value()

        if len(u_indices) > 0:
            new_coords = coords[u_indices].get_value()
        else:
            new_coords = np.array([])
        gathered_new_coords = vm.gather(new_coords)
        gathered_new_cindex = vm.gather(new_cindex)
        if vm.rank == 0:
            gathered_new_coords = hgather(gathered_new_coords)
            gathered_new_cindex = hgather(gathered_new_cindex)

            actual = gathered_new_coords[gathered_new_cindex]

            self.assertAsSetEqual(gathered_new_cindex.tolist(),
                                  [2, 1, 0, 3, 4, 5])
            desired_new_coords = [11, 22, 44, 55, 66, 77]
            self.assertAsSetEqual(gathered_new_coords.tolist(),
                                  desired_new_coords)
            self.assertEqual(len(gathered_new_coords), len(desired_new_coords))

            self.assertNumpyAll(actual, desired)
Esempio n. 27
0
 def test_update_dimension_bounds_single_simple_dimension(self):
     ompi = OcgDist(size=2)
     ompi.create_dimension('d1', 2, dist=True)
     ompi.update_dimension_bounds(min_elements=2)
     d1 = ompi.get_dimension('d1')
     for rank in range(2):
         actual = ompi.get_dimension(d1.name, rank=rank)
         if rank == 0:
             self.assertFalse(actual.is_empty)
             self.assertEqual(actual.bounds_local, (0, 2))
             self.assertEqual(id(d1), id(actual))
         else:
             self.assertTrue(actual.is_empty)
             self.assertEqual(actual.bounds_local, (0, 0))
             self.assertNotEqual(id(d1), id(actual))
Esempio n. 28
0
    def test_system_parallel_write_ndvariable(self):
        """Test a parallel vector GIS write with a n-dimensional variable."""

        ompi = OcgDist()
        ompi.create_dimension('time', 3)
        ompi.create_dimension('extra', 2)
        ompi.create_dimension('x', 4)
        ompi.create_dimension('y', 7, dist=True)
        ompi.update_dimension_bounds()

        if MPI_RANK == 0:
            path = self.get_temporary_file_path('foo.shp')

            t = TemporalVariable(name='time', value=[1, 2, 3], dtype=float, dimensions='time')
            t.set_extrapolated_bounds('the_time_bounds', 'bounds')

            extra = Variable(name='extra', value=[7, 8], dimensions='extra')

            x = Variable(name='x', value=[9, 10, 11, 12], dimensions='x', dtype=float)
            x.set_extrapolated_bounds('x_bounds', 'bounds')

            # This will have the distributed dimension.
            y = Variable(name='y', value=[13, 14, 15, 16, 17, 18, 19], dimensions='y', dtype=float)
            y.set_extrapolated_bounds('y_bounds', 'bounds')

            data = Variable(name='data', value=np.random.rand(3, 2, 7, 4), dimensions=['time', 'extra', 'y', 'x'])

            dimension_map = {'x': {'variable': 'x', 'bounds': 'x_bounds'},
                             'y': {'variable': 'y', 'bounds': 'y_bounds'},
                             'time': {'variable': 'time', 'bounds': 'the_time_bounds'}}

            vc = Field(variables=[t, extra, x, y, data], dimension_map=dimension_map, is_data='data')
            vc.set_abstraction_geom()
        else:
            path, vc = [None] * 2

        path = MPI_COMM.bcast(path)
        vc = variable_collection_scatter(vc, ompi)
        with vm.scoped_by_emptyable('write', vc):
            if not vm.is_null:
                vc.write(path, driver=DriverVector)
        MPI_COMM.Barrier()

        desired = 168
        rd = RequestDataset(path, driver=DriverVector)
        sizes = MPI_COMM.gather(rd.get().geom.shape[0])
        if MPI_RANK == 0:
            self.assertEqual(sum(sizes), desired)
Esempio n. 29
0
    def test_variable_collection_scatter(self):
        dest_mpi = OcgDist()
        five = dest_mpi.create_dimension('five', 5, dist=True)
        ten = dest_mpi.create_dimension('ten', 10)
        dest_mpi.create_variable(name='five', dimensions=five)
        dest_mpi.create_variable(name='all_in', dimensions=ten)
        dest_mpi.create_variable(name='i_could_be_a_coordinate_system')
        dest_mpi.update_dimension_bounds()

        if MPI_RANK == 0:
            var = Variable('holds_five', np.arange(5), dimensions='five')
            var_empty = Variable('i_could_be_a_coordinate_system',
                                 attrs={'reality': 'im_not'})
            var_not_dist = Variable('all_in',
                                    value=np.arange(10) + 10,
                                    dimensions='ten')
            vc = VariableCollection(variables=[var, var_empty, var_not_dist])
        else:
            vc = None

        svc = variable_collection_scatter(vc, dest_mpi)

        self.assertEqual(
            svc['i_could_be_a_coordinate_system'].attrs['reality'], 'im_not')

        if MPI_RANK < 2:
            self.assertFalse(svc['all_in'].is_empty)
            self.assertNumpyAll(svc['all_in'].get_value(), np.arange(10) + 10)
            self.assertFalse(svc.is_empty)
            self.assertFalse(svc['i_could_be_a_coordinate_system'].is_empty)
        else:
            self.assertTrue(svc['all_in'].is_empty)
            self.assertTrue(svc.is_empty)
            self.assertTrue(svc['i_could_be_a_coordinate_system'].is_empty)

        if MPI_RANK == 0:
            self.assertNumpyAll(var.get_value(), vc[var.name].get_value())

        actual = svc['holds_five'].get_value()
        if MPI_SIZE == 2:
            desired = {0: np.arange(3), 1: np.arange(3, 5)}
            self.assertNumpyAll(actual, desired[MPI_RANK])

        actual = svc['holds_five'].is_empty
        if MPI_RANK > 1:
            self.assertTrue(actual)
        else:
            self.assertFalse(actual)
Esempio n. 30
0
    def test_create_ugid_global(self):
        ompi = OcgDist()
        m = ompi.create_dimension('m', 4)
        n = ompi.create_dimension('n', 70, dist=True)
        ompi.update_dimension_bounds()

        gvar = GeometryVariable(name='geom', dimensions=(m, n))
        ugid = gvar.create_ugid_global('gid')

        if not gvar.is_empty:
            self.assertEqual(gvar.dist, ugid.dist)

        gathered = variable_gather(ugid)
        if MPI_RANK == 0:
            actual = gathered.get_value()
            self.assertEqual(actual.size, len(set(actual.flatten().tolist())))