Errors and warnings reference¶
The exception and warning classes Deepwave raises. Usage covers the conventions of the interface that raises them.
Exceptions and warnings¶
Deepwave raises its own exception types. Each one also inherits the builtin exception type that the same failure raised historically, so an existing except ValueError (or TypeError, RuntimeError, NotImplementedError, OSError, FloatingPointError) keeps catching exactly what it caught before – while except deepwave.DeepwaveError catches everything Deepwave raises deliberately, and nothing else. See Stability policy for what may change about them.
What “deliberately” covers¶
Every rejection Deepwave decides on – an argument it validates, a combination it cannot serve, a build or backend that is unavailable, a diverged wavefield, a scratch directory the filesystem refused – raises one of the classes below, so:
try:
out = deepwave.scalar(v, dx, dt, source_amplitudes=a,
source_locations=x_s)
except deepwave.DeepwaveError as error:
...
catches all of them. Two kinds of failure are deliberately outside it, and neither can be brought inside:
A
TypeErrorraised by Python’s own argument binding, before any Deepwave code runs: a missing required argument, a keyword spelled wrongly enough that no propagator accepts it, or an argument given twice. Python raises it while matching the call to the signature, so Deepwave has no opportunity to classify it. (A keyword a propagator recognises but cannot act on is a different thing: Deepwave checks that itself and raisesdeepwave.DeepwaveValueError.)Any exception from PyTorch or from the standard library – a shape mismatch inside an operation, an out-of-memory error, a CUDA failure. It stays exactly the exception those libraries raised; Deepwave does not wrap it, so a traceback still points at the operation that failed.
Deepwave also raises a few builtin exceptions where Python’s own protocols require them, rather than as a message to the caller: AttributeError from a __getattr__ for an unknown name, KeyError from a mapping lookup for an absent key, and AssertionError for an internal invariant that no call can violate (reaching one is a bug in Deepwave; please report it). These are protocol obligations and bug reports, not rejected requests, so they are not deepwave.DeepwaveError subclasses either. Everything else Deepwave raises on purpose is: tests/test_error_classes.py walks the source of every Deepwave module and fails if a raise of any other builtin exception type appears.
The classes¶
- exception deepwave.DeepwaveError(*args)¶
Base class for every exception Deepwave raises deliberately.
Catching this catches Deepwave’s own validation and capability errors without also catching unrelated exceptions from PyTorch or the standard library. Deepwave never raises
DeepwaveErroritself: every raise site uses one of the subclasses below, each of which also inherits the builtin exception type that site raised historically, soexcept ValueError(orTypeError,RuntimeError,NotImplementedError,FloatingPointError) keeps working unchanged.
- exception deepwave.DeepwaveValueError(*args)¶
A Deepwave error that is also a
ValueError.Raised for an argument whose type is right but whose value is not (an out-of-range number, an unrecognised option string, a mismatched shape).
- exception deepwave.DeepwaveTypeError(*args)¶
A Deepwave error that is also a
TypeError.Raised for an argument of the wrong type (a float where an int is required, a non-Tensor model).
- exception deepwave.DeepwaveRuntimeError(*args)¶
A Deepwave error that is also a
RuntimeError.Raised for a request that is well-formed but that this build, backend, or combination of options cannot serve.
- exception deepwave.DeepwaveNotImplementedError(*args)¶
A Deepwave error that is also a
NotImplementedError.Raised for a combination of options that is intended to work but has not been implemented yet.
- exception deepwave.DeepwaveOSError(*args)¶
A Deepwave error that is also an
OSError.Raised when the operating system refuses a filesystem operation Deepwave performs on the caller’s behalf, such as creating the scratch directory that
storage_mode="disk"writes its wavefield history into. The message names the argument that chose the location (storage_path) so that the fix is visible from the traceback alone.except OSErroraround a Deepwave call keeps catching it.
- exception deepwave.DeepwaveFloatingPointError(*args)¶
A Deepwave error that is also a
FloatingPointError.Raised when a tensor contains non-finite values, which usually means the simulation diverged; see
deepwave.check_finite().
- exception deepwave.DeepwaveFutureWarning(*args)¶
Warning category for a deprecated Deepwave spelling.
Emitted once per call per deprecated name, by the name that is going away, naming both the replacement and the release that removes it (see
DEPRECATION_REMOVAL_VERSION). Nothing that emits one changes what a call computes: the deprecated spelling keeps doing what it always did until it is removed.Silence it with one line:
warnings.filterwarnings( "ignore", category=deepwave.DeepwaveFutureWarning )
It subclasses
FutureWarning, so any filter that already targetsFutureWarningalso covers it.FutureWarningrather thanDeprecationWarningbecause the call that has to change is the user’s own: Python’s default filters showFutureWarningfrom any module, whileDeprecationWarningis hidden outside__main__, which is where a library’s deprecation is least likely to be read.
- exception deepwave.DeepwaveWarning(*args)¶
Base class for every warning Deepwave raises about a call’s behaviour.
One subclass per cause, never one per propagator or per message: the category is what a user filters on, so it has to name the thing they would decide about. Every warning raised under one of these categories names its class in its own text, so the one-line recipe for silencing it is in the message itself. Deepwave also still emits some plain
UserWarningmessages that predate this hierarchy and are not classified under it (the grid-cells-per-wavelength advice, thepml_freq-above-Nyquist warning, and the storage/auxiliary-state notices); those name no category, and are filtered asUserWarning.Filtering the base covers this class and its subclasses:
warnings.filterwarnings("ignore", category=deepwave.DeepwaveWarning)
It subclasses
UserWarning, so a filter that already targetsUserWarningalso covers it.DeepwaveFutureWarningis deliberately outside this hierarchy: a deprecated spelling is a message about the code that was written, not about the physics it asks for.
- exception deepwave.ZeroWidthFaceWarning(*args)¶
A
"pml"face of zero width, which reflects instead of absorbing.A
"pml"face whosepml_widthis zero absorbs nothing. It is a reflecting boundary whose exact condition depends on the propagator (see Boundary conditions), and it is reached identically whetherboundarywas omitted, given as the single string"pml", or given per face – those three spellings are the same call, so they warn the same way.Silence it with one line:
warnings.filterwarnings( "ignore", category=deepwave.ZeroWidthFaceWarning )
The warning is about a silent choice, not an error: the call runs, and naming the condition you meant with
boundary=is the fix.
- exception deepwave.MigrationWarning(*args)¶
A call whose numbers changed from what an older Deepwave computed.
Nothing about the call is wrong: the same arguments now mean something better than they used to. The warning exists so that a difference against an older run is explained rather than discovered. Where one line restores the previous behaviour exactly, the message names it; where no argument can, the message says so and names what the difference is confined to instead.
Silence it with one line:
warnings.filterwarnings( "ignore", category=deepwave.MigrationWarning )
- exception deepwave.PmlFreqInferenceWarning(*args)¶
pml_freqwas inferred, and differs from the old fixed default.Deepwave 0.0.27 used a fixed
pml_freqof 25.0 whenever the argument was omitted; it is now inferred from the source amplitudes. An inference of exactly 25.0 computes what that release computed and says nothing; this is the narrower category for every other inferred value, each of which gives a different absorbing boundary from that release. It is a migration aid, and is removed in Deepwave 0.4.0.Silence it with one line:
warnings.filterwarnings( "ignore", category=deepwave.PmlFreqInferenceWarning )
Passing
pml_freqexplicitly silences it too, and is the better fix: it makes the call say what it means.