Skip to content

Add kernel linting via @parcels.validate_kernel - #2842

Open
VeckoTheGecko wants to merge 5 commits into
Parcels-code:mainfrom
VeckoTheGecko:2109-kernel-linting
Open

Add kernel linting via @parcels.validate_kernel#2842
VeckoTheGecko wants to merge 5 commits into
Parcels-code:mainfrom
VeckoTheGecko:2109-kernel-linting

Conversation

@VeckoTheGecko

Copy link
Copy Markdown
Contributor

Description

This PR adds linting for Parcels kernels to help with correctness and for migration to v4.

The linting is broken up into errors and warnings:

  • Errors are guaranteed to be incorrect
    • i.e., using an incorrect function signature for your kernels, calling particles.delete()
  • Warnings are either likely to be incorrect, or give inaccurate results
    • using particle_dlon - a user might intentionally define this variable in their v4 kernel. There's no way to distinguish between that usage and someone upgrading their v3 kernel.
    • sampling ei, they should be warned about where they're sampling it

This linting is exposed via a decorator for users, and the docstring for validate_kernel shows which rules and looked for. I looked through the migration guide etc. and thought these rules were good, let me know @erikvansebille if you think additional rules are needed.

@parcels.validate_kernel
def my_kernel(particle, fieldset, time): ...

providing an opt-in endpoint for raising these errors and warnings before the execution phase of a simulation

Internally in the execute loop these kernels are validated again. Providing the decorator is more for providing a good user experience for upgrading kernels.

Example kernel upgrade

The following kernel is taken from PlasticParcels

import parcels
import math

@parcels.validate_kernel
def StokesDrift(particle, fieldset, time):
    # Sample the peak wave period
    T_p = fieldset.wave_Tp[time, particle.depth, particle.lat, particle.lon]

    # Compute the local bathymetry / water depth with a margin of error
    local_bathymetry = 0.99*fieldset.bathymetry[time, particle.depth, particle.lat, particle.lon]

    # Only compute displacements if the peak wave period is large enough and the particle is in the water
    if T_p > 1E-14 and particle.depth < local_bathymetry:
        # Sample the U / V components of Stokes drift
        stokes_U = fieldset.Stokes_U[time, particle.depth, particle.lat, particle.lon]
        stokes_V = fieldset.Stokes_V[time, particle.depth, particle.lat, particle.lon]

        # Peak wave frequency
        omega_p = 2. * math.pi / T_p

        # Peak wave number
        k_p = (omega_p ** 2) / fieldset.G

        # Repeated inner term of Eq. (19) - note depth is negative in this formulation, but model depths are positive by convention
        kp_z_2 = 2. * k_p * particle.depth

        # Decay factor in Eq. (19) -- Where beta=1 for the Phillips spectrum
        decay = math.exp(-kp_z_2) - math.sqrt(math.pi * kp_z_2) * math.erfc(math.sqrt(kp_z_2))

        # Apply Eq. (19) and compute particle displacement
        particle_dlon += stokes_U * decay * particle.dt  # noqa
        particle_dlat += stokes_V * decay * particle.dt  # noqa

which gives

/Users/Hodgs004/coding/repos/parcels/t.py:1: UserWarning: This is an alpha version of Parcels v4. The API is not stable and may change without deprecation warnings.
  import parcels
/Users/Hodgs004/coding/repos/parcels/t.py:4: KernelWarning: Kernel `StokesDrift` has 1 validation error(s):
  - Kernel signature must be `def StokesDrift(particles, fieldset)`, but got `def StokesDrift(particle, fieldset, time)`. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.

Kernel `StokesDrift` has 16 warning(s):
  - Line 4: `particle.depth` is deprecated. Use `particles.z` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 4: `particle.lat` is deprecated. Use `particles.y` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 4: `particle.lon` is deprecated. Use `particles.x` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 7: `particle.depth` is deprecated. Use `particles.z` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 7: `particle.lat` is deprecated. Use `particles.y` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 7: `particle.lon` is deprecated. Use `particles.x` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 10: `particle.depth` is deprecated. Use `particles.z` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 12: `particle.depth` is deprecated. Use `particles.z` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 12: `particle.lat` is deprecated. Use `particles.y` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 12: `particle.lon` is deprecated. Use `particles.x` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 13: `particle.depth` is deprecated. Use `particles.z` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 13: `particle.lat` is deprecated. Use `particles.y` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 13: `particle.lon` is deprecated. Use `particles.x` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 22: `particle.depth` is deprecated. Use `particles.z` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 28: `particle_dlon` is no longer valid in Parcels v4. Use `particles.dx` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 29: `particle_dlat` is no longer valid in Parcels v4. Use `particles.dy` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  @parcels.validate_kernel
Traceback (most recent call last):
  File "/Users/Hodgs004/coding/repos/parcels/t.py", line 4, in <module>
    @parcels.validate_kernel
     ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/Hodgs004/coding/repos/parcels/src/parcels/_core/utils/kernel_linting.py", line 232, in validate_kernel
    raise KernelValidationError(report)
parcels._core.utils.kernel_linting.KernelValidationError: Kernel `StokesDrift` has 1 validation error(s):
  - Kernel signature must be `def StokesDrift(particles, fieldset)`, but got `def StokesDrift(particle, fieldset, time)`. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.

Kernel `StokesDrift` has 16 warning(s):
  - Line 4: `particle.depth` is deprecated. Use `particles.z` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 4: `particle.lat` is deprecated. Use `particles.y` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 4: `particle.lon` is deprecated. Use `particles.x` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 7: `particle.depth` is deprecated. Use `particles.z` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 7: `particle.lat` is deprecated. Use `particles.y` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 7: `particle.lon` is deprecated. Use `particles.x` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 10: `particle.depth` is deprecated. Use `particles.z` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 12: `particle.depth` is deprecated. Use `particles.z` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 12: `particle.lat` is deprecated. Use `particles.y` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 12: `particle.lon` is deprecated. Use `particles.x` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 13: `particle.depth` is deprecated. Use `particles.z` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 13: `particle.lat` is deprecated. Use `particles.y` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 13: `particle.lon` is deprecated. Use `particles.x` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 22: `particle.depth` is deprecated. Use `particles.z` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 28: `particle_dlon` is no longer valid in Parcels v4. Use `particles.dx` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.
  - Line 29: `particle_dlat` is no longer valid in Parcels v4. Use `particles.dy` instead. See https://docs.oceanparcels.org/en/latest/user_guide/v4-migration.html for more info.

Note that there is a doubling up - the "report" is printed once for the warnings and once for the errors. I think that this is fine, and better than splitting them up (as warnings are likely errors as well, its nice to deal with them at the same time).

Checklist

AI Disclosure

  • This PR contains AI-generated content.
    • I have tested any AI-generated content in my PR.
    • I take responsibility for any AI-generated content in my PR.
    • Describe how you used it (e.g., by pasting your prompt): For creating the AST parsers and for creating the test suite

@VeckoTheGecko

Copy link
Copy Markdown
Contributor Author

Still need to update the tests (will do next week), otherwise ready for review

We need to decide where in docs to raise this (likely in quickstart and in migration guide)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

Runtime warnings for kernels (syntax upgrading, and correctness)

1 participant