From ef8ba9b28cff552fd097ef88595fe8207add8d09 Mon Sep 17 00:00:00 2001 From: sloosvel Date: Tue, 25 Jun 2019 17:06:03 +0200 Subject: [PATCH 01/13] Add first version --- diagonals/zonmean.py | 137 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 diagonals/zonmean.py diff --git a/diagonals/zonmean.py b/diagonals/zonmean.py new file mode 100644 index 0000000..3030d92 --- /dev/null +++ b/diagonals/zonmean.py @@ -0,0 +1,137 @@ +import os + +import numpy as np + +import iris +import iris.cube +import iris.analysis + +import warnings +import datetime + +import numba +from numba import vectorize +from numba import cuda +from numba import njit +from numba import int32, int64, float32, float64 +from numba.cuda.cudadrv import driver + +import diagonals + +__all__ = ['compute_zonmean', 'get_basin_area'] + + +def compute_zonmean(var, lats, area): + """Function that checks device and calls computing functions. + + Checks if the computations are going performed in the CPU or the GPU: + + Parameters + ---------- + var : float32 + Masked array containing variable data. + basins : float32 + List containing basin names and masks. + area : float32 + Masked array containing cell area. + + Returns + ------- + regmean: float32 + List containing regional mean for variable var + """ + if diagonals.CONFIG.use_gpu: + logger.warning('GPU routines not implemented for regmean diagnostic.' + 'Using CPU instead') + else: + zonmean = _compute_zonmean_cpu(var, lats, area) + return zonmean + + +def _compute_zonal_mean_cpu(var, lats, area): + times = var.shape[0] + levs = var.shape[1] + value = {} + for basin, mask in weight.items(): + for time in times: + for lev in levs: + value[basin]= _zonal_mean_cpu(var[t, l, :, :], + area[basin], + lats) + return value + + +def _compute_zonal_mean_gpu(var, lats, area): + times = var.shape[0] + levs = var.shape[1] + lats = var.shape[2] + lons = var.shape[3] + value = {} + + block = (128, 1, 1) + grid_size = (lons // block[0]) + 1 + grid = (grid_size, lats) + gpu_var = cuda.to_device(var.astype(np.float32)) + total = cuda.device_array(180, dtype=np.float32) + weights = cuda.device_array(180, dtype=np.float32) + for basin, mask in area.items(): + gpu_area = cuda.to_device(area[basin].astype(np.float32)) + gpu_value = _zonal_mean_gpu(gpu_var, gpu_area, lats) + value[basin] = gpu_value.copy_to_host() + del gpu_area, gpu_value, gpu_var + + return value + +@numba.njit() +def _zonal_mean_cpu(variable, weight, latitude): + total = np.zeros(180, np.float64) + weights = np.zeros(180, np.float64) + for i in range(variable.shape[0]): + for j in range(variable.shape[1]): + if weight[i, j] == 0: + continue + bin_value = int(round(latitude[i, j]) + 90) + weights[bin_value] += weight[i, j] + total[bin_value] += variable[i, j] * weight[i, j] + return total / weights + + +@cuda.jit() +def _zonal_mean_gpu(variable, weight, latitude): + total[i, j] = 0.0 + weights[i, j] = 0.0 + if(i >= total.shape[0]): + return + if weight[i, j] == 0: + continue + bin_value = int(round(latitude[i, j]) + 90) + weights[bin_value] += weight[i, j] + total[bin_value] += variable[i, j] * weight[i, j] + return total / weights + + +def get_basin_area(areacello, basins): + basin_areas = {} + for basin in basins: + basin_areas[basin] = _compute_basin_area(areacello, basins[basin]) + return basin_areas + + +@vectorize(['float32(float32, float32)'], target='cpu') +def _compute_basin_area(areacello, basin): + """Vectorized numba function executed on the cpu that computes the area + for each basin: + + Parameters + ---------- + areacello : float32 + Masked array containing areacello. + basin: float32 + Masked array containing the mask for a given basin. + + Returns + ------- + areacello*basin : float32 + Masked array containing the area for a given basin. + """ + return areacello*basin \ No newline at end of file -- GitLab From 6d957aabd206f774b356d4db0900f8646e04ae0e Mon Sep 17 00:00:00 2001 From: sloosvel Date: Tue, 25 Jun 2019 17:14:02 +0200 Subject: [PATCH 02/13] Add first version --- diagonals/examples/examples-zonalmean.py | 59 ++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 diagonals/examples/examples-zonalmean.py diff --git a/diagonals/examples/examples-zonalmean.py b/diagonals/examples/examples-zonalmean.py new file mode 100644 index 0000000..c7d9fed --- /dev/null +++ b/diagonals/examples/examples-zonalmean.py @@ -0,0 +1,59 @@ +import logging +import datetime +import numpy as np + +import iris +import iris.cube +import iris.analysis +import iris.coords +import iris.coord_categorisation +import iris.analysis + +import diagonals +import diagonals.zonmean as zonmean +from diagonals.mesh_helpers.nemo import Nemo + +MESH_FILE = "/esarchive/autosubmit/con_files/mesh_mask_nemo.Ec3.2_O1L75.nc" +REGIONS_FILE = "/esarchive/autosubmit/con_files/mask.regions.Ec3.2_O1L75.nc" +THETAO_FILE = "/esarchive/exp/ecearth/a16l/cmorfiles/CMIP/EC-Earth-Consortium"\ + "/EC-Earth3-LR/historical/r1i1p1f1/Omon/thetao/gn/v20180711/"\ + "thetao_Omon_EC-Earth3-LR_historical_r1i1p1f1_gn_"\ + "196101-196112.nc" + +logger = logging.getLogger(__name__) + + +def main(): + logging.basicConfig(level=logging.INFO) + start = datetime.datetime.now() + logger.info('Starting at %s', start) + mesh = Nemo(MESH_FILE, REGIONS_FILE) + with diagonals.CONFIG.context(use_gpu=False): + lats = mesh.get_mesh_var('latitude', THETAO_FILE) + areacello = mesh.get_areacello() + var = load_thetao() + basins = load_masks() + area_basin = zonmean.get_basin_area(areacello) + zonmean = zonmean.compute_zonmean(var, lats, area) + + +def load_thetao(): + thetao = iris.load_cube(THETAO_FILE, 'sea_water_potential_temperature') + thetao_data = thetao.data.astype(np.float32) + return thetao_data + + +def load_masks(): + basins = {} + cubes = iris.load(REGIONS_FILE) + for cube in cubes: + name = cube.name() + if name in ('nav_lat', 'nav_lon', 'Caspian_Sea'): + continue + cube = cube.extract(iris.Constraint(z=1)) + basins[name] = cube.data.astype(np.float32) + return basins + + +if __name__ == '__main__': + main() \ No newline at end of file -- GitLab From 988278d58d060d277da9bedaed4dcad759ca4763 Mon Sep 17 00:00:00 2001 From: sloosvel Date: Fri, 28 Jun 2019 15:18:44 +0200 Subject: [PATCH 03/13] First version of zonal mean, pending to test --- diagonals/examples/examples-zonalmean.py | 2 +- diagonals/zonmean.py | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/diagonals/examples/examples-zonalmean.py b/diagonals/examples/examples-zonalmean.py index c7d9fed..9a90df0 100644 --- a/diagonals/examples/examples-zonalmean.py +++ b/diagonals/examples/examples-zonalmean.py @@ -56,4 +56,4 @@ def load_masks(): if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/diagonals/zonmean.py b/diagonals/zonmean.py index 3030d92..bba8d3d 100644 --- a/diagonals/zonmean.py +++ b/diagonals/zonmean.py @@ -55,9 +55,9 @@ def _compute_zonal_mean_cpu(var, lats, area): for basin, mask in weight.items(): for time in times: for lev in levs: - value[basin]= _zonal_mean_cpu(var[t, l, :, :], - area[basin], - lats) + value[basin] = _zonal_mean_cpu(var[t, l, :, :], + area[basin], + lats) return value @@ -75,13 +75,14 @@ def _compute_zonal_mean_gpu(var, lats, area): total = cuda.device_array(180, dtype=np.float32) weights = cuda.device_array(180, dtype=np.float32) for basin, mask in area.items(): - gpu_area = cuda.to_device(area[basin].astype(np.float32)) - gpu_value = _zonal_mean_gpu(gpu_var, gpu_area, lats) - value[basin] = gpu_value.copy_to_host() + gpu_area = cuda.to_device(area[basin].astype(np.float32)) + gpu_value = _zonal_mean_gpu(gpu_var, gpu_area, lats) + value[basin] = gpu_value.copy_to_host() del gpu_area, gpu_value, gpu_var return value + @numba.njit() def _zonal_mean_cpu(variable, weight, latitude): total = np.zeros(180, np.float64) @@ -102,11 +103,10 @@ def _zonal_mean_gpu(variable, weight, latitude): weights[i, j] = 0.0 if(i >= total.shape[0]): return - if weight[i, j] == 0: - continue - bin_value = int(round(latitude[i, j]) + 90) - weights[bin_value] += weight[i, j] - total[bin_value] += variable[i, j] * weight[i, j] + if(weight[i, j] != 0.0): + bin_value = int(round(latitude[i, j]) + 90) + weights[bin_value] += weight[i, j] + total[bin_value] += variable[i, j] * weight[i, j] return total / weights @@ -134,4 +134,4 @@ def _compute_basin_area(areacello, basin): areacello*basin : float32 Masked array containing the area for a given basin. """ - return areacello*basin \ No newline at end of file + return areacello*basin -- GitLab From acc5e95e5cb9714ec023a8e31f2836acca06c678 Mon Sep 17 00:00:00 2001 From: sloosvel Date: Mon, 1 Jul 2019 12:34:45 +0200 Subject: [PATCH 04/13] Fix bugs in cpu routine --- diagonals/zonmean.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/diagonals/zonmean.py b/diagonals/zonmean.py index bba8d3d..5094423 100644 --- a/diagonals/zonmean.py +++ b/diagonals/zonmean.py @@ -44,7 +44,7 @@ def compute_zonmean(var, lats, area): logger.warning('GPU routines not implemented for regmean diagnostic.' 'Using CPU instead') else: - zonmean = _compute_zonmean_cpu(var, lats, area) + zonmean = _compute_zonal_mean_cpu(var, lats, area) return zonmean @@ -52,11 +52,13 @@ def _compute_zonal_mean_cpu(var, lats, area): times = var.shape[0] levs = var.shape[1] value = {} - for basin, mask in weight.items(): - for time in times: - for lev in levs: - value[basin] = _zonal_mean_cpu(var[t, l, :, :], - area[basin], + for basin, mask in area.items(): + weight = np.squeeze(area[basin]) + value[basin] = np.empty((times, levs, 180)) + for time in range(times): + for lev in range(levs): + value[basin][time][lev][:] = _zonal_mean_cpu(var[time, lev, :, :], + weight, lats) return value @@ -85,8 +87,8 @@ def _compute_zonal_mean_gpu(var, lats, area): @numba.njit() def _zonal_mean_cpu(variable, weight, latitude): - total = np.zeros(180, np.float64) - weights = np.zeros(180, np.float64) + total = np.zeros(180, np.float32) + weights = np.zeros(180, np.float32) for i in range(variable.shape[0]): for j in range(variable.shape[1]): if weight[i, j] == 0: -- GitLab From 07348b042918c187dfd2229ab9538be804f06ac3 Mon Sep 17 00:00:00 2001 From: sloosvel Date: Mon, 1 Jul 2019 13:19:39 +0200 Subject: [PATCH 05/13] Add save function --- diagonals/examples/examples-zonalmean.py | 31 ++++++++++++++++++------ 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/diagonals/examples/examples-zonalmean.py b/diagonals/examples/examples-zonalmean.py index 9a90df0..b3fcd28 100644 --- a/diagonals/examples/examples-zonalmean.py +++ b/diagonals/examples/examples-zonalmean.py @@ -15,10 +15,10 @@ from diagonals.mesh_helpers.nemo import Nemo MESH_FILE = "/esarchive/autosubmit/con_files/mesh_mask_nemo.Ec3.2_O1L75.nc" REGIONS_FILE = "/esarchive/autosubmit/con_files/mask.regions.Ec3.2_O1L75.nc" -THETAO_FILE = "/esarchive/exp/ecearth/a16l/cmorfiles/CMIP/EC-Earth-Consortium"\ - "/EC-Earth3-LR/historical/r1i1p1f1/Omon/thetao/gn/v20180711/"\ - "thetao_Omon_EC-Earth3-LR_historical_r1i1p1f1_gn_"\ - "196101-196112.nc" +THETAO_FILE = "/esarchive/exp/ecearth/a1tr/cmorfiles/CMIP/EC-Earth-Consortium"\ + "/EC-Earth3/historical/r24i1p1f1/Omon/thetao/gn/v20190312/"\ + "thetao_Omon_EC-Earth3_historical_r24i1p1f1_gn_"\ + "185001-185012.nc" logger = logging.getLogger(__name__) @@ -29,12 +29,19 @@ def main(): logger.info('Starting at %s', start) mesh = Nemo(MESH_FILE, REGIONS_FILE) with diagonals.CONFIG.context(use_gpu=False): - lats = mesh.get_mesh_var('latitude', THETAO_FILE) + lats = mesh.get_mesh_var('nav_lat', dtype=np.float32) areacello = mesh.get_areacello() var = load_thetao() basins = load_masks() - area_basin = zonmean.get_basin_area(areacello) - zonmean = zonmean.compute_zonmean(var, lats, area) + area_basin = zonmean.get_basin_area(areacello, basins) + zonalmean = zonmean.compute_zonmean(var, lats, area_basin) + if diagonals.CONFIG.use_gpu: + device = 'GPU' + else: + device = 'CPU' + save_data(zonalmean, basins, device) + ellapsed = datetime.datetime.now() - start + logger.info('Total ellapsed time on the %s: %s', device, ellapsed) def load_thetao(): @@ -55,5 +62,15 @@ def load_masks(): return basins +def save_data(zonalmean, basins, device): + cubes_zonmean = iris.cube.CubeList() + for basin in basins.keys(): + cube_zonmean = iris.cube.Cube(zonalmean[basin]) + cube_zonmean.add_aux_coord(iris.coords.AuxCoord(basin, 'region')) + cubes_zonmean.append(cube_zonmean) + iris.save(cubes_zonmean.merge_cube(), '/esarchive/scratch/sloosvel/' + 'numba_outputs/zonmean_{0}.nc'.format(device), zlib=True) + + if __name__ == '__main__': main() -- GitLab From 81c05bac1b7daf370ef223be6359771a3f59fe45 Mon Sep 17 00:00:00 2001 From: sloosvel Date: Mon, 1 Jul 2019 13:24:28 +0200 Subject: [PATCH 06/13] Fix style issues --- diagonals/siasie.py | 4 ++-- diagonals/zonmean.py | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/diagonals/siasie.py b/diagonals/siasie.py index 95f3832..b4280d3 100644 --- a/diagonals/siasie.py +++ b/diagonals/siasie.py @@ -137,10 +137,10 @@ def _compute_sic_cpu(gphit, area, sic_slices, basins, sithick): if sithick: temp = _voln_cpu(gphit, area, tmask, sic, sit) - voln[b][time] = np.sum(temp, axis=(1,2)) + voln[b][time] = np.sum(temp, axis=(1, 2)) temp = _vols_cpu(gphit, area, tmask, sic, sit) - vols[b][time] = np.sum(temp, axis=(1,2)) + vols[b][time] = np.sum(temp, axis=(1, 2)) b += 1 diff --git a/diagonals/zonmean.py b/diagonals/zonmean.py index 5094423..082b3c4 100644 --- a/diagonals/zonmean.py +++ b/diagonals/zonmean.py @@ -41,8 +41,7 @@ def compute_zonmean(var, lats, area): List containing regional mean for variable var """ if diagonals.CONFIG.use_gpu: - logger.warning('GPU routines not implemented for regmean diagnostic.' - 'Using CPU instead') + zonmean = _compute_zonal_mean_gpu(var, lats, area) else: zonmean = _compute_zonal_mean_cpu(var, lats, area) return zonmean @@ -55,11 +54,11 @@ def _compute_zonal_mean_cpu(var, lats, area): for basin, mask in area.items(): weight = np.squeeze(area[basin]) value[basin] = np.empty((times, levs, 180)) - for time in range(times): + for t in range(times): for lev in range(levs): - value[basin][time][lev][:] = _zonal_mean_cpu(var[time, lev, :, :], - weight, - lats) + value[basin][t][lev][:] = _zonal_mean_cpu(var[t, lev, :, :], + weight, + lats) return value -- GitLab From 6c7c63eb5c4d6e2131cf3dd0b3d1fc7e8d29d8ed Mon Sep 17 00:00:00 2001 From: sloosvel Date: Mon, 1 Jul 2019 16:17:18 +0200 Subject: [PATCH 07/13] Test gpu routine --- diagonals/zonmean.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/diagonals/zonmean.py b/diagonals/zonmean.py index 082b3c4..74f23fd 100644 --- a/diagonals/zonmean.py +++ b/diagonals/zonmean.py @@ -62,7 +62,7 @@ def _compute_zonal_mean_cpu(var, lats, area): return value -def _compute_zonal_mean_gpu(var, lats, area): +def _compute_zonal_mean_gpu(var, latitudes, area): times = var.shape[0] levs = var.shape[1] lats = var.shape[2] @@ -73,12 +73,17 @@ def _compute_zonal_mean_gpu(var, lats, area): grid_size = (lons // block[0]) + 1 grid = (grid_size, lats) gpu_var = cuda.to_device(var.astype(np.float32)) - total = cuda.device_array(180, dtype=np.float32) - weights = cuda.device_array(180, dtype=np.float32) + gpu_lats = cuda.to_device(latitudes.astype(np.float32)) + gpu_total = cuda.device_array(180, dtype=np.float32) + gpu_weights = cuda.device_array(180, dtype=np.float32) for basin, mask in area.items(): - gpu_area = cuda.to_device(area[basin].astype(np.float32)) - gpu_value = _zonal_mean_gpu(gpu_var, gpu_area, lats) - value[basin] = gpu_value.copy_to_host() + value[basin] = np.empty((times, levs, 180)) + gpu_area = cuda.to_device(np.squeeze(area[basin]).astype(np.float32)) + for t in range(times): + for lev in range(levels): + gpu_value = _zonal_mean_gpu(gpu_var[t, lev, :, :], gpu_area, + gpu_lats, gpu_total, gpu_weights) + value[basin][t][lev][:] = gpu_value.copy_to_host() del gpu_area, gpu_value, gpu_var return value @@ -99,7 +104,7 @@ def _zonal_mean_cpu(variable, weight, latitude): @cuda.jit() -def _zonal_mean_gpu(variable, weight, latitude): +def _zonal_mean_gpu(variable, weight, latitude, total, weights): total[i, j] = 0.0 weights[i, j] = 0.0 if(i >= total.shape[0]): @@ -108,7 +113,7 @@ def _zonal_mean_gpu(variable, weight, latitude): bin_value = int(round(latitude[i, j]) + 90) weights[bin_value] += weight[i, j] total[bin_value] += variable[i, j] * weight[i, j] - return total / weights + return total[i, j] / weights[i, j] def get_basin_area(areacello, basins): -- GitLab From 4b8257bc8eead98fc6ec111df1a747fa2900e304 Mon Sep 17 00:00:00 2001 From: sloosvel Date: Mon, 1 Jul 2019 16:19:37 +0200 Subject: [PATCH 08/13] Fix wrong var name --- diagonals/zonmean.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diagonals/zonmean.py b/diagonals/zonmean.py index 74f23fd..05758bd 100644 --- a/diagonals/zonmean.py +++ b/diagonals/zonmean.py @@ -80,7 +80,7 @@ def _compute_zonal_mean_gpu(var, latitudes, area): value[basin] = np.empty((times, levs, 180)) gpu_area = cuda.to_device(np.squeeze(area[basin]).astype(np.float32)) for t in range(times): - for lev in range(levels): + for lev in range(levs): gpu_value = _zonal_mean_gpu(gpu_var[t, lev, :, :], gpu_area, gpu_lats, gpu_total, gpu_weights) value[basin][t][lev][:] = gpu_value.copy_to_host() -- GitLab From adaa8caaca9b60e66d394e58acfd36b8af82f840 Mon Sep 17 00:00:00 2001 From: sloosvel Date: Mon, 1 Jul 2019 16:22:41 +0200 Subject: [PATCH 09/13] Add missing indices --- diagonals/zonmean.py | 1 + 1 file changed, 1 insertion(+) diff --git a/diagonals/zonmean.py b/diagonals/zonmean.py index 05758bd..51c7aa6 100644 --- a/diagonals/zonmean.py +++ b/diagonals/zonmean.py @@ -105,6 +105,7 @@ def _zonal_mean_cpu(variable, weight, latitude): @cuda.jit() def _zonal_mean_gpu(variable, weight, latitude, total, weights): + i, j = cuda.grid(2) total[i, j] = 0.0 weights[i, j] = 0.0 if(i >= total.shape[0]): -- GitLab From db1b28785a37b8f22dc26bade29bb94bc61424c4 Mon Sep 17 00:00:00 2001 From: sloosvel Date: Mon, 1 Jul 2019 16:26:44 +0200 Subject: [PATCH 10/13] Delete wrong indexed array --- diagonals/zonmean.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/diagonals/zonmean.py b/diagonals/zonmean.py index 51c7aa6..a59bfd9 100644 --- a/diagonals/zonmean.py +++ b/diagonals/zonmean.py @@ -106,15 +106,13 @@ def _zonal_mean_cpu(variable, weight, latitude): @cuda.jit() def _zonal_mean_gpu(variable, weight, latitude, total, weights): i, j = cuda.grid(2) - total[i, j] = 0.0 - weights[i, j] = 0.0 if(i >= total.shape[0]): return if(weight[i, j] != 0.0): bin_value = int(round(latitude[i, j]) + 90) weights[bin_value] += weight[i, j] total[bin_value] += variable[i, j] * weight[i, j] - return total[i, j] / weights[i, j] + return total / weights def get_basin_area(areacello, basins): -- GitLab From 32fc9d6eff9c48f57f77137e37af4753627352b4 Mon Sep 17 00:00:00 2001 From: sloosvel Date: Mon, 1 Jul 2019 16:49:30 +0200 Subject: [PATCH 11/13] segmentation fault --- diagonals/examples/examples-zonalmean.py | 2 +- diagonals/zonmean.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/diagonals/examples/examples-zonalmean.py b/diagonals/examples/examples-zonalmean.py index b3fcd28..5b5b3a7 100644 --- a/diagonals/examples/examples-zonalmean.py +++ b/diagonals/examples/examples-zonalmean.py @@ -28,7 +28,7 @@ def main(): start = datetime.datetime.now() logger.info('Starting at %s', start) mesh = Nemo(MESH_FILE, REGIONS_FILE) - with diagonals.CONFIG.context(use_gpu=False): + with diagonals.CONFIG.context(use_gpu=True): lats = mesh.get_mesh_var('nav_lat', dtype=np.float32) areacello = mesh.get_areacello() var = load_thetao() diff --git a/diagonals/zonmean.py b/diagonals/zonmean.py index a59bfd9..9ac5296 100644 --- a/diagonals/zonmean.py +++ b/diagonals/zonmean.py @@ -81,9 +81,9 @@ def _compute_zonal_mean_gpu(var, latitudes, area): gpu_area = cuda.to_device(np.squeeze(area[basin]).astype(np.float32)) for t in range(times): for lev in range(levs): - gpu_value = _zonal_mean_gpu(gpu_var[t, lev, :, :], gpu_area, - gpu_lats, gpu_total, gpu_weights) - value[basin][t][lev][:] = gpu_value.copy_to_host() + _zonal_mean_gpu[block, grid](gpu_var[t, lev, :, :], gpu_area, gpu_lats, gpu_total, gpu_weights) + value[basin][t][lev][:] = (gpu_total.copy_to_host() / + gpu_weights.copy_to_host()) del gpu_area, gpu_value, gpu_var return value @@ -109,10 +109,10 @@ def _zonal_mean_gpu(variable, weight, latitude, total, weights): if(i >= total.shape[0]): return if(weight[i, j] != 0.0): + bin_value = int(round(latitude[i, j]) + 90) weights[bin_value] += weight[i, j] total[bin_value] += variable[i, j] * weight[i, j] - return total / weights def get_basin_area(areacello, basins): -- GitLab From 6cabfa8ba915d150b71331098fb8de61838ef8ad Mon Sep 17 00:00:00 2001 From: sloosvel Date: Tue, 2 Jul 2019 13:16:42 +0200 Subject: [PATCH 12/13] Add warning due to numba bug --- diagonals/zonmean.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/diagonals/zonmean.py b/diagonals/zonmean.py index 9ac5296..9bc5397 100644 --- a/diagonals/zonmean.py +++ b/diagonals/zonmean.py @@ -41,9 +41,12 @@ def compute_zonmean(var, lats, area): List containing regional mean for variable var """ if diagonals.CONFIG.use_gpu: - zonmean = _compute_zonal_mean_gpu(var, lats, area) - else: - zonmean = _compute_zonal_mean_cpu(var, lats, area) + if diagonals.CONFIG.use_gpu: + logger.warning('GPU routines not implemented yet' + 'for zonmean diagnostic due to a compiler bug.' + 'Using CPU instead until bug has been fixed') + + zonmean = _compute_zonal_mean_cpu(var, lats, area) return zonmean @@ -81,7 +84,8 @@ def _compute_zonal_mean_gpu(var, latitudes, area): gpu_area = cuda.to_device(np.squeeze(area[basin]).astype(np.float32)) for t in range(times): for lev in range(levs): - _zonal_mean_gpu[block, grid](gpu_var[t, lev, :, :], gpu_area, gpu_lats, gpu_total, gpu_weights) + _zonal_mean_gpu[block, grid](gpu_var[t, lev, :, :], gpu_area, + gpu_lats, gpu_total, gpu_weights) value[basin][t][lev][:] = (gpu_total.copy_to_host() / gpu_weights.copy_to_host()) del gpu_area, gpu_value, gpu_var @@ -109,7 +113,7 @@ def _zonal_mean_gpu(variable, weight, latitude, total, weights): if(i >= total.shape[0]): return if(weight[i, j] != 0.0): - + bin_value = int(round(latitude[i, j]) + 90) weights[bin_value] += weight[i, j] total[bin_value] += variable[i, j] * weight[i, j] -- GitLab From 748d9a48757a6810c74a6566f7c442d867c3ae83 Mon Sep 17 00:00:00 2001 From: sloosvel Date: Tue, 2 Jul 2019 13:21:27 +0200 Subject: [PATCH 13/13] Fix style issues --- diagonals/zonmean.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/diagonals/zonmean.py b/diagonals/zonmean.py index 9bc5397..ccffc24 100644 --- a/diagonals/zonmean.py +++ b/diagonals/zonmean.py @@ -41,7 +41,6 @@ def compute_zonmean(var, lats, area): List containing regional mean for variable var """ if diagonals.CONFIG.use_gpu: - if diagonals.CONFIG.use_gpu: logger.warning('GPU routines not implemented yet' 'for zonmean diagnostic due to a compiler bug.' 'Using CPU instead until bug has been fixed') @@ -84,10 +83,10 @@ def _compute_zonal_mean_gpu(var, latitudes, area): gpu_area = cuda.to_device(np.squeeze(area[basin]).astype(np.float32)) for t in range(times): for lev in range(levs): - _zonal_mean_gpu[block, grid](gpu_var[t, lev, :, :], gpu_area, - gpu_lats, gpu_total, gpu_weights) - value[basin][t][lev][:] = (gpu_total.copy_to_host() / - gpu_weights.copy_to_host()) + _zonal_mean_gpu[block, grid](gpu_var[t, lev, :, :], gpu_area, + gpu_lats, gpu_total, gpu_weights) + value[basin][t][lev][:] = (gpu_total.copy_to_host() / + gpu_weights.copy_to_host()) del gpu_area, gpu_value, gpu_var return value -- GitLab