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