From 50c16e13d3bfcbe2ccee9d60f7effb6f704661f0 Mon Sep 17 00:00:00 2001 From: erogluorhan Date: Sat, 21 Dec 2024 08:49:46 -0700 Subject: [PATCH 1/6] Vectorize coordinates._construct_face_centroids() --- uxarray/grid/coordinates.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/uxarray/grid/coordinates.py b/uxarray/grid/coordinates.py index 5c11c8281..c4f477d64 100644 --- a/uxarray/grid/coordinates.py +++ b/uxarray/grid/coordinates.py @@ -327,15 +327,14 @@ def _construct_face_centroids(node_x, node_y, node_z, face_nodes, n_nodes_per_fa tuple The x, y, and z coordinates of the centroids. """ - centroid_x = np.zeros((face_nodes.shape[0]), dtype=np.float64) - centroid_y = np.zeros((face_nodes.shape[0]), dtype=np.float64) - centroid_z = np.zeros((face_nodes.shape[0]), dtype=np.float64) - - for face_idx, n_max_nodes in enumerate(n_nodes_per_face): - # Compute Cartesian Average - centroid_x[face_idx] = np.mean(node_x[face_nodes[face_idx, 0:n_max_nodes]]) - centroid_y[face_idx] = np.mean(node_y[face_nodes[face_idx, 0:n_max_nodes]]) - centroid_z[face_idx] = np.mean(node_z[face_nodes[face_idx, 0:n_max_nodes]]) + + # Mask to ignore invalid indices + mask = np.arange(face_nodes.shape[1])[None, :] < n_nodes_per_face[:, None] + + # Calculate centroids + centroid_x = np.sum(node_x[face_nodes] * mask, axis=1) / n_nodes_per_face + centroid_y = np.sum(node_y[face_nodes] * mask, axis=1) / n_nodes_per_face + centroid_z = np.sum(node_z[face_nodes] * mask, axis=1) / n_nodes_per_face return _normalize_xyz(centroid_x, centroid_y, centroid_z) From ed7b2f908455409c8e0fc440c237ae0cd81cb2f4 Mon Sep 17 00:00:00 2001 From: Philip Chmielowiec <67855069+philipc2@users.noreply.github.com> Date: Wed, 15 Jan 2025 18:40:46 -0600 Subject: [PATCH 2/6] numba implementation --- uxarray/grid/coordinates.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/uxarray/grid/coordinates.py b/uxarray/grid/coordinates.py index c4f477d64..5e4a8581c 100644 --- a/uxarray/grid/coordinates.py +++ b/uxarray/grid/coordinates.py @@ -305,6 +305,7 @@ def _populate_face_centroids(grid, repopulate=False): ) +@njit(cache=True) def _construct_face_centroids(node_x, node_y, node_z, face_nodes, n_nodes_per_face): """Constructs the xyz centroid coordinate for each face using Cartesian Averaging. @@ -328,15 +329,24 @@ def _construct_face_centroids(node_x, node_y, node_z, face_nodes, n_nodes_per_fa The x, y, and z coordinates of the centroids. """ - # Mask to ignore invalid indices - mask = np.arange(face_nodes.shape[1])[None, :] < n_nodes_per_face[:, None] + centroid_x = np.zeros((face_nodes.shape[0]), dtype=np.float64) + centroid_y = np.zeros((face_nodes.shape[0]), dtype=np.float64) + centroid_z = np.zeros((face_nodes.shape[0]), dtype=np.float64) - # Calculate centroids - centroid_x = np.sum(node_x[face_nodes] * mask, axis=1) / n_nodes_per_face - centroid_y = np.sum(node_y[face_nodes] * mask, axis=1) / n_nodes_per_face - centroid_z = np.sum(node_z[face_nodes] * mask, axis=1) / n_nodes_per_face + for face_idx, n_max_nodes in enumerate(n_nodes_per_face): + # Compute Cartesian Average + x = np.mean(node_x[face_nodes[face_idx, 0:n_max_nodes]]) + y = np.mean(node_y[face_nodes[face_idx, 0:n_max_nodes]]) + z = np.mean(node_z[face_nodes[face_idx, 0:n_max_nodes]]) - return _normalize_xyz(centroid_x, centroid_y, centroid_z) + # Normalize coordinates + x, y, z = _normalize_xyz_scalar(x, y, z) + # Store coordinates + centroid_x[face_idx] = x + centroid_y[face_idx] = y + centroid_z[face_idx] = z + + return centroid_x, centroid_y, centroid_z def _welzl_recursive(points, boundary, R): From 0f2ccf16ed29e2d5a733027a199b101cbddc1a3e Mon Sep 17 00:00:00 2001 From: Philip Chmielowiec <67855069+philipc2@users.noreply.github.com> Date: Wed, 15 Jan 2025 18:50:00 -0600 Subject: [PATCH 3/6] add numba prange --- uxarray/grid/coordinates.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/uxarray/grid/coordinates.py b/uxarray/grid/coordinates.py index 5e4a8581c..f6c761a03 100644 --- a/uxarray/grid/coordinates.py +++ b/uxarray/grid/coordinates.py @@ -5,7 +5,7 @@ from uxarray.conventions import ugrid -from numba import njit +from numba import njit, prange from uxarray.constants import ERROR_TOLERANCE from typing import Union @@ -305,7 +305,7 @@ def _populate_face_centroids(grid, repopulate=False): ) -@njit(cache=True) +@njit(cache=True, parallel=True) def _construct_face_centroids(node_x, node_y, node_z, face_nodes, n_nodes_per_face): """Constructs the xyz centroid coordinate for each face using Cartesian Averaging. @@ -333,7 +333,9 @@ def _construct_face_centroids(node_x, node_y, node_z, face_nodes, n_nodes_per_fa centroid_y = np.zeros((face_nodes.shape[0]), dtype=np.float64) centroid_z = np.zeros((face_nodes.shape[0]), dtype=np.float64) - for face_idx, n_max_nodes in enumerate(n_nodes_per_face): + # for face_idx, n_max_nodes in enumerate(n_nodes_per_face): + for face_idx in prange(face_nodes.shape[0]): + n_max_nodes = n_nodes_per_face[face_idx] # Compute Cartesian Average x = np.mean(node_x[face_nodes[face_idx, 0:n_max_nodes]]) y = np.mean(node_y[face_nodes[face_idx, 0:n_max_nodes]]) From 1c5e1ce57c20f5cfbd9b28fe1dc9bd5bb40226c2 Mon Sep 17 00:00:00 2001 From: Philip Chmielowiec <67855069+philipc2@users.noreply.github.com> Date: Wed, 15 Jan 2025 18:52:24 -0600 Subject: [PATCH 4/6] remove comment --- uxarray/grid/coordinates.py | 1 - 1 file changed, 1 deletion(-) diff --git a/uxarray/grid/coordinates.py b/uxarray/grid/coordinates.py index f6c761a03..2d78b978a 100644 --- a/uxarray/grid/coordinates.py +++ b/uxarray/grid/coordinates.py @@ -333,7 +333,6 @@ def _construct_face_centroids(node_x, node_y, node_z, face_nodes, n_nodes_per_fa centroid_y = np.zeros((face_nodes.shape[0]), dtype=np.float64) centroid_z = np.zeros((face_nodes.shape[0]), dtype=np.float64) - # for face_idx, n_max_nodes in enumerate(n_nodes_per_face): for face_idx in prange(face_nodes.shape[0]): n_max_nodes = n_nodes_per_face[face_idx] # Compute Cartesian Average From 73809fbff556f4a3295361c68a2065d609237bf9 Mon Sep 17 00:00:00 2001 From: Philip Chmielowiec <67855069+philipc2@users.noreply.github.com> Date: Thu, 16 Jan 2025 09:21:55 -0600 Subject: [PATCH 5/6] faster n_node_per_face construction --- uxarray/grid/connectivity.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/uxarray/grid/connectivity.py b/uxarray/grid/connectivity.py index 78e936117..54bd1017e 100644 --- a/uxarray/grid/connectivity.py +++ b/uxarray/grid/connectivity.py @@ -146,13 +146,14 @@ def _build_n_nodes_per_face(face_nodes, n_face, n_max_face_nodes): """Constructs ``n_nodes_per_face``, which contains the number of non-fill- value nodes for each face in ``face_node_connectivity``""" - # padding to shape [n_face, n_max_face_nodes + 1] - closed = np.ones((n_face, n_max_face_nodes + 1), dtype=INT_DTYPE) * INT_FILL_VALUE - - closed[:, :-1] = face_nodes.copy() - - n_nodes_per_face = np.argmax(closed == INT_FILL_VALUE, axis=1) - + n_face, n_max_face_nodes = face_nodes.shape + n_nodes_per_face = np.empty(n_face, dtype=INT_DTYPE) + for i in range(n_face): + c = 0 + for j in range(n_max_face_nodes): + if face_nodes[i, j] != INT_FILL_VALUE: + c += 1 + n_nodes_per_face[i] = c return n_nodes_per_face From 5a2ef875f4ae4ebced7124728ad24a08a51cc140 Mon Sep 17 00:00:00 2001 From: erogluorhan Date: Wed, 5 Feb 2025 09:27:16 -0700 Subject: [PATCH 6/6] Remove unused variable assignment --- uxarray/grid/coordinates.py | 1 - 1 file changed, 1 deletion(-) diff --git a/uxarray/grid/coordinates.py b/uxarray/grid/coordinates.py index 025576023..2d78b978a 100644 --- a/uxarray/grid/coordinates.py +++ b/uxarray/grid/coordinates.py @@ -332,7 +332,6 @@ def _construct_face_centroids(node_x, node_y, node_z, face_nodes, n_nodes_per_fa centroid_x = np.zeros((face_nodes.shape[0]), dtype=np.float64) centroid_y = np.zeros((face_nodes.shape[0]), dtype=np.float64) centroid_z = np.zeros((face_nodes.shape[0]), dtype=np.float64) - n_face = n_nodes_per_face.shape[0] for face_idx in prange(face_nodes.shape[0]): n_max_nodes = n_nodes_per_face[face_idx]