-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding progress bar to forward gravity calculation of prisms #312
Comments
@mdtanker thank you for opening this feature request! I wasn't aware of numba-progress so it's good to know it exists. My main concern with this is: Does this have an impact on performance? Adding a function call to jit-compiled loop (which usually runs many times) has the potential to slow down the process. It would be good to try this out and measure the performance impact. It's unlikely to be zero but I have no idea if it would be large. If the performance hit is small, particularly when not using a progressbar, then it would be great to have as an optional. The dependency on The Maybe @santisoler or @LL-Geo can advise on how you could go about trying this out? |
Thanks for the fast response @leouieda. I've had a go at implementing # Iterate over computation points and prisms
for l in prange(coordinates[0].size):
for m in range(prisms.shape[0]):
# Iterate over the prism boundaries to compute the result of the
# integration (see Nagy et al., 2000)
for i in range(2):
for j in range(2):
for k in range(2):
shift_east = prisms[m, 1 - i]
shift_north = prisms[m, 3 - j]
shift_upward = prisms[m, 5 - k]
# If i, j or k is 1, the shift_* will refer to the
# lower boundary, meaning the corresponding term should
# have a minus sign
out[l] += (
density[m]
* (-1) ** (i + j + k)
* kernel(
shift_east - coordinates[0][l],
shift_north - coordinates[1][l],
shift_upward - coordinates[2][l],
)
)
progress_proxy.update(1) To get this to work, I added the arg To calculate the forward gravity of a layer of prisms I was previously using something like the following: for k, v in layers.items():
df_grav[f'{k}_forward_grav'] = v['prisms'].prism_layer.gravity(
coordinates=(df_grav.x, df_grav.y, df_grav.z),
field = 'g_z',) Where Below is how I've updated this to show a progress bar for each of the 3 layers of prisms. from numba_progress import ProgressBar
for k, v in layers.items():
with ProgressBar(total=len(df_grav)) as progress:
df_grav[f'{k}_forward_grav'] = v['prisms'].prism_layer.gravity(
coordinates=(df_grav.x, df_grav.y, df_grav.z),
field = 'g_z', progress_proxy=progress)
100%|██████████| 16641.0/16641 [00:27<00:00, 608.82it/s]
100%|██████████| 16641.0/16641 [00:34<00:00, 489.12it/s]
100%|██████████| 16641.0/16641 [00:35<00:00, 464.67it/s] This took 1m 37s. Based off this it seem to not slow the runtime at all. Any suggestions for not needing to add the arg |
This looks great! Thanks @mdtanker for the idea! 🥇
Actually I was thinking that we don't need to expose the So, your last example would look like this: for k, v in layers.items():
df_grav[f'{k}_forward_grav'] = v['prisms'].prism_layer.gravity(
coordinates=(df_grav.x, df_grav.y, df_grav.z),
field = 'g_z',
progressbar=True,
) Since |
Thanks for opening this feature request @mdtanker ! I think if we only pass the progressbar to the outer loop (the observation points), that will have a small impact on the performance. |
Thanks for the suggestions! I have it working and everything seems alright, except if called with Here is an example without the progress bar, which took 1m 28.2s : for k, v in layers.items():
df_grav[f'{k}_forward_grav'] = v['prisms'].prism_layer.gravity(
coordinates=(df_grav.x, df_grav.y, df_grav.z),
field = 'g_z',
) And an example with for k, v in layers.items():
df_grav[f'{k}_forward_grav'] = v['prisms'].prism_layer.gravity(
coordinates=(df_grav.x, df_grav.y, df_grav.z),
field = 'g_z',
progressbar=True,
)
100%|██████████| 16641.0/16641 [00:29<00:00, 557.69it/s]
100%|██████████| 16641.0/16641 [00:31<00:00, 527.07it/s]
100%|██████████| 16641.0/16641 [00:33<00:00, 503.12it/s] In the if progressbar is True:
from numba_progress import ProgressBar
progress_proxy = ProgressBar(total = coordinates[0].size)
else:
progress_proxy = None And the following after the dispacher call: try:
progress_proxy.close()
except:
pass And this is the updated function: def jit_prism_gravity(coordinates, prisms, density, kernel, out, progress_proxy):
# Iterate over computation points and prisms
for l in prange(coordinates[0].size):
# Update progress bar if called
if progress_proxy is not None:
progress_proxy.update(1)
for m in range(prisms.shape[0]):
# Iterate over the prism boundaries to compute the result of the
# integration (see Nagy et al., 2000)
for i in range(2):
for j in range(2):
for k in range(2):
shift_east = prisms[m, 1 - i]
shift_north = prisms[m, 3 - j]
shift_upward = prisms[m, 5 - k]
# If i, j or k is 1, the shift_* will refer to the
# lower boundary, meaning the corresponding term should
# have a minus sign
out[l] += (
density[m]
* (-1) ** (i + j + k)
* kernel(
shift_east - coordinates[0][l],
shift_north - coordinates[1][l],
shift_upward - coordinates[2][l],
)
) Is the next step to open a pull request to implement this? |
Looking awesome! Congrats!
Thanks for noticing it. This is not a good behaviour: any user that keeps waiting for ~1 minute without seeing the progressbar moving will likely stop the computation. The progressbar should work both with parallel set to True or False. But don't worry about it now, we can look into it later. That's just troubleshooting.
Minor suggestion here. if progressbar:
progress_proxy.close() But, there's a good case in which we would like to use the
If a user flags
Absolutely! Feel free to open a PR with the changes. It doesn't need to be perfect nor the final version. We can continue this talk in there, with actual shared code we can both run and test. |
Good catch, I've added the |
Description of the desired feature:
During a call to
prism.gravity
(orprism_layer.gravity
) it would be great to have a progress bar which updates as the calculations advance through the gravity observation points (coordinates
) . @LL-Geo suggested thenumba_progress
package, which seems to be a good fit. Looking throughharmonica.forward.prisms.py
, I assume implementing this feature would be done within thejit_prism_gravity
function, and when calling the function, users would use something along the lines of:Are you willing to help implement and maintain this feature?
Yes I'm willing to try, but will likely need some assistance since it's my first code contribution, and I'm unfamiliar with numba_progress.
The text was updated successfully, but these errors were encountered: