Misc

Contents

Misc#

Visualization#

Visualization#

class pystopt.visualization.VisualizerBase(conn: DiscretizationConnection)[source]#

Bases: object

Encapsulated visualization methods.

ext#

Default extension used by the visualizer.

conn#

A DiscretizationConnection between the incoming data and the data to be outputted.

from_discr#

Original discretization on which the incoming data lives on.

to_discr#

Output visualization discretization, i.e. all incoming data is first projected on this discretization before writing.

write_file(basename: str | bytes | PathLike[str] | IOBase, names_and_fields: Sequence[Tuple[str, Any]], *, overwrite: bool = True, **unused_kwargs: Any) None[source]#
Parameters:
  • basename – basename of the file to be written. The exact extension is chosen by the visualizer.

  • names_and_fields – a list of tuples (name, field), where field is an Array or a numpy.ndarray of Array, representing scalar or vector fields on from_discr.

  • overwrite – flag to overwrite existing files.

  • kwargs – additional supported arguments.

pystopt.visualization.make_visualizer(actx: ArrayContext, discr: Discretization, vis_order: int | None = None, vis_type: str | None = None, **kwargs: Any) VisualizerBase[source]#

Simple interface for visualization. In most cases, the following will do the expected

vis = make_visualizer(actx, discr, vis_order=order)
vis.write_file(basename, [
    ("velocity", u),
    ("pressure", p),
    ("vorticity", omega)
], overwrite=True)

where u and omega are an object arrays (see pytools.obj_array) and p is a scalar.

Currently supported visualizers (selected using vis_type) are

  • "vtkxml": writes XML VTK files with first-order elements.

  • "vtkxml_lagrange": writes XML VTK files with high-order Lagrange elements.

  • "vtkhdf": writes HDF5 VTK files with first-order elements.

  • "vtkhdf_lagrange": writes HDF5 VTK files with high-order Lagrange elements.

  • "matplotlib": writes binary (e.g. PNG) files using matplotlib. Only available in 2D.

Parameters:
  • actx – a ArrayContext.

  • discr – a Discretization.

  • vis_order – resampling for output, e.g. can give a lower order than the one discr was constructed with to cut down on the number of DOFs.

  • vis_type – force selection of one of the visualizers.

Returns:

an appropriate VisualizerBase that depends on the provided discr.

pystopt.visualization.make_same_connectivity_visualizer(actx: ArrayContext, vis: VisualizerBase, discr: Discretization, *, skip_tests: bool = False) VisualizerBase[source]#
Parameters:
  • vis – an existing VisualizerBase.

  • discr – a new Discretization with the same connectivity as from_discr.

  • skip_tests – If True, no checks are performed that the two discretization actually have the same connectivity.

Returns:

a visualizer of the same type as the input with the base discretization exchanged for discr.

Checkpointing#

class pystopt.checkpoint.Checkpoint[source]#
close()[source]#

Close or otherwise finalize the checkpoint class.

After this method is called, the checkpoint should not be able to read or write. By default, it does nothing.

write(key: Hashable, obj: Any, *, overwrite: bool = False) None[source]#
Parameters:
  • key – a key that is interpretable by the writer. For example, this can be a suffix for a filename, if each object is written in a different file, or a key in a dictionary if the checkpoint is kept in memory.

  • overwrite – if True, existing data with the same key should be overwritten.

read(key: Hashable) Any[source]#
Parameters:

key – a string key interpretable by the reader, which should match the choice in write().

class pystopt.checkpoint.OnDiskCheckpoint[source]#

Bases: Checkpoint

property filename: Path#

File name in which the current checkpoint is stored.

property root: Path#

Root directory for all the checkpoints.

class pystopt.checkpoint.CheckpointManager(rw: Checkpoint)[source]#

A generic manager for writing and reading checkpoint-like data.

Specific implementations should be used as a context manager, i.e.,

with MyCheckpointManager(rw) as chk:
    chk.write_to("checkpoint0", {"data"})

    # do some things

    chk.write("checkpoint0", {"more_data"})

where read and writes should not be used inside the same context.

rw: Checkpoint#

A Checkpoint instance used to read_from() and write_to().

done()[source]#

Method to call to finalize the checkpoint writing.

write_to(key: Hashable, obj: Any, *, overwrite: bool = False) None[source]#

Write an object to the checkpoint (see Checkpoint.write()).

read_from(key: Hashable) Any | None[source]#

Read an object from the checkpoint (see Checkpoint.read()).

class pystopt.checkpoint.CheckpointManagerWithKeys(rw: Checkpoint)[source]#

Bases: CheckpointManager

A version of CheckpointManager that generates its own unique keys.

property prev_key: Hashable#

The previously used key during a read or write.

property next_key: Hashable#

The key that would be used in the next call to read() or write().

skip() bool[source]#

Skips the current key.

Returns:

True if the skipped key is actually in the checkpoint, False otherwise.

write(obj: Any, *, overwrite: bool = False) None[source]#

Write the given data to the next unique key.

Parameters:
read() Any | None[source]#

Read the data from the next unique key.

Returns:

the stored checkpoint, if any.

class pystopt.checkpoint.IteratorCheckpointManager(rw: Checkpoint, pattern: str = 'Checkpoint{i:09d}')[source]#

Bases: CheckpointManagerWithKeys

A checkpoint helper that just increments a given iterator on each write.

__init__(rw: Checkpoint, pattern: str = 'Checkpoint{i:09d}') None#
pattern: str = 'Checkpoint{i:09d}'#

A str.format() pattern for checkpoint names that takes the variable i as a counter for the number of calls to write() or read().

property prev_key#

The previously used key during a read or write.

property next_key#

The key that would be used in the next call to read() or write().

done()[source]#

Should be called to finalize the checkpointing and write the final state. This information is used to reset the iterator in advance().

reset(pattern: str | None = None) None[source]#

Resets the iterator to its original state.

advance(ncalls: int | None = None) None[source]#

Advance the iterator to the given number of calls. If the number is not given, it can be determined:

  • from metadata saved by the checkpoint on a previous run, see done().

  • by iterating over the keys with the current pattern until a key is found that is not yet in the checkpoint.

skip() bool[source]#

Advances the pattern without reading or writing.

Returns:

True if the next key is already in the checkpoint. If it is not, the iterator is advanced and False is returned.

write(obj: Any, *, overwrite: bool = False) None[source]#

Write the given data to the next unique key.

Parameters:
read() Any | None[source]#

Read the data from the next unique key.

Returns:

the stored checkpoint, if any.

class pystopt.checkpoint.OnDiskIteratorCheckpointManager(rw: Checkpoint, pattern: str = 'Checkpoint{i:09d}')[source]#

Bases: IteratorCheckpointManager

class pystopt.checkpoint.InMemoryCheckpoint(is_open: bool = True)[source]#

Bases: Checkpoint

pystopt.checkpoint.make_memory_checkpoint_manager() IteratorCheckpointManager[source]#
class pystopt.checkpoint.H5Checkpoint(h5root: Any, owned: bool)[source]#

Bases: OnDiskCheckpoint

A reader and writer for HDF5 checkpoints.

pystopt.checkpoint.make_hdf_checkpoint(filename_or_h5, *, mode: str = 'a', h5_file_options: Dict[str, Any] | None = None, h5_dset_options: Dict[str, Any] | None = None) H5Checkpoint[source]#
Parameters:
  • filename_or_h5 – can be a filename or an h5py object, like a file or a group.

  • h5_file_options – used to open an h5py.File if filename_or_h5 is a file name.

  • h5_dset_options – used when creating new datasets, see h5pyckle.PickleGroup.h5_dset_options.

pystopt.checkpoint.make_hdf_checkpoint_manager(filename_or_h5, *, mode: str = 'a', h5_file_options: Dict[str, Any] | None = None, h5_dset_options: Dict[str, Any] | None = None) OnDiskIteratorCheckpointManager[source]#

Paths#

class pystopt.paths.PathLike#

Type alias to be for file names.

class pystopt.paths.FileParts(stem: str, ext: str | None, suffix: str | None, index: str | None, cwd: Path | None)[source]#

Bases: object

Constructs filenames of the form:

[cwd]/[stem]_[suffix]_[index].[ext]
with_suffix(suffix: str) PathLike[source]#
Returns:

a pathlib.Path with the given suffix.

aspath() PathLike[source]#
pystopt.paths.get_dirname(stem: str, *, today: bool | str = True, cwd: PathLike | None = None) Path[source]#

Create canonical directory names of the form:

[cwd]/[date]_[stem]

The resulting directory name is then slugified to ensure only ascii alphanumeric characters are present.

Parameters:

today – if True, use the current date %Y-%m-%d as the prefix.

Returns:

absolute path to the directory.

pystopt.paths.make_dirname(stem: str, *, today: bool | str = True, cwd: PathLike | None = None) Path[source]#

Same as get_dirname(), but also ensures the directory exists.

pystopt.paths.get_filename(stem: str, *, suffix: str | None = None, cwd: PathLike | None = None, ext: str | None = None) FileParts[source]#

Create a canonically named file of the form:

[dirname]/[stem]_[suffix].[ext]

The resulting file name is then slugified to ensure only ascii alphanumeric characters are present.

pystopt.paths.generate_filename_series(stem: str, *, suffix: str | None = None, cwd: str | bytes | PathLike[str] | IOBase | None = None, ext: str | None = None, start: int = 0, idxfmt: str | None = None) Iterator[FileParts][source]#

Create a set of canonically named file names of the form:

[cwd]/[stem]_[suffix]_[NNNNN].[ext]

This is a generator that can be used as

filenames = generate_filename_series("series", ext=".out")
for i in range(10):
    filename = next(filenames)
    with open(filename.aspath(), "w") as f:
        f.write(str(i))
Parameters:
  • start – starting index for the series.

  • idxfmt – format string for the series index, by default set to {:09d}.

Returns:

a generator for filenames.

Timers and Measuring#

Measuring#

exception pystopt.measure.IncorrectConvergenceOrderError(msg: str, p_est: float, max_error: float)[source]#

Bases: ValueError

p_est: float#

Estimated order of convergence that was not satisfied.

max_error: float#

Maximum error throughout the history.

class pystopt.measure.EOCRecorder(*, name: str = 'Error', expected_order: float | None = None)[source]#

Bases pytools.convergence.EOCRecorder.

name: str#

An identifier for the error being computed.

expected_order: float | None#

Expected order of convergence of the errors.

add_data_point(abscissa: float, error: float) None[source]#
order_estimate() float[source]#
max_error() float[source]#
pystopt.measure.verify_eoc(eoc: EOCRecorder, expected_order: float | None = None, *, window: float = 0.25, atol: float = 1e-14, strict: bool = False) None[source]#

Checks that the order of convergence matches an expected value.

The order estimate \(p_{est}\) is satisfied if

\[p - w < p_{est} < p + w\]

where \(p\) is the expected order and \(w\) is a given window. The error estimate is satisfied if

\[\max e_i < atol\]
Parameters:

strict – If True, \(p_{est}\) is bounded on both sides (as above). Otherwise, just the lower bound is checked, which allows for an order of convergence much better than the expected one.

Raises:

IncorrectConvergenceOrderError – if the estimated order of convergence is not within the margins of expected_order or the maximum error is larger than atol.

pystopt.measure.stringify_eoc(*eocs: EOCRecorder, table_format: str = 'unicode', abscissa_name: str = 'h', abscissa_format: str | None = None, error_format: str | None = None, eoc_format: str | None = None)[source]#
Parameters:
  • table_format – a string defining the table format. Can be one of ["markdown", "latex", "unicode"].

  • abscissa_formatstr.format() compatible formatting string.

  • error_formatstr.format() compatible formatting string.

  • eoc_formatstr.format() compatible formatting string.

pystopt.measure.visualize_eoc(fig_or_filename: PathLike, *eocs: EOCRecorder, order: float | None = None, abscissa: str = 'h', ylabel: str = 'Error', enable_legend: bool = True, overwrite: bool = False) None[source]#
Parameters:
  • fig_or_filename – output file name or an existing figure.

  • order – expected order for all the errors recorded in eocs.

  • abscissa – name for the abscissa.

class pystopt.measure.TimeResult(walltime: float, mean: float, std: float)[source]#
walltime: float#

Smallest value of the walltime for all the runs.

mean: float#

Mean value for the walltime.

std: float#

Standard deviation for the walltime.

pystopt.measure.timeit(stmt: str | Callable[[], Any], *, setup: str | Callable[[], Any] = 'pass', repeat: int = 16, number: int = 1) TimeResult[source]#

Run stmt using timeit.repeat().

Returns:

a TimeResult with statistics about the runs.

class pystopt.measure.TicTocTimer[source]#

A simple tic-toc-like timer with support for various statistics.

The intended use of this timer is in some looping code where we want to keep track of the iteration time. For example

timer = TicTocTimer()
for i in range(maxit):
    timer.tic()
    # ... loads of heavy work ...
    timer.toc()
    print(f"elapsed: {timer}")

print(timer.stats())
tic() None[source]#

Clear previous values and start the timer.

toc() None[source]#

Stop the timer and store elapsed values since last call to tic().

At this point, the history of the timer is also updated.

stats() TimeResult[source]#
Returns:

an instance of TimeResult with statistics from all the calls to tic() and toc().

__str__() str[source]#

Stringify the latest elapsed time from toc().

If called outside a tic()-toc() pair, an empty string is returned instead.

pystopt.measure.format_seconds(s: float, *, days: bool = False) str[source]#

Format (fractional) seconds to a nicer format %Hh%Mm%Ss.

Parameters:
  • s – an elapsed time in (fractional) seconds, as obtained from, e.g., time.perf_counter().

  • days – if True, days are listed separately, instead of being added to hours.

pystopt.measure.estimate_wall_time_from_timestep(timer: TicTocTimer, dt: float | None, n: int | None, t: float | None, maxit: int | None, tmax: float | None, nhistory: int | None = 5) Tuple[float, float | None][source]#

Estimate total time of an iteration based on a timer.

This function is meant to be used for time advancing simulations. Then, if we know the current iteration n and the maximum number of iterations maxit, we can use the history of the timer to estimate the remaining wall time.

If tmax is given instead of maxit, we can simply compute:

remaining_steps = int((tmax - t) / dt)
Parameters:
  • dt – time step used in the iteration.

  • n – current iteration count.

  • t – current time in the iteration.

  • maxit – maximum number of iterations.

  • tmax – maximum time of the iteration.

  • nhistory – number of items in the history of the timer to use in estimating the real time per iteration.

pystopt.measure.estimate_wall_time_from_iteration(timer: TicTocTimer, n: int, maxit: int)[source]#

Simplified version of estimate_wall_time_from_timestep() for the case where we know the iteration counts.

DOFArray Additions#

Functions taking DOFArray that extend the functionality present in meshmode.

class pystopt.dof_array.DOFArrayT#
class pystopt.dof_array.SpectralDOFArray(*args: Any, **kwargs: Any)#

Bases: DOFArray

A DOFArray that contains spectral coefficients.

pystopt.dof_array.uniform_like(actx: ArrayContext, ary: ArrayOrContainerT, *, a: float = 0.0, b: float = 1.0, seed: int | None = None, rng: Generator | None = None) ArrayOrContainerT[source]#
pystopt.dof_array.dof_array_norm(ary: ArrayOrContainer, ord: float | None = None) Any[source]#
Parameters:

ary – a DOFArray or an object array of such.

pystopt.dof_array.dof_array_rnorm(x: ArrayOrContainerT, y: ArrayOrContainerT, ord: float | None = None) Any[source]#

Relative norm of the given order.

Callbacks#

class pystopt.callbacks.OutputType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]#

Bases: IntFlag

CHECKPOINT = 1#

Set if the output field should be checkpointed.

VISUALIZED = 2#

Set if the output field should be visualized.

GENERIC = 3#

Set if the output field should be both checkpointed and visualized.

class pystopt.callbacks.OutputField(label: str, value: ~typing.Any, flag: ~pystopt.callbacks.OutputType = <OutputType.GENERIC: 3>)[source]#

Bases: object

label#

A name for the field that is used in the output, e.g. as the key name in checkpointing or dataset name in visualization.

value#
flag#

A OutputType denoting the type of the output field.

class pystopt.callbacks.OutputFieldCallable(*args, **kwargs)[source]#

Bases: Protocol

__call__(state: Any, **kwargs: Any) Dict[str, OutputField][source]#

Call self as a function.

class pystopt.callbacks.OutputFieldVisualizeCallable(*args, **kwargs)[source]#

Bases: Protocol

__call__(vis: VisualizeCallback, basename: FileParts, state: Any, fields: Dict[str, OutputField], **kwargs: Any) None[source]#

Call self as a function.

class pystopt.callbacks.CallbackCallable(norm: Callable[[Any], float] | None)[source]#

Bases: object

Generic callable base class for callbacks.

norm#

A Callable that computes the norm of an array or array container.

restart_from_iteration(n: int) None[source]#

For callbacks that keep an internal state based on the iteration count, this function should return them to the iteration n.

__call__(*args: Any, **kwargs: Any) int[source]#
Returns:

1 if no error was encountered and 0 otherwise.

class pystopt.callbacks.CallbackManager(stop_file_name: ~pathlib.Path | None = None, callbacks: ~typing.Dict[str, ~pystopt.callbacks.CallbackCallable] = <factory>, short_circuit: bool = False, _force_gc: bool = True)[source]#

Bases: object

A wrapper for various callbacks used during an iterative process.

The main function of this wrapper is to call all the callbacks in callbacks and handle their return values. Any callback can request a termination of the iteration by returning \(0\). Besides that, two other methods are provided to stop the iteration externally:

  • sending the signal SIGUSR1 to the process.

  • creating the file stop_file_name.

Note that all the termination conditions are checked and all the callbacks are called, i.e. they are not shortcircuited once one is found to return \(0\).

stop_file_name#

The name of a file that, when it is found to exist, the iteration should be stopped.

short_circuit#

If True, the return values from the callbacks are shortcircuited. This means that, if a callback returns \(0\), no subsequent callback will be called. The stop_file_name and signal are checked first.

callbacks#

Additional user provided callbacks.

restart_from_iteration(ncalls: int) None[source]#
__call__(*args: Any, **kwargs: Any) int[source]#

Calls all the callbacks in callbacks and aggregates their return values.

In addition to the input arguments, the manager also inserts the keyword ncalls, with the number of calls to this class.

Returns:

\(0\) to stop the optimization and another integer otherwise.

class pystopt.callbacks.LogCallback(norm: Callable[[Any], float] | None, log: Callable[[...], Any] | None)[source]#

Bases: CallbackCallable

log#

User-provided logging function that takes the same arguments as logging.Logger.info() and friends using the old school percent-based syntax for string formatting.

class pystopt.callbacks.OptimizationLogCallback(norm: Callable[[Any], float] | None, log: Callable[..., Any] | None)[source]#

Bases: LogCallback

class pystopt.callbacks.HistoryCallback(norm: Callable[[Any], float] | None)[source]#

Bases: CallbackCallable

A callable that collects history for various variables.

All fields should be lists or support the append method.

to_numpy() Dict[str, ndarray][source]#
Returns:

a dict with the history as numpy.ndarrays.

from_numpy(history: Dict[str, ndarray]) None[source]#

Takes the output of to_numpy() and appends it to the current histories in the callback.

class pystopt.callbacks.PerformanceHistoryCallback(norm: ~typing.Callable[[~typing.Any], float] | None, memory: ~typing.List[int] = <factory>, timestamp: ~typing.List[int] = <factory>)[source]#

Bases: HistoryCallback

Gather basic performance data using psutil.

memory#

Memory used at the time of calling in Mib.

timestamp#

Process time at the time of calling.

class pystopt.callbacks.OptimizationHistoryCallback(norm: ~typing.Callable[[~typing.Any], float] | None, memory: ~typing.List[int] = <factory>, timestamp: ~typing.List[int] = <factory>, f: ~typing.List[float] = <factory>, g: ~typing.List[float] = <factory>, d: ~typing.List[float] = <factory>, alpha: ~typing.List[float] = <factory>)[source]#

Bases: PerformanceHistoryCallback

f#

Cost functional values at each iteration.

g#

Norm of the cost gradient at each iteration, computed using norm.

d#

Norm of the descent direction used in the gradient descent algorithm, computed using norm. This is not the same as g if, e.g., a nonlinear conjugate gradient method is used.

alpha#

Gradient descent step size at each iteration.

class pystopt.callbacks.CheckpointCallback(norm: Callable[[Any], float] | None, checkpoint: IteratorCheckpointManager, overwrite: bool = False)[source]#

Bases: CallbackCallable

class pystopt.callbacks.VisualizeCallback(norm: Callable[[Any], float] | None, visualize_file_series: Iterator[FileParts], overwrite: bool = False, frequency: int = 1)[source]#

Bases: CallbackCallable

ambient_dim#
from_discr#
write_file(*args, **kwargs) None[source]#
get_file_writers() Tuple[OutputFieldVisualizeCallable, ...][source]#
Returns:

a tuple of callables used to do the actual writing. Subclasses should customize this for their needs.

__call__(*args: Any, **kwargs: Any) int[source]#
Returns:

1 if no error was encountered and 0 otherwise.