예제 #1
0
    def test_system_get_field_from_file(self):
        """Test returning a distributed field from file."""

        field = self.get_field(nrow=5, ncol=7)
        if MPI_RANK == 0:
            path = self.get_temporary_file_path('data.nc')
        else:
            path = None
        path = MPI_COMM.bcast(path)

        with vm.scoped('write test field', [0]):
            if MPI_RANK == 0:
                field.write(path)

        MPI_COMM.Barrier()

        rd = RequestDataset(path)
        out_field = rd.get()

        if MPI_SIZE == 8:
            self.assertEqual(vm.size, 8)

        if MPI_RANK == 0:
            path2 = self.get_temporary_file_path('out_field.nc')
        else:
            path2 = None
        path2 = MPI_COMM.bcast(path2)

        with vm.scoped_by_emptyable('out_field write', out_field):
            if not vm.is_null:
                out_field.write(path2)

        MPI_COMM.Barrier()

        with vm.scoped('get actual', [0]):
            if MPI_RANK == 0:
                actual = RequestDataset(path2).get()
                actual = actual.data_variables[0].get_value().sum()
            else:
                actual = None

        actual = MPI_COMM.bcast(actual)

        desired = field.data_variables[0].get_value().sum()
        self.assertAlmostEqual(actual, desired)
예제 #2
0
    def test(self):
        gs = self.get_grid_splitter()

        desired_dst_grid_sum = gs.dst_grid.parent['data'].get_value().sum()
        desired_dst_grid_sum = MPI_COMM.gather(desired_dst_grid_sum)
        if MPI_RANK == 0:
            desired_sum = np.sum(desired_dst_grid_sum)

        desired = [{'y': slice(0, 180, None), 'x': slice(0, 240, None)},
                   {'y': slice(0, 180, None), 'x': slice(240, 480, None)},
                   {'y': slice(0, 180, None), 'x': slice(480, 720, None)},
                   {'y': slice(180, 360, None), 'x': slice(0, 240, None)},
                   {'y': slice(180, 360, None), 'x': slice(240, 480, None)},
                   {'y': slice(180, 360, None), 'x': slice(480, 720, None)}]
        actual = list(gs.iter_dst_grid_slices())
        self.assertEqual(actual, desired)

        gs.write_subsets()

        if MPI_RANK == 0:
            rank_sums = []

        for ctr in range(1, gs.nsplits_dst[0] * gs.nsplits_dst[1] + 1):
            src_path = gs.create_full_path_from_template('src_template', index=ctr)
            dst_path = gs.create_full_path_from_template('dst_template', index=ctr)

            src_field = RequestDataset(src_path).get()
            dst_field = RequestDataset(dst_path).get()

            src_envelope_global = box(*src_field.grid.extent_global)
            dst_envelope_global = box(*dst_field.grid.extent_global)

            self.assertTrue(does_contain(src_envelope_global, dst_envelope_global))

            actual = get_variable_names(src_field.data_variables)
            self.assertIn('data', actual)

            actual = get_variable_names(dst_field.data_variables)
            self.assertIn('data', actual)
            actual_data_sum = dst_field['data'].get_value().sum()
            actual_data_sum = MPI_COMM.gather(actual_data_sum)
            if MPI_RANK == 0:
                actual_data_sum = np.sum(actual_data_sum)
                rank_sums.append(actual_data_sum)

        if MPI_RANK == 0:
            self.assertAlmostEqual(desired_sum, np.sum(rank_sums))
            index_path = gs.create_full_path_from_template('index_file')
            self.assertTrue(os.path.exists(index_path))

        MPI_COMM.Barrier()

        index_path = gs.create_full_path_from_template('index_file')
        index_field = RequestDataset(index_path).get()
        self.assertTrue(len(list(index_field.keys())) > 2)
예제 #3
0
    def test_write_parallel(self):
        """Test writing by selective rank."""

        if MPI_SIZE != 3 and MPI_SIZE != 1:
            raise SkipTest('MPI_SIZE != 1 or 3')

        ranks = list(range(MPI_SIZE))

        for base_rank in ranks:
            for driver in [DriverCSV, DriverVector, DriverNetcdf]:
                if MPI_RANK == 0:
                    path = self.get_temporary_file_path('{}-{}.{}'.format(
                        driver.key, base_rank, driver.common_extension))
                else:
                    path = None
                path = MPI_COMM.bcast(path)

                with vm.scoped('field write by rank', [base_rank]):
                    if not vm.is_null:
                        geom = GeometryVariable(
                            value=[Point(1, 2), Point(3, 4)],
                            name='geom',
                            dimensions='geom')
                        data = Variable(name='data',
                                        value=[10, 20],
                                        dimensions='geom')
                        field = Field(geom=geom)
                        field.add_variable(data, is_data=True)
                        self.assertFalse(os.path.isdir(path))
                        field.write(path, driver=driver)
                        self.assertFalse(os.path.isdir(path))

                        rd = RequestDataset(path, driver=driver)
                        in_field = rd.get()
                        self.assertEqual(in_field['data'].dimensions[0].size,
                                         2)
                MPI_COMM.Barrier()
        MPI_COMM.Barrier()
예제 #4
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)
예제 #5
0
    def test_get_intersects_state_boundaries(self):
        path_shp = self.path_state_boundaries
        geoms = []
        with fiona.open(path_shp) as source:
            for record in source:
                geom = shape(record['geometry'])
                geoms.append(geom)

        gvar = GeometryVariable(value=geoms, dimensions='ngeom')
        gvar_sub = gvar.get_unioned()

        if gvar_sub is not None:
            subset = gvar_sub.get_value().flatten()[0]

        else:
            subset = None
        subset = MPI_COMM.bcast(subset)
        resolution = 1.0

        for with_bounds in [False, True]:
            grid = self.get_gridxy_global(resolution=resolution,
                                          with_bounds=with_bounds)

            vm.create_subcomm_by_emptyable('global grid',
                                           grid,
                                           is_current=True)
            if not vm.is_null:
                res = grid.get_intersects(subset, return_slice=True)
                grid_sub, slc = res

                vm.create_subcomm_by_emptyable('grid subset',
                                               grid_sub,
                                               is_current=True)

                if not vm.is_null:
                    mask = Variable('mask_after_subset',
                                    grid_sub.get_mask(),
                                    dimensions=grid_sub.dimensions)
                    mask = variable_gather(mask)

                    if vm.rank == 0:
                        mask_sum = np.invert(mask.get_value()).sum()
                        mask_shape = mask.shape
                    else:
                        mask_sum = None
                        mask_shape = None
                    mask_sum = vm.bcast(mask_sum)
                    mask_shape = vm.bcast(mask_shape)

                    if with_bounds:
                        self.assertEqual(mask_shape, (54, 113))
                        self.assertEqual(
                            slc, (slice(108, 162, None), slice(1, 114, None)))
                        self.assertEqual(mask_sum, 1358)
                    else:
                        if MPI_SIZE == 2:
                            grid_bounds_global = [
                                dim.bounds_global
                                for dim in grid_sub.dimensions
                            ]
                            self.assertEqual(grid_bounds_global, [(0, 52),
                                                                  (0, 105)])
                        self.assertEqual(mask_shape, (52, 105))
                        self.assertEqual(
                            slc, (slice(109, 161, None), slice(8, 113, None)))
                        self.assertEqual(mask_sum, 1087)

                    if vm.rank == 0:
                        path = self.get_temporary_file_path('foo.nc')
                    else:
                        path = None
                    path = vm.bcast(path)
                    field = Field(grid=grid_sub)
                    field.write(path)

            vm.finalize()
            vm.__init__()
            MPI_COMM.Barrier()
예제 #6
0
    def test_get_intersects_parallel(self):
        if sys.version_info.major == 3 and sys.version_info.minor == 5:
            raise SkipTest('undefined behavior with Python 3.5')

        grid = self.get_gridxy()

        live_ranks = vm.get_live_ranks_from_object(grid)

        # Test with an empty subset.
        subset_geom = box(1000., 1000., 1100., 1100.)
        with vm.scoped('empty subset', live_ranks):
            if not vm.is_null:
                with self.assertRaises(EmptySubsetError):
                    grid.get_intersects(subset_geom)

        # Test combinations.
        subset_geom = box(101.5, 40.5, 102.5, 42.)

        keywords = dict(is_vectorized=[True, False],
                        has_bounds=[False, True],
                        use_bounds=[False, True],
                        keep_touches=[True, False])

        for ctr, k in enumerate(self.iter_product_keywords(keywords)):
            grid = self.get_gridxy()

            vm_name, _ = vm.create_subcomm_by_emptyable('grid testing',
                                                        grid,
                                                        is_current=True)
            if vm.is_null:
                vm.free_subcomm(name=vm_name)
                vm.set_comm()
                continue

            if k.has_bounds:
                grid.set_extrapolated_bounds('xbounds', 'ybounds', 'bounds')
                self.assertTrue(grid.has_bounds)

            # Cannot use bounds with a point grid abstraction.
            if k.use_bounds and grid.abstraction == 'point':
                vm.free_subcomm(name=vm_name)
                vm.set_comm()
                continue

            grid_sub, slc = grid.get_intersects(subset_geom,
                                                keep_touches=k.keep_touches,
                                                use_bounds=k.use_bounds,
                                                return_slice=True)

            if k.has_bounds:
                self.assertTrue(grid.has_bounds)

            # Test geometries are filled appropriately after allocation.
            if not grid_sub.is_empty:
                for t in grid_sub.get_abstraction_geometry().get_value().flat:
                    self.assertIsInstance(t, BaseGeometry)

            self.assertIsInstance(grid_sub, Grid)
            if k.keep_touches:
                if k.has_bounds and k.use_bounds:
                    desired = (slice(0, 3, None), slice(0, 3, None))
                else:
                    desired = (slice(1, 3, None), slice(1, 2, None))
            else:
                if k.has_bounds and k.use_bounds:
                    desired = (slice(1, 3, None), slice(1, 2, None))
                else:
                    desired = (slice(1, 2, None), slice(1, 2, None))
            if not grid.is_empty:
                self.assertEqual(grid.has_bounds, k.has_bounds)
                self.assertTrue(grid.is_vectorized)
            self.assertEqual(slc, desired)

            vm.free_subcomm(name=vm_name)
            vm.set_comm()

        # Test against a file. #########################################################################################
        subset_geom = box(101.5, 40.5, 102.5, 42.)

        if MPI_RANK == 0:
            path_grid = self.get_temporary_file_path('grid.nc')
        else:
            path_grid = None
        path_grid = MPI_COMM.bcast(path_grid)

        grid_to_write = self.get_gridxy()
        with vm.scoped_by_emptyable('write', grid_to_write):
            if not vm.is_null:
                field = Field(grid=grid_to_write)
                field.write(path_grid, driver=DriverNetcdfCF)
        MPI_COMM.Barrier()

        rd = RequestDataset(uri=path_grid)
        x = SourcedVariable(name='x', request_dataset=rd)
        self.assertIsNone(x._value)
        y = SourcedVariable(name='y', request_dataset=rd)
        self.assertIsNone(x._value)
        self.assertIsNone(y._value)

        grid = Grid(x, y)

        for target in [grid._y_name, grid._x_name]:
            self.assertIsNone(grid.parent[target]._value)
        self.assertTrue(grid.is_vectorized)

        with vm.scoped_by_emptyable('intersects', grid):
            if not vm.is_null:
                sub, slc = grid.get_intersects(subset_geom, return_slice=True)

                self.assertEqual(slc, (slice(1, 3, None), slice(1, 2, None)))
                self.assertIsInstance(sub, Grid)

        # The file may be deleted before other ranks open.
        MPI_COMM.Barrier()