pyop2 package

Submodules

pyop2.backends module

OP2 backend configuration and auxiliaries.

Warning

User code should usually set the backend via pyop2.op2.init()

pyop2.backends.get_backend()

Get the OP2 backend

pyop2.backends.set_backend(backend)

Set the OP2 backend

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

pyop2.backends.unset_backend()

Unset the OP2 backend

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

pyop2.base module

Base classes for OP2 objects, containing metadata and runtime data information which is backend independent. Individual runtime backends should subclass these as required to implement backend-specific features.

class pyop2.base.LazyComputation(reads, writes)

Bases: object

Helper class holding computation to be carried later on.

enqueue()
class pyop2.base.ExecutionTrace

Bases: object

Container maintaining delayed computation until they are executed.

append(computation)
in_queue(computation)
clear()

Forcefully drops delayed computation. Only use this if you know what you are doing.

evaluate_all()

Forces the evaluation of all delayed computations.

evaluate(reads=None, writes=None)

Force the evaluation of delayed computation on which reads and writes depend.

Parameters:
  • reads – the DataCarriers which you wish to read from. This forces evaluation of all par_loop()s that write to the DataCarrier (and any other dependent computation).
  • writes – the DataCarriers which you will write to (i.e. modify values). This forces evaluation of all par_loop()s that read from the DataCarrier (and any other dependent computation).
class pyop2.base.Access(mode)

Bases: object

OP2 access type. In an Arg, this describes how the DataCarrier will be accessed.

Warning

Access should not be instantiated by user code. Instead, use the predefined values: READ, WRITE, RW, INC, MIN, MAX

pyop2.base.READ = Access('READ')

The Global, Dat, or Mat is accessed read-only.

pyop2.base.WRITE = Access('WRITE')

The Global, Dat, or Mat is accessed write-only, and OP2 is not required to handle write conflicts.

pyop2.base.RW = Access('RW')

The Global, Dat, or Mat is accessed for reading and writing, and OP2 is not required to handle write conflicts.

pyop2.base.INC = Access('INC')

The kernel computes increments to be summed onto a Global, Dat, or Mat. OP2 is responsible for managing the write conflicts caused.

pyop2.base.MIN = Access('MIN')

The kernel contributes to a reduction into a Global using a min operation. OP2 is responsible for reducing over the different kernel invocations.

pyop2.base.MAX = Access('MAX')

The kernel contributes to a reduction into a Global using a max operation. OP2 is responsible for reducing over the different kernel invocations.

class pyop2.base.Arg(data=None, map=None, idx=None, access=None, flatten=False)

Bases: object

An argument to a pyop2.op2.par_loop().

Warning

User code should not directly instantiate Arg. Instead, use the call syntax on the DataCarrier.

Parameters:
  • data – A data-carrying object, either Dat or class:Mat
  • map – A Map to access this Arg or the default if the identity map is to be used.
  • idx – An index into the Map: an IterationIndex when using an iteration space, an int to use a given component of the mapping or the default to use all components of the mapping.
  • access – An access descriptor of type Access
  • flatten – Treat the data dimensions of this Arg as flat s.t. the kernel is passed a flat vector of length map.arity * data.dataset.cdim.

Checks that:

  1. the maps used are initialized i.e. have mapping data associated, and
  2. the to Set of the map used to access it matches the Set it is defined on.

A MapValueError is raised if these conditions are not met.

split

Split a mixed argument into a tuple of constituent arguments.

name

The generated argument name.

position

The position of this Arg in the ParLoop argument list

indirect_position

The position of the first unique occurence of this indirect Arg in the ParLoop argument list.

ctype

String representing the C type of the data in this Arg.

dtype

Numpy datatype of this Arg

map

The Map via which the data is to be accessed.

idx

Index into the mapping.

access

Access descriptor. One of the constants of type Access

halo_exchange_begin()

Begin halo exchange for the argument if a halo update is required. Doing halo exchanges only makes sense for Dat objects.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

halo_exchange_end()

End halo exchange if it is in flight. Doing halo exchanges only makes sense for Dat objects.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

reduction_begin()

Begin reduction for the argument if its access is INC, MIN, or MAX. Doing a reduction only makes sense for Global objects.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

reduction_end()

End reduction for the argument if it is in flight. Doing a reduction only makes sense for Global objects.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

data

Data carrier of this argument: Dat, Mat, Const or Global.

class pyop2.base.Set(size=None, name=None, halo=None)

Bases: object

OP2 set.

Parameters:
  • size (integer or list of four integers.) – The size of the set.
  • dim (integer or tuple of integers) – The shape of the data associated with each element of this Set.
  • name (string) – The name of the set (optional).
  • halo – An exisiting halo to use (optional).

When the set is employed as an iteration space in a pyop2.op2.par_loop(), the extent of any local iteration space within each set entry is indicated in brackets. See the example in pyop2.op2.par_loop() for more details.

The size of the set can either be an integer, or a list of four integers. The latter case is used for running in parallel where we distinguish between:

  • CORE (owned and not touching halo)
  • OWNED (owned, touching halo)
  • EXECUTE HALO (not owned, but executed over redundantly)
  • NON EXECUTE HALO (not owned, read when executing in the execute halo)

If a single integer is passed, we assume that we’re running in serial and there is no distinction.

The division of set elements is:

[0, CORE)
[CORE, OWNED)
[OWNED, EXECUTE HALO)
[EXECUTE HALO, NON EXECUTE HALO).

Halo send/receive data is stored on sets in a Halo.

core_size

Core set size. Owned elements not touching halo elements.

size

Set size, owned elements.

exec_size

Set size including execute halo elements.

If a ParLoop is indirect, we do redundant computation by executing over these set elements as well as owned ones.

total_size

Total set size, including halo elements.

sizes

Set sizes: core, owned, execute halo, total.

name

User-defined label

halo

Halo associated with this Set

partition_size

Default partition size

layers

Return None (not an ExtrudedSet).

classmethod fromhdf5(f, name)

Construct a Set from set named name in HDF5 data f

core_part
owned_part
exec_part
all_part
class pyop2.base.ExtrudedSet(parent, layers)

Bases: pyop2.base.Set

OP2 ExtrudedSet.

Parameters:

The number of layers indicates the number of time the base set is extruded in the direction of the ExtrudedSet. As a result, there are layers-1 extruded “cells” in an extruded set.

parent
layers

The number of layers in this extruded set.

class pyop2.base.Subset(superset, indices)

Bases: pyop2.base.ExtrudedSet

OP2 subset.

Parameters:
  • superset (a Set or a Subset.) – The superset of the subset.
  • indices (a list of integers, or a numpy array.) – Elements of the superset that form the subset. Duplicate values are removed when constructing the subset.
superset

Returns the superset Set

indices

Returns the indices pointing in the superset.

class pyop2.base.SetPartition(set, offset, size)

Bases: object

class pyop2.base.MixedSet(sets)

Bases: pyop2.base.Set, pyop2.caching.ObjectCached

A container for a bag of Sets.

Parameters:sets (iterable) – Iterable of Sets or ExtrudedSets
split

The underlying tuple of Sets.

core_size

Core set size. Owned elements not touching halo elements.

size

Set size, owned elements.

exec_size

Set size including execute halo elements.

total_size

Total set size, including halo elements.

sizes

Set sizes: core, owned, execute halo, total.

name

User-defined labels.

halo

Halos associated with these Sets.

layers

Numbers of layers in the extruded mesh (or None if this MixedSet is not extruded).

class pyop2.base.DataSet(iter_set, dim=1, name=None)

Bases: pyop2.caching.ObjectCached

PyOP2 Data Set

Set used in the op2.Dat structures to specify the dimension of the data.

dim

The shape tuple of the values for each element of the set.

cdim

The scalar number of values for each member of the set. This is the product of the dim tuple.

name

Returns the name of the data set.

set

Returns the parent set of the data set.

class pyop2.base.MixedDataSet(arg, dims=None)

Bases: pyop2.base.DataSet, pyop2.caching.ObjectCached

A container for a bag of DataSets.

Initialized either from a MixedSet and an iterable or iterator of dims of corresponding length

mdset = op2.MixedDataSet(mset, [dim1, ..., dimN])

or from a tuple of Sets and an iterable of dims of corresponding length

mdset = op2.MixedDataSet([set1, ..., setN], [dim1, ..., dimN])

If all dims are to be the same, they can also be given as an int for either of above invocations

mdset = op2.MixedDataSet(mset, dim)
mdset = op2.MixedDataSet([set1, ..., setN], dim)

Initialized from a MixedSet without explicitly specifying dims they default to 1

mdset = op2.MixedDataSet(mset)

Initialized from an iterable or iterator of DataSets and/or Sets, where Sets are implicitly upcast to DataSets of dim 1

mdset = op2.MixedDataSet([dset1, ..., dsetN])
Parameters:
  • arg – a MixedSet or an iterable or a generator expression of Sets or DataSets or a mixture of both
  • dimsNone (the default) or an int or an iterable or generator expression of ints, which must be of same length as arg

Warning

When using generator expressions for arg or dims, these must terminate or else will cause an infinite loop.

split

The underlying tuple of DataSets.

dim

The shape tuple of the values for each element of the sets.

cdim

The sum of the scalar number of values for each member of the sets. This is the sum of products of the dim tuples.

name

Returns the name of the data sets.

set

Returns the MixedSet this MixedDataSet is defined on.

class pyop2.base.Halo(sends, receives, comm=None, gnn2unn=None)

Bases: object

A description of a halo associated with a Set.

The halo object describes which Set elements are sent where, and which Set elements are received from where.

The sends should be a dict whose key is the process we want to send to, similarly the receives should be a dict whose key is the process we want to receive from. The value should in each case be a numpy array of the set elements to send to/receive from each process.

The gnn2unn array is a map from process-local set element numbering to cross-process set element numbering. It must correctly number all the set elements in the halo region as well as owned elements. Providing this array is only necessary if you will access Mat objects on the Set this Halo lives on. Insertion into Dats always uses process-local numbering, however insertion into Mats uses cross-process numbering under the hood.

sends

Return the sends associated with this Halo.

A dict of numpy arrays, keyed by the rank to send to, with each array indicating the Set elements to send.

For example, to send no elements to rank 0, elements 1 and 2 to rank 1 and no elements to rank 2 (with comm.size == 3) we would have:

{1: np.array([1,2], dtype=np.int32)}.
receives

Return the receives associated with this Halo.

A dict of numpy arrays, keyed by the rank to receive from, with each array indicating the Set elements to receive.

See Halo.sends() for an example.

global_to_petsc_numbering

The mapping from global (per-process) dof numbering to petsc (cross-process) dof numbering.

comm

The MPI communicator this Halo‘s communications should take place over

verify(s)

Verify that this Halo is valid for a given Set.

class pyop2.base.IterationSpace(iterset, block_shape=None)

Bases: object

OP2 iteration space type.

Warning

User code should not directly instantiate IterationSpace. This class is only for internal use inside a pyop2.op2.par_loop().

iterset

The Set over which this IterationSpace is defined.

extents

Extents of the IterationSpace within each item of iterset

name

The name of the Set over which this IterationSpace is defined.

core_size

The number of Set elements which don’t touch halo elements in the set over which this IterationSpace is defined

size

The size of the Set over which this IterationSpace is defined.

exec_size

The size of the Set over which this IterationSpace is defined, including halo elements to be executed over

layers

Number of layers in the extruded set (or None if this is not an extruded iteration space)

partition_size

Default partition size

total_size

The total size of Set over which this IterationSpace is defined.

This includes all halo set elements.

cache_key

Cache key used to uniquely identify the object in the cache.

class pyop2.base.DataCarrier

Bases: pyop2.versioning.Versioned

Abstract base class for OP2 data.

Actual objects will be DataCarrier objects of rank 0 (Const and Global), rank 1 (Dat), or rank 2 (Mat)

class Snapshot(obj)

Bases: object

A snapshot of the current state of the DataCarrier object. If is_valid() returns True, then the object hasn’t changed since this snapshot was taken (and still exists).

is_valid()
DataCarrier.create_snapshot()

Returns a snapshot of the current object. If not overriden, this method will return a full duplicate object.

DataCarrier.dtype

The Python type of the data.

DataCarrier.ctype

The c type of the data.

DataCarrier.name

User-defined label.

DataCarrier.dim

The shape tuple of the values for each element of the object.

DataCarrier.cdim

The scalar number of values for each member of the object. This is the product of the dim tuple.

class pyop2.base.SetAssociated

Bases: pyop2.base.DataCarrier

Intermediate class between DataCarrier and subtypes associated with a Set (vectors and matrices).

class Snapshot(obj)

Bases: object

A snapshot for SetAssociated objects is valid if the snapshot version is the same as the current version of the object

is_valid()
class pyop2.base.Dat(dataset, data=None, dtype=None, name=None, soa=None, uid=None)

Bases: pyop2.base.SetAssociated, pyop2.base._EmptyDataMixin, pyop2.versioning.CopyOnWrite

OP2 vector data. A Dat holds values on every element of a DataSet.

If a Set is passed as the dataset argument, rather than a DataSet, the Dat is created with a default DataSet dimension of 1.

If a Dat is passed as the dataset argument, a copy is returned.

It is permissible to pass None as the data argument. In this case, allocation of the data buffer is postponed until it is accessed.

Note

If the data buffer is not passed in, it is implicitly initialised to be zero.

When a Dat is passed to pyop2.op2.par_loop(), the map via which indirection occurs and the access descriptor are passed by calling the Dat. For instance, if a Dat named D is to be accessed for reading via a Map named M, this is accomplished by

D(pyop2.READ, M)

The Map through which indirection occurs can be indexed using the index notation described in the documentation for the Map. Direct access to a Dat is accomplished by omitting the path argument.

Dat objects support the pointwise linear algebra operations +=, *=, -=, /=, where *= and /= also support multiplication / division by a scalar.

split

Tuple containing only this Dat.

dataset

DataSet on which the Dat is defined.

dim

The shape of the values for each element of the object.

cdim

The scalar number of values for each member of the object. This is the product of the dim tuple.

soa

Are the data in SoA format?

data

Numpy array containing the data values.

With this accessor you are claiming that you will modify the values you get back. If you only need to look at the values, use data_ro() instead.

This only shows local values, to see the halo values too use data_with_halos().

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

data_with_halos

A view of this Dats data.

This accessor marks the Dat as dirty, see data() for more details on the semantics.

With this accessor, you get to see up to date halo values, but you should not try and modify them, because they will be overwritten by the next halo exchange.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

data_ro

Numpy array containing the data values. Read-only.

With this accessor you are not allowed to modify the values you get back. If you need to do so, use data() instead.

This only shows local values, to see the halo values too use data_ro_with_halos().

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

data_ro_with_halos

A view of this Dats data.

This accessor does not mark the Dat as dirty, and is a read only view, see data_ro() for more details on the semantics.

With this accessor, you get to see up to date halo values, but you should not try and modify them, because they will be overwritten by the next halo exchange.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

save(filename)

Write the data array to file filename in NumPy format.

load(filename)

Read the data stored in file filename into a NumPy array and store the values in _data().

shape
dtype
nbytes

Return an estimate of the size of the data associated with this Dat in bytes. This will be the correct size of the data payload, but does not take into account the (presumably small) overhead of the object and its metadata.

Note that this is the process local memory usage, not the sum over all MPI processes.

needs_halo_update

Has this Dat been written to since the last halo exchange?

zero()

Zero the data associated with this Dat

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

copy(other, subset=None)

Copy the data in this Dat into another.

Parameters:
  • other – The destination Dat
  • subset – A Subset of elements to copy (optional)

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

inner(other)

Compute the l2 inner product of the flattened Dat

Parameters:other – the other Dat to compute the inner product against.
norm

Compute the l2 norm of this Dat

Note

This acts on the flattened data (see also inner()).

halo_exchange_begin()

Begin halo exchange.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

halo_exchange_end()

End halo exchange. Waits on MPI recv.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

classmethod fromhdf5(dataset, f, name)

Construct a Dat from a Dat named name in HDF5 data f

class pyop2.base.MixedDat(mdset_or_dats)

Bases: pyop2.base.Dat

A container for a bag of Dats.

Initialized either from a MixedDataSet, a MixedSet, or an iterable of DataSets and/or Sets, where all the Sets are implcitly upcast to DataSets

mdat = op2.MixedDat(mdset)
mdat = op2.MixedDat([dset1, ..., dsetN])

or from an iterable of Dats

mdat = op2.MixedDat([dat1, ..., datN])
dtype

The NumPy dtype of the data.

split

The underlying tuple of Dats.

dataset

MixedDataSets this MixedDat is defined on.

soa

Are the data in SoA format?

data

Numpy arrays containing the data excluding halos.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

data_with_halos

Numpy arrays containing the data including halos.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

data_ro

Numpy arrays with read-only data excluding halos.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

data_ro_with_halos

Numpy arrays with read-only data including halos.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

needs_halo_update

Has this Dat been written to since the last halo exchange?

halo_exchange_begin()

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

halo_exchange_end()

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

zero()

Zero the data associated with this MixedDat.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

nbytes

Return an estimate of the size of the data associated with this MixedDat in bytes. This will be the correct size of the data payload, but does not take into account the (presumably small) overhead of the object and its metadata.

Note that this is the process local memory usage, not the sum over all MPI processes.

copy(other, subset=None)

Copy the data in this MixedDat into another.

Parameters:
  • other – The destination MixedDat
  • subset – Subsets are not supported, this must be None

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

inner(other)

Compute the l2 inner product.

Parameters:other – the other MixedDat to compute the inner product against
class pyop2.base.Const(dim, data=None, name=None, dtype=None)

Bases: pyop2.base.DataCarrier

Data that is constant for any element of any set.

class Snapshot(obj)

Bases: object

Overridden from DataCarrier; a snapshot is always valid as long as the Const object still exists

is_valid()
exception Const.NonUniqueNameError

Bases: exceptions.ValueError

The Names of const variables are required to be globally unique. This exception is raised if the name is already in use.

Const.duplicate()

A Const duplicate can always refer to the same data vector, since it’s read-only

Const.data

Data array.

Const.remove_from_namespace()

Remove this Const object from the namespace

This allows the same name to be redeclared with a different shape.

classmethod Const.fromhdf5(f, name)

Construct a Const from const named name in HDF5 data f

class pyop2.base.Global(dim, data=None, dtype=None, name=None)

Bases: pyop2.base.DataCarrier, pyop2.base._EmptyDataMixin

OP2 global value.

When a Global is passed to a pyop2.op2.par_loop(), the access descriptor is passed by calling the Global. For example, if a Global named G is to be accessed for reading, this is accomplished by:

G(pyop2.READ)

It is permissible to pass None as the data argument. In this case, allocation of the data buffer is postponed until it is accessed.

Note

If the data buffer is not passed in, it is implicitly initialised to be zero.

shape
dtype
data_ro

Data array.

data

Data array.

nbytes

Return an estimate of the size of the data associated with this Global in bytes. This will be the correct size of the data payload, but does not take into account the overhead of the object and its metadata. This renders this method of little statistical significance, however it is included to make the interface consistent.

soa

Are the data in SoA format? This is always false for Global objects.

duplicate()

Return a deep copy of self.

class pyop2.base.IterationIndex(index=None)

Bases: object

OP2 iteration space index

Users should not directly instantiate IterationIndex objects. Use op2.i instead.

index

Return the integer value of this index.

pyop2.base.i = IterationIndex(None)

Shorthand for constructing IterationIndex objects.

i[idx] builds an IterationIndex object for which the index property is idx.

class pyop2.base.Map(iterset, toset, arity, values=None, name=None, offset=None, parent=None, bt_masks=None)

Bases: object

OP2 map, a relation between two Set objects.

Each entry in the iterset maps to arity entries in the toset. When a map is used in a pyop2.op2.par_loop(), it is possible to use Python index notation to select an individual entry on the right hand side of this map. There are three possibilities:

  • No index. All arity Dat entries will be passed to the kernel.
  • An integer: some_map[n]. The n th entry of the map result will be passed to the kernel.
  • An IterationIndex, some_map[pyop2.i[n]]. n will take each value from 0 to e-1 where e is the n th extent passed to the iteration space for this pyop2.op2.par_loop(). See also i.

For extruded problems (where iterset is an ExtrudedSet) with boundary conditions applied at the top and bottom of the domain, one needs to provide a list of which of the arity values in each map entry correspond to values on the bottom boundary and which correspond to the top. This is done by supplying two lists of indices in bt_masks, the first provides indices for the bottom, the second for the top.

split
iteration_region

Return the iteration region for the current map. For a normal map it will always be ALL. For a DecoratedMap it will specify over which mesh region the iteration will take place.

implicit_bcs

Return any implicit (extruded “top” or “bottom”) bcs to apply to this Map. Normally empty except in the case of some DecoratedMaps.

iterset

Set mapped from.

toset

Set mapped to.

arity

Arity of the mapping: number of toset elements mapped to per iterset element.

arities

Arity of the mapping: number of toset elements mapped to per iterset element.

Return type:tuple
arange

Tuple of arity offsets for each constituent Map.

values

Mapping array.

This only returns the map values for local points, to see the halo points too, use values_with_halo().

values_with_halo

Mapping array.

This returns all map values (including halo points), see values() if you only need to look at the local points.

name

User-defined label

offset

The vertical offset.

top_mask

The top layer mask to be applied on a mesh cell.

bottom_mask

The bottom layer mask to be applied on a mesh cell.

classmethod fromhdf5(iterset, toset, f, name)

Construct a Map from set named name in HDF5 data f

class pyop2.base.DecoratedMap(map, iteration_region=None, implicit_bcs=None)

Bases: pyop2.base.Map, pyop2.caching.ObjectCached

Augmented type for a map used for attaching extra information used to inform code generation and/or sparsity building about the implicit structure of the extruded Map.

Parameters:
  • map – The original class:Map.
  • iteration_region – The class:IterationRegion of the mesh over which the parallel loop will iterate.
  • implicit_bcs – Any “top” or “bottom” boundary conditions to apply when assembling Mats.

The map parameter may be an existing DecoratedMap in which case, if either the iteration_region or implicit_bcs arguments are None, they will be copied over from the supplied map.

map

The Map this DecoratedMap is decorating

iteration_region

Returns the type of the iteration to be performed.

implicit_bcs

Return the set (if any) of implicit (“top” or “bottom”) bcs to be applied to the Map.

class pyop2.base.MixedMap(maps)

Bases: pyop2.base.Map, pyop2.caching.ObjectCached

A container for a bag of Maps.

Parameters:maps (iterable) – Iterable of Maps
split

The underlying tuple of Maps.

iterset

MixedSet mapped from.

toset

MixedSet mapped to.

arity

Arity of the mapping: total number of toset elements mapped to per iterset element.

arities

Arity of the mapping: number of toset elements mapped to per iterset element.

Return type:tuple
arange

Tuple of arity offsets for each constituent Map.

values

Mapping arrays excluding data for halos.

This only returns the map values for local points, to see the halo points too, use values_with_halo().

values_with_halo

Mapping arrays including data for halos.

This returns all map values (including halo points), see values() if you only need to look at the local points.

name

User-defined labels

offset

Vertical offsets.

class pyop2.base.Sparsity(dsets, maps, name=None)

Bases: pyop2.caching.ObjectCached

OP2 Sparsity, the non-zero structure a matrix derived from the union of the outer product of pairs of Map objects.

Examples of constructing a Sparsity:

Sparsity(single_dset, single_map, 'mass')
Sparsity((row_dset, col_dset), (single_rowmap, single_colmap))
Sparsity((row_dset, col_dset),
         [(first_rowmap, first_colmap), (second_rowmap, second_colmap)])
Parameters:
  • dsetsDataSets for the left and right function spaces this Sparsity maps between
  • maps (a pair of Maps specifying a row map and a column map, or an iterable of pairs of Maps specifying multiple row and column maps - if a single Map is passed, it is used as both a row map and a column map) – Maps to build the Sparsity from
  • name (string) – user-defined label (optional)
dsets

A pair of DataSets for the left and right function spaces this Sparsity maps between.

maps

A list of pairs (rmap, cmap) where each pair of Map objects will later be used to assemble into this matrix. The iterset of each of the maps in a pair must be the same, while the toset of all the maps which appear first must be common, this will form the row Set of the sparsity. Similarly, the toset of all the maps which appear second must be common and will form the column Set of the Sparsity.

cmaps

The list of column maps this sparsity is assembled from.

rmaps

The list of row maps this sparsity is assembled from.

dims

A pair giving the number of rows per entry of the row Set and the number of columns per entry of the column Set of the Sparsity.

shape

Number of block rows and columns.

nrows

The number of rows in the Sparsity.

ncols

The number of columns in the Sparsity.

name

A user-defined label.

rowptr

Row pointer array of CSR data structure.

colidx

Column indices array of CSR data structure.

nnz

Array containing the number of non-zeroes in the various rows of the diagonal portion of the local submatrix.

This is the same as the parameter d_nnz used for preallocation in PETSc’s MatMPIAIJSetPreallocation.

onnz

Array containing the number of non-zeroes in the various rows of the off-diagonal portion of the local submatrix.

This is the same as the parameter o_nnz used for preallocation in PETSc’s MatMPIAIJSetPreallocation.

nz

Number of non-zeroes in the diagonal portion of the local submatrix.

onz

Number of non-zeroes in the off-diagonal portion of the local submatrix.

class pyop2.base.Mat(sparsity, dtype=None, name=None)

Bases: pyop2.base.SetAssociated

OP2 matrix data. A Mat is defined on a sparsity pattern and holds a value for each element in the Sparsity.

When a Mat is passed to pyop2.op2.par_loop(), the maps via which indirection occurs for the row and column space, and the access descriptor are passed by calling the Mat. For instance, if a Mat named A is to be accessed for reading via a row Map named R and a column Map named C, this is accomplished by:

A(pyop2.READ, (R[pyop2.i[0]], C[pyop2.i[1]]))

Notice that it is always necessary to index the indirection maps for a Mat. See the Mat documentation for more details.

Note

After executing par_loop()s that write to a Mat and before using it (for example to view its values), you must call assemble() to finalise the writes.

assemble()

Finalise this Mat ready for use.

Call this /after/ executing all the par_loops that write to the matrix before you want to look at it.

dims

A pair of integers giving the number of matrix rows and columns for each member of the row Set and column Set respectively. This corresponds to the cdim member of a DataSet.

sparsity

Sparsity on which the Mat is defined.

values

A numpy array of matrix values.

Warning

This is a dense array, so will need a lot of memory. It’s probably not a good idea to access this property if your matrix has more than around 10000 degrees of freedom.

dtype

The Python type of the data.

nbytes

Return an estimate of the size of the data associated with this Mat in bytes. This will be the correct size of the data payload, but does not take into account the (presumably small) overhead of the object and its metadata. The memory associated with the sparsity pattern is also not recorded.

Note that this is the process local memory usage, not the sum over all MPI processes.

class pyop2.base.Kernel(code, name, opts={}, include_dirs=[], headers=[], user_code='')

Bases: pyop2.caching.Cached

OP2 kernel type.

Parameters:
  • code – kernel function definition, including signature; either a string or an AST Node
  • name – kernel function name; must match the name of the kernel function given in code
  • opts – options dictionary for PyOP2 IR optimisations (optional, ignored if code is a string)
  • include_dirs – list of additional include directories to be searched when compiling the kernel (optional, defaults to empty)
  • headers – list of system headers to include when compiling the kernel in the form #include <header.h> (optional, defaults to empty)
  • user_code – code snippet to be executed once at the very start of the generated kernel wrapper code (optional, defaults to empty)

Consider the case of initialising a Dat with seeded random values in the interval 0 to 1. The corresponding Kernel is constructed as follows:

op2.Kernel("void setrand(double *x) { x[0] = (double)random()/RAND_MAX); }",
           name="setrand",
           headers=["#include <stdlib.h>"], user_code="srandom(10001);")

Note

When running in parallel with MPI the generated code must be the same on all ranks.

name

Kernel name, must match the kernel function name in the code.

code

String containing the c code for this kernel routine. This code must conform to the OP2 user kernel API.

class pyop2.base.JITModule

Bases: pyop2.caching.Cached

Cached module encapsulating the generated ParLoop stub.

Warning

Note to implementors. This object is cached and therefore should not hold any references to objects you might want to be collected (such PyOP2 data objects).

class pyop2.base.IterationRegion(iterate)

Bases: object

Class that specifies the way to iterate over a column of extruded mesh elements. A column of elements refers to the elements which are in the extrusion direction. The accesses to these elements are direct.

where
pyop2.base.ON_BOTTOM = 'ON_BOTTOM'

Iterate over the cells at the bottom of the column in an extruded mesh.

pyop2.base.ON_TOP = 'ON_TOP'

Iterate over the top cells in an extruded mesh.

pyop2.base.ON_INTERIOR_FACETS = 'ON_INTERIOR_FACETS'

Iterate over the interior facets of an extruded mesh.

pyop2.base.ALL = 'ALL'

Iterate over all cells of an extruded mesh.

class pyop2.base.ParLoop(kernel, iterset, *args, **kwargs)

Bases: pyop2.base.LazyComputation

Represents the kernel, iteration space and arguments of a parallel loop invocation.

Note

Users should not directly construct ParLoop objects, but use pyop2.op2.par_loop() instead.

An optional keyword argument, iterate, can be used to specify which region of an ExtrudedSet the parallel loop should iterate over.

compute()

Executes the kernel over all members of the iteration space.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

maybe_set_dat_dirty()
halo_exchange_begin()

Start halo exchanges.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

halo_exchange_end()

Finish halo exchanges (wait on irecvs)

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

reduction_begin()

Start reductions

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

reduction_end()

End reductions

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

maybe_set_halo_update_needed()

Set halo update needed for Dat arguments that are written to in this parallel loop.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

build_itspace(iterset)

Checks that the iteration set of the ParLoop matches the iteration set of all its arguments. A MapValueError is raised if this condition is not met.

Also determines the size of the local iteration space and checks all arguments using an IterationIndex for consistency.

Returns:class:IterationSpace for this ParLoop
offset_args

The offset args that need to be added to the argument list.

layer_arg

The layer arg that needs to be added to the argument list.

it_space

Iteration space of the parallel loop.

is_direct

Is this parallel loop direct? I.e. are all the arguments either :class:Dats accessed through the identity map, or :class:Global?

is_indirect

Is the parallel loop indirect?

needs_exec_halo

Does the parallel loop need an exec halo?

kernel

Kernel executed by this parallel loop.

args

Arguments to this parallel loop.

is_layered

Flag which triggers extrusion

iteration_region

Specifies the part of the mesh the parallel loop will be iterating over. The effect is the loop only iterates over a certain part of an extruded mesh, for example on top cells, bottom cells or interior facets.

pyop2.base.DEFAULT_SOLVER_PARAMETERS = {'pc_type': 'jacobi', 'ksp_atol': 1e-50, 'ksp_max_it': 10000, 'ksp_type': 'cg', 'ksp_gmres_restart': 30, 'ksp_divtol': 10000.0, 'ksp_rtol': 1e-07, 'plot_prefix': '', 'error_on_nonconvergence': True, 'plot_convergence': False, 'ksp_monitor': False}

All parameters accepted by PETSc KSP and PC objects are permissible as options to the op2.Solver.

class pyop2.base.Solver(parameters=None, **kwargs)

Bases: object

OP2 Solver object. The Solver holds a set of parameters that are passed to the underlying linear algebra library when the solve method is called. These can either be passed as a dictionary parameters or as individual keyword arguments (combining both will cause an exception).

Recognized parameters either as dictionary keys or keyword arguments are:

Parameters:
  • ksp_type – the solver type (‘cg’)
  • pc_type – the preconditioner type (‘jacobi’)
  • ksp_rtol – relative solver tolerance (1e-7)
  • ksp_atol – absolute solver tolerance (1e-50)
  • ksp_divtol – factor by which the residual norm may exceed the right-hand-side norm before the solve is considered to have diverged: norm(r) >= dtol*norm(b) (1e4)
  • ksp_max_it – maximum number of solver iterations (10000)
  • error_on_nonconvergence – abort if the solve does not converge in the maximum number of iterations (True, if False only a warning is printed)
  • ksp_monitor – print the residual norm after each iteration (False)
  • plot_convergence – plot a graph of the convergence history after the solve has finished and save it to file (False, implies ksp_monitor)
  • plot_prefix – filename prefix for plot files (‘’)
  • ksp_gmres_restart – restart period when using GMRES
update_parameters(parameters)

Update solver parameters

Parameters:parameters – Dictionary containing the parameters to update.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

solve(A, x, b)

Solve a matrix equation.

Parameters:
  • A – The Mat containing the matrix.
  • x – The Dat to receive the solution.
  • b – The Dat containing the RHS.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

pyop2.base.par_loop(kernel, it_space, *args, **kwargs)

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

pyop2.caching module

Provides common base classes for cached objects.

pyop2.caching.report_cache(typ)

Report the size of caches of type typ

Parameters:typ – A class of cached object. For example ObjectCached or Cached.
class pyop2.caching.ObjectCached

Bases: object

Base class for objects that should be cached on another object.

Derived classes need to implement classmethods _process_args() and _cache_key() (which see for more details). The object on which the cache is stored should contain a dict in its _cache attribute.

Warning

This kind of cache sets up a circular reference. If either of the objects implements __del__, the Python garbage collector will not be able to collect this cycle, and hence the cache will never be evicted.

Warning

The derived class’ __init__() is still called if the object is retrieved from cache. If that is not desired, derived classes can set a flag indicating whether the constructor has already been called and immediately return from __init__() if the flag is set. Otherwise the object will be re-initialized even if it was returned from cache!

class pyop2.caching.Cached

Bases: object

Base class providing global caching of objects. Derived classes need to implement classmethods _process_args() and _cache_key() and define a class attribute _cache of type dict.

Warning

The derived class’ __init__() is still called if the object is retrieved from cache. If that is not desired, derived classes can set a flag indicating whether the constructor has already been called and immediately return from __init__() if the flag is set. Otherwise the object will be re-initialized even if it was returned from cache!

cache_key

Cache key.

class pyop2.caching.DiskCached

Bases: pyop2.caching.Cached

Base class providing global caching of objects on disk. The same notes as in Cached apply. In addition, derived classes need to define a class attribute _cachedir specifying the path where to cache objects on disk.

Warning

The key returned by _cache_key() must be a str safe to use as a filename, such as an md5 hex digest.

pyop2.compilation module

class pyop2.compilation.Compiler(cc, ld=None, cppargs=[], ldargs=[])

Bases: object

A compiler for shared libraries.

Parameters:
  • cc – C compiler executable (can be overriden by exporting the environment variable CC).
  • ld – Linker executable (optional, if None, we assume the compiler can build object files and link in a single invocation, can be overridden by exporting the environment variable LDSHARED).
  • cppargs – A list of arguments to the C compiler (optional).
  • ldargs – A list of arguments to the linker (optional).
get_so(src, extension)

Build a shared library and load it

Parameters:
  • src – The source string to compile.
  • extension – extension of the source file (c, cpp).

Returns a ctypes.CDLL object of the resulting shared library.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

class pyop2.compilation.MacCompiler(cppargs=[], ldargs=[])

Bases: pyop2.compilation.Compiler

A compiler for building a shared library on mac systems.

Parameters:
  • cppargs – A list of arguments to pass to the C compiler (optional).
  • ldargs – A list of arguments to pass to the linker (optional).
class pyop2.compilation.LinuxCompiler(cppargs=[], ldargs=[])

Bases: pyop2.compilation.Compiler

A compiler for building a shared library on linux systems.

Parameters:
  • cppargs – A list of arguments to pass to the C compiler (optional).
  • ldargs – A list of arguments to pass to the linker (optional).
class pyop2.compilation.LinuxIntelCompiler(cppargs=[], ldargs=[])

Bases: pyop2.compilation.Compiler

The intel compiler for building a shared library on linux systems.

Parameters:
  • cppargs – A list of arguments to pass to the C compiler (optional).
  • ldargs – A list of arguments to pass to the linker (optional).
pyop2.compilation.load(src, extension, fn_name, cppargs=[], ldargs=[], argtypes=None, restype=None, compiler=None)

Build a shared library and return a function pointer from it.

Parameters:
  • src – A string containing the source to build
  • extension – extension of the source file (c, cpp)
  • fn_name – The name of the function to return from the resulting library
  • cppargs – A list of arguments to the C compiler (optional)
  • ldargs – A list of arguments to the linker (optional)
  • argtypes – A list of ctypes argument types matching the arguments of the returned function (optional, pass None for void).
  • restype – The return type of the function (optional, pass None for void).
  • compiler – The name of the C compiler (intel, None for default).

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

pyop2.compilation.clear_cache(prompt=False)

Clear the PyOP2 compiler cache.

Parameters:prompt – if True prompt before removing any files

pyop2.computeind module

pyop2.computeind.compute_ind_extr()

pyop2.configuration module

PyOP2 global configuration.

class pyop2.configuration.Configuration

Bases: object

PyOP2 configuration parameters

Parameters:
  • backend – Select the PyOP2 backend (one of cuda, opencl, openmp or sequential).
  • debug – Turn on debugging for generated code (turns off compiler optimisations).
  • log_level – How chatty should PyOP2 be? Valid values are “DEBUG”, “INFO”, “WARNING”, “ERROR”, “CRITICAL”.
  • lazy_evaluation – Should lazy evaluation be on or off?
  • lazy_max_trace_length – How many par_loop()s should be queued lazily before forcing evaluation? Pass 0 for an unbounded length.
  • dump_gencode – Should PyOP2 write the generated code somewhere for inspection?
  • dump_gencode_path – Where should the generated code be written to?
  • print_cache_size – Should PyOP2 print the size of caches at program exit?
  • print_summary – Should PyOP2 print a summary of timings at program exit?
  • profiling – Profiling mode (CUDA kernels are launched synchronously)
DEFAULTS = {'profiling': ('PYOP2_PROFILING', <type 'bool'>, False), 'blas': ('PYOP2_BLAS', <type 'str'>, ''), 'dump_gencode': ('PYOP2_DUMP_GENCODE', <type 'bool'>, False), 'simd_isa': ('PYOP2_SIMD_ISA', <type 'str'>, 'sse'), 'debug': ('PYOP2_DEBUG', <type 'int'>, 0), 'cache_dir': ('PYOP2_CACHE_DIR', <type 'str'>, '/tmp/pyop2-cache-uid1000'), 'lazy_max_trace_length': ('PYOP2_MAX_TRACE_LENGTH', <type 'int'>, 0), 'compiler': ('PYOP2_BACKEND_COMPILER', <type 'str'>, 'gnu'), 'log_level': ('PYOP2_LOG_LEVEL', (<type 'str'>, <type 'int'>), 'WARNING'), 'print_summary': ('PYOP2_PRINT_SUMMARY', <type 'bool'>, False), 'dump_gencode_path': ('PYOP2_DUMP_GENCODE_PATH', <type 'str'>, '/tmp/pyop2-gencode'), 'lazy_evaluation': ('PYOP2_LAZY', <type 'bool'>, True), 'backend': ('PYOP2_BACKEND', <type 'str'>, 'sequential'), 'print_cache_size': ('PYOP2_PRINT_CACHE_SIZE', <type 'bool'>, False)}

Default values for PyOP2 configuration parameters

READONLY = ['backend']

List of read-only configuration keys.

reset()

Reset the configuration parameters to the default values.

reconfigure(**kwargs)

Update the configuration parameters with new values.

pyop2.cuda module

class pyop2.cuda.Kernel(code, name, opts={}, include_dirs=[])

Bases: pyop2.device.Kernel

instrument()
class pyop2.cuda.Arg(data=None, map=None, idx=None, access=None, flatten=False)

Bases: pyop2.device.Arg

Parameters:
  • data – A data-carrying object, either Dat or class:Mat
  • map – A Map to access this Arg or the default if the identity map is to be used.
  • idx – An index into the Map: an IterationIndex when using an iteration space, an int to use a given component of the mapping or the default to use all components of the mapping.
  • access – An access descriptor of type Access
  • flatten – Treat the data dimensions of this Arg as flat s.t. the kernel is passed a flat vector of length map.arity * data.dataset.cdim.

Checks that:

  1. the maps used are initialized i.e. have mapping data associated, and
  2. the to Set of the map used to access it matches the Set it is defined on.

A MapValueError is raised if these conditions are not met.

class pyop2.cuda.Subset(superset, indices)

Bases: pyop2.base.Subset

class pyop2.cuda.DeviceDataMixin

Bases: pyop2.device.DeviceDataMixin

class pyop2.cuda.Dat(dataset, data=None, dtype=None, name=None, soa=None, uid=None)

Bases: pyop2.cuda.DeviceDataMixin, pyop2.device.Dat

class pyop2.cuda.Sparsity(dsets, maps, name=None)

Bases: pyop2.base.Sparsity

Parameters:
  • dsetsDataSets for the left and right function spaces this Sparsity maps between
  • maps (a pair of Maps specifying a row map and a column map, or an iterable of pairs of Maps specifying multiple row and column maps - if a single Map is passed, it is used as both a row map and a column map) – Maps to build the Sparsity from
  • name (string) – user-defined label (optional)
rowptr
colidx
class pyop2.cuda.Mat(datasets, dtype=None, name=None)

Bases: pyop2.cuda.DeviceDataMixin, pyop2.device.Mat

values
array
zero_rows(rows, diag_val=1.0)

Zeroes the specified rows of the matrix, with the exception of the diagonal entry, which is set to diag_val. May be used for applying strong boundary conditions.

Parameters:rows – a Subset or an iterable
zero()
class pyop2.cuda.Const(dim, data, name, dtype=None)

Bases: pyop2.cuda.DeviceDataMixin, pyop2.device.Const

class pyop2.cuda.Global(dim, data=None, dtype=None, name=None)

Bases: pyop2.cuda.DeviceDataMixin, pyop2.device.Global

data
class pyop2.cuda.Map(iterset, dataset, arity, values=None, name=None, offset=None, parent=None, bt_masks=None)

Bases: pyop2.device.Map

class pyop2.cuda.Plan

Bases: pyop2.plan.Plan

nthrcol
thrcol
offset
ind_map
ind_offs
ind_sizes
loc_map
nelems
blkmap
class pyop2.cuda.Solver(parameters=None, **kwargs)

Bases: pyop2.base.Solver

class pyop2.cuda.JITModule(kernel, itspace_extents, *args, **kwargs)

Bases: pyop2.base.JITModule

A cached compiled function to execute for a specified par_loop.

See par_loop() for the description of arguments.

Warning

Note to implementors. This object is cached, and therefore should not hold any long term references to objects that you want to be collected. In particular, after the args have been inspected to produce the compiled code, they must not remain part of the object’s slots, otherwise they (and the Dats, Maps and Mats they reference) will never be collected.

compile()
class pyop2.cuda.ParLoop(kernel, itspace, *args, **kwargs)

Bases: pyop2.device.ParLoop

launch_configuration(part)

pyop2.device module

class pyop2.device.Kernel(code, name, opts={}, include_dirs=[])

Bases: pyop2.base.Kernel

class pyop2.device.Arg(data=None, map=None, idx=None, access=None, flatten=False)

Bases: pyop2.base.Arg

Parameters:
  • data – A data-carrying object, either Dat or class:Mat
  • map – A Map to access this Arg or the default if the identity map is to be used.
  • idx – An index into the Map: an IterationIndex when using an iteration space, an int to use a given component of the mapping or the default to use all components of the mapping.
  • access – An access descriptor of type Access
  • flatten – Treat the data dimensions of this Arg as flat s.t. the kernel is passed a flat vector of length map.arity * data.dataset.cdim.

Checks that:

  1. the maps used are initialized i.e. have mapping data associated, and
  2. the to Set of the map used to access it matches the Set it is defined on.

A MapValueError is raised if these conditions are not met.

name

The generated argument name.

class pyop2.device.DeviceDataMixin

Bases: object

DEVICE_UNALLOCATED = 'DEVICE_UNALLOCATED'
HOST_UNALLOCATED = 'HOST_UNALLOCATED'
DEVICE = 'DEVICE'
HOST = 'HOST'
BOTH = 'BOTH'
state

Current allocation state of the data.

data

Numpy array containing the data values.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

data_ro

Numpy array containing the data values. Read-only

class pyop2.device.Dat(dataset, data=None, dtype=None, name=None, soa=None, uid=None)

Bases: pyop2.device.DeviceDataMixin, pyop2.base.Dat

array

The data array on the device.

halo_exchange_begin()
halo_exchange_end()
class pyop2.device.Const(dim, data, name, dtype=None)

Bases: pyop2.device.DeviceDataMixin, pyop2.base.Const

data

Numpy array containing the data values.

class pyop2.device.Global(dim, data=None, dtype=None, name=None)

Bases: pyop2.device.DeviceDataMixin, pyop2.base.Global

data_ro
class pyop2.device.Map(iterset, dataset, arity, values=None, name=None, offset=None, parent=None, bt_masks=None)

Bases: pyop2.base.Map

class pyop2.device.Mat(datasets, dtype=None, name=None)

Bases: pyop2.base.Mat

class pyop2.device.ParLoop(kernel, itspace, *args, **kwargs)

Bases: pyop2.base.ParLoop

pyop2.exceptions module

OP2 exception types

exception pyop2.exceptions.DataTypeError

Bases: exceptions.TypeError

Invalid type for data.

exception pyop2.exceptions.DimTypeError

Bases: exceptions.TypeError

Invalid type for dimension.

exception pyop2.exceptions.ArityTypeError

Bases: exceptions.TypeError

Invalid type for arity.

exception pyop2.exceptions.IndexTypeError

Bases: exceptions.TypeError

Invalid type for index.

exception pyop2.exceptions.NameTypeError

Bases: exceptions.TypeError

Invalid type for name.

exception pyop2.exceptions.SetTypeError

Bases: exceptions.TypeError

Invalid type for pyop2.op2.Set.

exception pyop2.exceptions.SizeTypeError

Bases: exceptions.TypeError

Invalid type for size.

exception pyop2.exceptions.SubsetIndexOutOfBounds

Bases: exceptions.TypeError

Out of bound index.

exception pyop2.exceptions.SparsityTypeError

Bases: exceptions.TypeError

Invalid type for pyop2.op2.Sparsity.

exception pyop2.exceptions.MapTypeError

Bases: exceptions.TypeError

Invalid type for pyop2.op2.Map.

exception pyop2.exceptions.DataSetTypeError

Bases: exceptions.TypeError

Invalid type for pyop2.op2.DataSet.

exception pyop2.exceptions.MatTypeError

Bases: exceptions.TypeError

Invalid type for pyop2.op2.Mat.

exception pyop2.exceptions.DatTypeError

Bases: exceptions.TypeError

Invalid type for pyop2.op2.Dat.

exception pyop2.exceptions.KernelTypeError

Bases: exceptions.TypeError

Invalid type for pyop2.op2.Kernel.

exception pyop2.exceptions.DataValueError

Bases: exceptions.ValueError

Illegal value for data.

exception pyop2.exceptions.IndexValueError

Bases: exceptions.ValueError

Illegal value for index.

exception pyop2.exceptions.ModeValueError

Bases: exceptions.ValueError

Illegal value for mode.

exception pyop2.exceptions.IterateValueError

Bases: exceptions.ValueError

Illegal value for iterate.

exception pyop2.exceptions.SetValueError

Bases: exceptions.ValueError

Illegal value for pyop2.op2.Set.

exception pyop2.exceptions.MapValueError

Bases: exceptions.ValueError

Illegal value for pyop2.op2.Map.

exception pyop2.exceptions.ConfigurationError

Bases: exceptions.RuntimeError

Illegal configuration value or type.

exception pyop2.exceptions.CompilationError

Bases: exceptions.RuntimeError

Error during JIT compilation

pyop2.finalised module

This module contains stub implementations of core classes which are used to provide useful error messages if the user invokes them after calling pyop2.op2.exit()

class pyop2.finalised.Access(*args)

Bases: object

class pyop2.finalised.Set(*args)

Bases: object

class pyop2.finalised.Kernel(*args)

Bases: object

class pyop2.finalised.Dat(*args)

Bases: object

class pyop2.finalised.Mat(*args)

Bases: object

class pyop2.finalised.Const(*args)

Bases: object

class pyop2.finalised.Global(*args)

Bases: object

class pyop2.finalised.Map(*args)

Bases: object

pyop2.finalised.par_loop(*args)

pyop2.host module

Base classes extending those from the base module with functionality common to backends executing on the host.

class pyop2.host.Kernel(code, name, opts={}, include_dirs=[], headers=[], user_code='')

Bases: pyop2.base.Kernel

class pyop2.host.Arg(data=None, map=None, idx=None, access=None, flatten=False)

Bases: pyop2.base.Arg

Parameters:
  • data – A data-carrying object, either Dat or class:Mat
  • map – A Map to access this Arg or the default if the identity map is to be used.
  • idx – An index into the Map: an IterationIndex when using an iteration space, an int to use a given component of the mapping or the default to use all components of the mapping.
  • access – An access descriptor of type Access
  • flatten – Treat the data dimensions of this Arg as flat s.t. the kernel is passed a flat vector of length map.arity * data.dataset.cdim.

Checks that:

  1. the maps used are initialized i.e. have mapping data associated, and
  2. the to Set of the map used to access it matches the Set it is defined on.

A MapValueError is raised if these conditions are not met.

c_arg_name(i=0, j=None)
c_vec_name()
c_map_name(i, j)
c_offset_name(i, j)
c_wrapper_arg()
c_vec_dec(is_facet=False)
c_wrapper_dec(is_facet=False)
c_ind_data(idx, i, j=0, is_top=False, layers=1, offset=None)
c_ind_data_xtr(idx, i, j=0, is_top=False, layers=1)
c_kernel_arg_name(i, j)
c_global_reduction_name(count=None)
c_local_tensor_name(i, j)
c_kernel_arg(count, i=0, j=0, shape=(0, ), is_top=False, layers=1)
c_vec_init(is_top, layers, is_facet=False)
c_addto_scalar_field(i, j, buf_name, extruded=None, is_facet=False)
c_addto_vector_field(i, j, buf_name, indices, xtr='', is_facet=False)
c_local_tensor_dec(extents, i, j)
c_zero_tmp(i, j)
c_add_offset(is_facet=False)
c_intermediate_globals_decl(count)
c_intermediate_globals_init(count)
c_intermediate_globals_writeback(count)
c_map_decl(is_facet=False)
c_map_init(is_top=False, layers=1, is_facet=False)
c_map_bcs(sign)
c_add_offset_map(is_facet=False)
c_offset_init()
c_buffer_decl(size, idx, buf_name, is_facet=False)
c_buffer_gather(size, idx, buf_name)
c_buffer_scatter_mm(i, j, mxofs, buf_name, buf_scat_name)
c_buffer_scatter_vec(count, i, j, mxofs, buf_name)
class pyop2.host.JITModule(kernel, itspace, *args, **kwargs)

Bases: pyop2.base.JITModule

A cached compiled function to execute for a specified par_loop.

See par_loop() for the description of arguments.

Warning

Note to implementors. This object is cached, and therefore should not hold any long term references to objects that you want to be collected. In particular, after the args have been inspected to produce the compiled code, they must not remain part of the object’s slots, otherwise they (and the Dats, Maps and Mats they reference) will never be collected.

compile(argtypes=None, restype=None)

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

generate_code()

pyop2.logger module

The PyOP2 logger, based on the Python standard library logging module.

pyop2.logger.set_log_level(level)

Set the log level of the PyOP2 logger.

Parameters:level – the log level. Valid values: DEBUG, INFO, WARNING, ERROR, CRITICAL
pyop2.logger.info_red(message, *args, **kwargs)

Write info message in red.

Parameters:message – the message to be printed.
pyop2.logger.info_green(message, *args, **kwargs)

Write info message in green.

Parameters:message – the message to be printed.
pyop2.logger.info_blue(message, *args, **kwargs)

Write info message in blue.

Parameters:message – the message to be printed.
pyop2.logger.log(level, msg, *args, **kwargs)

Print ‘msg % args’ with the severity ‘level’.

Parameters:
  • level – the log level. Valid values: DEBUG, INFO, WARNING, ERROR, CRITICAL
  • msg – the message
pyop2.logger.progress(*args, **kwds)

A context manager to print a progress message.

The block is wrapped in msg..., msg...done log messages with an appropriate indent (to distinguish nested message).

Parameters:
  • level – the log level. See log() for valid values
  • msg – the message.

See log() for more details.

pyop2.mpi module

PyOP2 MPI communicator.

pyop2.mpi.collective(fn)
class pyop2.mpi.MPIConfig

Bases: object

parallel

Are we running in parallel?

comm

The MPI Communicator used by PyOP2.

rank_zero(f)

Decorator for executing a function only on MPI rank zero.

pyop2.op2 module

The PyOP2 API specification.

pyop2.op2.initialised()

Check whether PyOP2 has been yet initialised but not yet finalised.

pyop2.op2.init(**kwargs)

Initialise PyOP2: select the backend and potentially other configuration options.

Parameters:
  • backend – Set the hardware-specific backend. Current choices are "sequential", "openmp", "opencl", "cuda".
  • debug – The level of debugging output.
  • comm – The MPI communicator to use for parallel communication, defaults to MPI_COMM_WORLD
  • log_level – The log level. Options: DEBUG, INFO, WARNING, ERROR, CRITICAL

For debugging purposes, init accepts all keyword arguments accepted by the PyOP2 Configuration object, see Configuration.__init__() for details of further accepted options.

Note

Calling init again with a different backend raises an exception. Changing the backend is not possible. Calling init again with the same backend or not specifying a backend will update the configuration. Calling init after exit has been called is an error and will raise an exception.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

pyop2.op2.exit()

Exit OP2 and clean up

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

class pyop2.op2.Kernel(code, name, opts={}, include_dirs=[], headers=[], user_code='')

Bases: pyop2.base.Kernel

OP2 kernel type.

Parameters:
  • code – kernel function definition, including signature; either a string or an AST Node
  • name – kernel function name; must match the name of the kernel function given in code
  • opts – options dictionary for PyOP2 IR optimisations (optional, ignored if code is a string)
  • include_dirs – list of additional include directories to be searched when compiling the kernel (optional, defaults to empty)
  • headers – list of system headers to include when compiling the kernel in the form #include <header.h> (optional, defaults to empty)
  • user_code – code snippet to be executed once at the very start of the generated kernel wrapper code (optional, defaults to empty)

Consider the case of initialising a Dat with seeded random values in the interval 0 to 1. The corresponding Kernel is constructed as follows:

op2.Kernel("void setrand(double *x) { x[0] = (double)random()/RAND_MAX); }",
           name="setrand",
           headers=["#include <stdlib.h>"], user_code="srandom(10001);")

Note

When running in parallel with MPI the generated code must be the same on all ranks.

class pyop2.op2.Set(size=None, name=None, halo=None)

Bases: pyop2.base.Set

OP2 set.

Parameters:
  • size (integer or list of four integers.) – The size of the set.
  • dim (integer or tuple of integers) – The shape of the data associated with each element of this Set.
  • name (string) – The name of the set (optional).
  • halo – An exisiting halo to use (optional).

When the set is employed as an iteration space in a pyop2.op2.par_loop(), the extent of any local iteration space within each set entry is indicated in brackets. See the example in pyop2.op2.par_loop() for more details.

The size of the set can either be an integer, or a list of four integers. The latter case is used for running in parallel where we distinguish between:

  • CORE (owned and not touching halo)
  • OWNED (owned, touching halo)
  • EXECUTE HALO (not owned, but executed over redundantly)
  • NON EXECUTE HALO (not owned, read when executing in the execute halo)

If a single integer is passed, we assume that we’re running in serial and there is no distinction.

The division of set elements is:

[0, CORE)
[CORE, OWNED)
[OWNED, EXECUTE HALO)
[EXECUTE HALO, NON EXECUTE HALO).

Halo send/receive data is stored on sets in a Halo.

class pyop2.op2.ExtrudedSet(size=None, name=None, halo=None)

Bases: pyop2.base.Set

OP2 set.

Parameters:
  • size (integer or list of four integers.) – The size of the set.
  • dim (integer or tuple of integers) – The shape of the data associated with each element of this Set.
  • name (string) – The name of the set (optional).
  • halo – An exisiting halo to use (optional).

When the set is employed as an iteration space in a pyop2.op2.par_loop(), the extent of any local iteration space within each set entry is indicated in brackets. See the example in pyop2.op2.par_loop() for more details.

The size of the set can either be an integer, or a list of four integers. The latter case is used for running in parallel where we distinguish between:

  • CORE (owned and not touching halo)
  • OWNED (owned, touching halo)
  • EXECUTE HALO (not owned, but executed over redundantly)
  • NON EXECUTE HALO (not owned, read when executing in the execute halo)

If a single integer is passed, we assume that we’re running in serial and there is no distinction.

The division of set elements is:

[0, CORE)
[CORE, OWNED)
[OWNED, EXECUTE HALO)
[EXECUTE HALO, NON EXECUTE HALO).

Halo send/receive data is stored on sets in a Halo.

class pyop2.op2.MixedSet(sets)

Bases: pyop2.base.MixedSet

A container for a bag of Sets.

Parameters:sets (iterable) – Iterable of Sets or ExtrudedSets
class pyop2.op2.Subset(superset, indices)

Bases: pyop2.base.Subset

OP2 subset.

Parameters:
  • superset (a Set or a Subset.) – The superset of the subset.
  • indices (a list of integers, or a numpy array.) – Elements of the superset that form the subset. Duplicate values are removed when constructing the subset.
class pyop2.op2.DataSet(iter_set, dim=1, name=None)

Bases: pyop2.base.DataSet

PyOP2 Data Set

Set used in the op2.Dat structures to specify the dimension of the data.

class pyop2.op2.MixedDataSet(arg, dims=None)

Bases: pyop2.base.MixedDataSet

A container for a bag of DataSets.

Initialized either from a MixedSet and an iterable or iterator of dims of corresponding length

mdset = op2.MixedDataSet(mset, [dim1, ..., dimN])

or from a tuple of Sets and an iterable of dims of corresponding length

mdset = op2.MixedDataSet([set1, ..., setN], [dim1, ..., dimN])

If all dims are to be the same, they can also be given as an int for either of above invocations

mdset = op2.MixedDataSet(mset, dim)
mdset = op2.MixedDataSet([set1, ..., setN], dim)

Initialized from a MixedSet without explicitly specifying dims they default to 1

mdset = op2.MixedDataSet(mset)

Initialized from an iterable or iterator of DataSets and/or Sets, where Sets are implicitly upcast to DataSets of dim 1

mdset = op2.MixedDataSet([dset1, ..., dsetN])
Parameters:
  • arg – a MixedSet or an iterable or a generator expression of Sets or DataSets or a mixture of both
  • dimsNone (the default) or an int or an iterable or generator expression of ints, which must be of same length as arg

Warning

When using generator expressions for arg or dims, these must terminate or else will cause an infinite loop.

class pyop2.op2.Halo(sends, receives, comm=None, gnn2unn=None)

Bases: pyop2.base.Halo

A description of a halo associated with a Set.

The halo object describes which Set elements are sent where, and which Set elements are received from where.

The sends should be a dict whose key is the process we want to send to, similarly the receives should be a dict whose key is the process we want to receive from. The value should in each case be a numpy array of the set elements to send to/receive from each process.

The gnn2unn array is a map from process-local set element numbering to cross-process set element numbering. It must correctly number all the set elements in the halo region as well as owned elements. Providing this array is only necessary if you will access Mat objects on the Set this Halo lives on. Insertion into Dats always uses process-local numbering, however insertion into Mats uses cross-process numbering under the hood.

class pyop2.op2.Dat(dataset, data=None, dtype=None, name=None, soa=None, uid=None)

Bases: pyop2.base.Dat

OP2 vector data. A Dat holds values on every element of a DataSet.

If a Set is passed as the dataset argument, rather than a DataSet, the Dat is created with a default DataSet dimension of 1.

If a Dat is passed as the dataset argument, a copy is returned.

It is permissible to pass None as the data argument. In this case, allocation of the data buffer is postponed until it is accessed.

Note

If the data buffer is not passed in, it is implicitly initialised to be zero.

When a Dat is passed to pyop2.op2.par_loop(), the map via which indirection occurs and the access descriptor are passed by calling the Dat. For instance, if a Dat named D is to be accessed for reading via a Map named M, this is accomplished by

D(pyop2.READ, M)

The Map through which indirection occurs can be indexed using the index notation described in the documentation for the Map. Direct access to a Dat is accomplished by omitting the path argument.

Dat objects support the pointwise linear algebra operations +=, *=, -=, /=, where *= and /= also support multiplication / division by a scalar.

class pyop2.op2.MixedDat(mdset_or_dats)

Bases: pyop2.base.MixedDat

A container for a bag of Dats.

Initialized either from a MixedDataSet, a MixedSet, or an iterable of DataSets and/or Sets, where all the Sets are implcitly upcast to DataSets

mdat = op2.MixedDat(mdset)
mdat = op2.MixedDat([dset1, ..., dsetN])

or from an iterable of Dats

mdat = op2.MixedDat([dat1, ..., datN])
class pyop2.op2.Mat(sparsity, dtype=None, name=None)

Bases: pyop2.base.Mat

OP2 matrix data. A Mat is defined on a sparsity pattern and holds a value for each element in the Sparsity.

When a Mat is passed to pyop2.op2.par_loop(), the maps via which indirection occurs for the row and column space, and the access descriptor are passed by calling the Mat. For instance, if a Mat named A is to be accessed for reading via a row Map named R and a column Map named C, this is accomplished by:

A(pyop2.READ, (R[pyop2.i[0]], C[pyop2.i[1]]))

Notice that it is always necessary to index the indirection maps for a Mat. See the Mat documentation for more details.

Note

After executing par_loop()s that write to a Mat and before using it (for example to view its values), you must call assemble() to finalise the writes.

class pyop2.op2.Const(dim, data=None, name=None, dtype=None)

Bases: pyop2.base.Const

Data that is constant for any element of any set.

class pyop2.op2.Global(dim, data=None, dtype=None, name=None)

Bases: pyop2.base.Global

OP2 global value.

When a Global is passed to a pyop2.op2.par_loop(), the access descriptor is passed by calling the Global. For example, if a Global named G is to be accessed for reading, this is accomplished by:

G(pyop2.READ)

It is permissible to pass None as the data argument. In this case, allocation of the data buffer is postponed until it is accessed.

Note

If the data buffer is not passed in, it is implicitly initialised to be zero.

class pyop2.op2.Map(iterset, toset, arity, values=None, name=None, offset=None, parent=None, bt_masks=None)

Bases: pyop2.base.Map

OP2 map, a relation between two Set objects.

Each entry in the iterset maps to arity entries in the toset. When a map is used in a pyop2.op2.par_loop(), it is possible to use Python index notation to select an individual entry on the right hand side of this map. There are three possibilities:

  • No index. All arity Dat entries will be passed to the kernel.
  • An integer: some_map[n]. The n th entry of the map result will be passed to the kernel.
  • An IterationIndex, some_map[pyop2.i[n]]. n will take each value from 0 to e-1 where e is the n th extent passed to the iteration space for this pyop2.op2.par_loop(). See also i.

For extruded problems (where iterset is an ExtrudedSet) with boundary conditions applied at the top and bottom of the domain, one needs to provide a list of which of the arity values in each map entry correspond to values on the bottom boundary and which correspond to the top. This is done by supplying two lists of indices in bt_masks, the first provides indices for the bottom, the second for the top.

class pyop2.op2.MixedMap(maps)

Bases: pyop2.base.MixedMap

A container for a bag of Maps.

Parameters:maps (iterable) – Iterable of Maps
class pyop2.op2.Sparsity(dsets, maps, name=None)

Bases: pyop2.base.Sparsity

OP2 Sparsity, the non-zero structure a matrix derived from the union of the outer product of pairs of Map objects.

Examples of constructing a Sparsity:

Sparsity(single_dset, single_map, 'mass')
Sparsity((row_dset, col_dset), (single_rowmap, single_colmap))
Sparsity((row_dset, col_dset),
         [(first_rowmap, first_colmap), (second_rowmap, second_colmap)])
Parameters:
  • dsetsDataSets for the left and right function spaces this Sparsity maps between
  • maps (a pair of Maps specifying a row map and a column map, or an iterable of pairs of Maps specifying multiple row and column maps - if a single Map is passed, it is used as both a row map and a column map) – Maps to build the Sparsity from
  • name (string) – user-defined label (optional)
class pyop2.op2.Solver(parameters=None, **kwargs)

Bases: pyop2.base.Solver

OP2 Solver object. The Solver holds a set of parameters that are passed to the underlying linear algebra library when the solve method is called. These can either be passed as a dictionary parameters or as individual keyword arguments (combining both will cause an exception).

Recognized parameters either as dictionary keys or keyword arguments are:

Parameters:
  • ksp_type – the solver type (‘cg’)
  • pc_type – the preconditioner type (‘jacobi’)
  • ksp_rtol – relative solver tolerance (1e-7)
  • ksp_atol – absolute solver tolerance (1e-50)
  • ksp_divtol – factor by which the residual norm may exceed the right-hand-side norm before the solve is considered to have diverged: norm(r) >= dtol*norm(b) (1e4)
  • ksp_max_it – maximum number of solver iterations (10000)
  • error_on_nonconvergence – abort if the solve does not converge in the maximum number of iterations (True, if False only a warning is printed)
  • ksp_monitor – print the residual norm after each iteration (False)
  • plot_convergence – plot a graph of the convergence history after the solve has finished and save it to file (False, implies ksp_monitor)
  • plot_prefix – filename prefix for plot files (‘’)
  • ksp_gmres_restart – restart period when using GMRES
pyop2.op2.par_loop(kernel, iterset, *args, **kwargs)

Invocation of an OP2 kernel

Parameters:
  • kernel – The Kernel to be executed.
  • iterset – The iteration Set over which the kernel should be executed.
  • *args – One or more base.Args constructed from a Global, Dat or Mat using the call syntax and passing in an optionally indexed Map through which this base.Arg is accessed and the base.Access descriptor indicating how the Kernel is going to access this data (see the example below). These are the global data structures from and to which the kernel will read and write.
  • iterate

    Optionally specify which region of an ExtrudedSet to iterate over. Valid values are:

    • ON_BOTTOM: iterate over the bottom layer of cells.
    • ON_TOP iterate over the top layer of cells.
    • ALL iterate over all cells (the default if unspecified)
    • ON_INTERIOR_FACETS iterate over all the layers
      except the top layer, accessing data two adjacent (in the extruded direction) cells at a time.

Warning

It is the caller’s responsibility that the number and type of all base.Args passed to the par_loop() match those expected by the Kernel. No runtime check is performed to ensure this!

If a par_loop() argument indexes into a Map using an base.IterationIndex, this implies the use of a local base.IterationSpace of a size given by the arity of the Map. It is an error to have several arguments using local iteration spaces of different size.

par_loop() invocation is illustrated by the following example

pyop2.par_loop(mass, elements,
               mat(pyop2.INC, (elem_node[pyop2.i[0]]), elem_node[pyop2.i[1]]),
               coords(pyop2.READ, elem_node))

This example will execute the Kernel mass over the Set elements executing 3x3 times for each Set member, assuming the Map elem_node is of arity 3. The Kernel takes four arguments, the first is a Mat named mat, the second is a field named coords. The remaining two arguments indicate which local iteration space point the kernel is to execute.

A Mat requires a pair of Map objects, one each for the row and column spaces. In this case both are the same elem_node map. The row Map is indexed by the first index in the local iteration space, indicated by the 0 index to pyop2.i, while the column space is indexed by the second local index. The matrix is accessed to increment values using the pyop2.INC access descriptor.

The coords Dat is also accessed via the elem_node Map, however no indices are passed so all entries of elem_node for the relevant member of elements will be passed to the kernel as a vector.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

pyop2.op2.solve(A, x, b)

Solve a matrix equation using the default Solver

Parameters:
  • A – The Mat containing the matrix.
  • x – The Dat to receive the solution.
  • b – The Dat containing the RHS.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

pyop2.op2.set_log_level(level)

Set the log level of the PyOP2 logger.

Parameters:level – the log level. Valid values: DEBUG, INFO, WARNING, ERROR, CRITICAL

pyop2.opencl module

pyop2.openmp module

OP2 OpenMP backend.

class pyop2.openmp.Arg(data=None, map=None, idx=None, access=None, flatten=False)

Bases: pyop2.host.Arg

Parameters:
  • data – A data-carrying object, either Dat or class:Mat
  • map – A Map to access this Arg or the default if the identity map is to be used.
  • idx – An index into the Map: an IterationIndex when using an iteration space, an int to use a given component of the mapping or the default to use all components of the mapping.
  • access – An access descriptor of type Access
  • flatten – Treat the data dimensions of this Arg as flat s.t. the kernel is passed a flat vector of length map.arity * data.dataset.cdim.

Checks that:

  1. the maps used are initialized i.e. have mapping data associated, and
  2. the to Set of the map used to access it matches the Set it is defined on.

A MapValueError is raised if these conditions are not met.

c_kernel_arg_name(i, j, idx=None)
c_local_tensor_name(i, j)
c_vec_dec(is_facet=False)
padding()
c_reduction_dec()
c_reduction_init()
c_reduction_finalisation()
c_global_reduction_name(count=None)
class pyop2.openmp.JITModule(kernel, itspace, *args, **kwargs)

Bases: pyop2.host.JITModule

A cached compiled function to execute for a specified par_loop.

See par_loop() for the description of arguments.

Warning

Note to implementors. This object is cached, and therefore should not hold any long term references to objects that you want to be collected. In particular, after the args have been inspected to produce the compiled code, they must not remain part of the object’s slots, otherwise they (and the Dats, Maps and Mats they reference) will never be collected.

generate_code()
ompflag = '-fopenmp'
omplib = '-lgomp'
class pyop2.openmp.ParLoop(kernel, itspace, *args, **kwargs)

Bases: pyop2.device.ParLoop, pyop2.base.ParLoop

pyop2.petsc_base module

Base classes for OP2 objects. The versions here extend those from the base module to include runtime data information which is backend independent. Individual runtime backends should subclass these as required to implement backend-specific features.

class pyop2.petsc_base.MPIConfig

Bases: pyop2.mpi.MPIConfig

comm

The MPI Communicator used by PyOP2.

class pyop2.petsc_base.Dat(dataset, data=None, dtype=None, name=None, soa=None, uid=None)

Bases: pyop2.base.Dat

vec_context(*args, **kwds)

A context manager for a PETSc.Vec from a Dat.

Parameters:readonly – Access the data read-only (use Dat.data_ro()) or read-write (use Dat.data()). Read-write access requires a halo update.
vec

Context manager for a PETSc Vec appropriate for this Dat.

You’re allowed to modify the data you get back from this view.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

vec_ro

Context manager for a PETSc Vec appropriate for this Dat.

You’re not allowed to modify the data you get back from this view.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

dump(filename)

Dump the vector to file filename in PETSc binary format.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

class pyop2.petsc_base.MixedDat(mdset_or_dats)

Bases: pyop2.base.MixedDat

vecscatter(*args, **kwds)

A context manager scattering the arrays of all components of this MixedDat into a contiguous PETSc.Vec and reverse scattering to the original arrays when exiting the context.

Parameters:readonly – Access the data read-only (use Dat.data_ro()) or read-write (use Dat.data()). Read-write access requires a halo update.

Note

The Vec obtained from this context is in the correct order to be left multiplied by a compatible MixedMat. In parallel it is not just a concatenation of the underlying Dats.

vec

Context manager for a PETSc Vec appropriate for this Dat.

You’re allowed to modify the data you get back from this view.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

vec_ro

Context manager for a PETSc Vec appropriate for this Dat.

You’re not allowed to modify the data you get back from this view.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

class pyop2.petsc_base.Mat(sparsity, dtype=None, name=None)

Bases: pyop2.base.Mat, pyop2.versioning.CopyOnWrite

OP2 matrix data. A Mat is defined on a sparsity pattern and holds a value for each element in the Sparsity.

dump(filename)

Dump the matrix to file filename in PETSc binary format.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

zero()

Zero the matrix.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

zero_rows(rows, diag_val=1.0)

Zeroes the specified rows of the matrix, with the exception of the diagonal entry, which is set to diag_val. May be used for applying strong boundary conditions.

Parameters:rows – a Subset or an iterable

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

set_diagonal(vec)

Add a vector to the diagonal of the matrix.

Params vec:vector to add (Dat or PETsc.Vec)

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

inc_local_diagonal_entries(rows, diag_val=1.0)

Increment the diagonal entry in rows by a particular value.

Parameters:
  • rows – a Subset or an iterable.
  • diag_val – the value to add

The indices in rows should index the process-local rows of the matrix (no mapping to global indexes is applied).

The diagonal entries corresponding to the complement of rows are incremented by zero.

This function is logically collective over MPI ranks, it is an error to call it on fewer than all the ranks in MPI communicator.

blocks

2-dimensional array of matrix blocks.

array

Array of non-zero values.

values
handle

Petsc4py Mat holding matrix data.

class pyop2.petsc_base.Solver(parameters=None, **kwargs)

Bases: pyop2.base.Solver, petsc4py.PETSc.KSP

pyop2.plan module

Cython implementation of the Plan construction.

class pyop2.plan.Plan

Bases: pyop2.caching.Cached, pyop2.plan._Plan

pyop2.profiling module

Profiling classes/functions.

pyop2.profiling.profile(func)

Pass-through version of the profile decorator.

pyop2.profiling.lineprof(func)

Pass-through version of the profile decorator.

pyop2.profiling.memprof(func)

Pass-through version of the profile decorator.

class pyop2.profiling.Timer(name=None, timer=<built-in function time>)

Bases: object

Generic timer class.

Parameters:
  • name – The name of the timer, used as unique identifier.
  • timer – The timer function to use. Takes no parameters and returns the current time. Defaults to time.time.
start()

Start the timer.

stop()

Stop the timer.

reset()

Reset the timer.

add(t)

Add a timing.

name

Name of the timer.

elapsed

Elapsed time for the currently running timer.

ncalls

Total number of recorded events.

total

Total time spent for all recorded events.

average

Average time spent per recorded event.

classmethod summary(filename=None)

Print a summary table for all timers or write CSV to filename.

classmethod get_timers()

Return a dict containing all Timers.

classmethod reset_all()

Clear all timer information previously recorded.

class pyop2.profiling.timed_function(name=None, timer=<built-in function time>)

Bases: pyop2.profiling.Timer

Decorator to time function calls.

pyop2.profiling.tic(name)

Start a timer with the given name.

pyop2.profiling.toc(name)

Stop a timer with the given name.

pyop2.profiling.timed_region(*args, **kwds)

A context manager for timing a given code region.

pyop2.profiling.summary(filename=None)

Print a summary table for all timers or write CSV to filename.

pyop2.profiling.get_timers(reset=False)

Return a dict containing all Timers.

pyop2.profiling.reset_timers()

Clear all timer information previously recorded.

pyop2.profiling.timing(name, reset=False, total=True)

Return timing (average) for given task, optionally clearing timing.

pyop2.pyparloop module

A stub implementation of “Python” parallel loops.

This basically executes a python function over the iteration set, feeding it the appropriate data for each set entity.

Example usage:

.. code-block:: python

s = op2.Set(10) d = op2.Dat(s) d2 = op2.Dat(s**2)

m = op2.Map(s, s, 2, np.dstack(np.arange(4),
np.roll(np.arange(4), -1)))
def fn(x, y):
x[0] = y[0] x[1] = y[1]

d.data[:] = np.arange(4)

op2.par_loop(fn, s, d2(op2.WRITE), d(op2.READ, m))

print d2.data # [[ 0. 1.] # [ 1. 2.] # [ 2. 3.] # [ 3. 0.]]

def fn2(x, y):
x[0] += y[0] x[1] += y[0]

op2.par_loop(fn, s, d2(op2.INC), d(op2.READ, m[1]))

print d2.data # [[ 1. 2.] # [ 3. 4.] # [ 5. 6.] # [ 3. 0.]]

class pyop2.pyparloop.Kernel(code, name=None, **kwargs)

Bases: pyop2.base.Kernel

class pyop2.pyparloop.ParLoop(kernel, iterset, *args, **kwargs)

Bases: pyop2.base.ParLoop

pyop2.sequential module

OP2 sequential backend.

class pyop2.sequential.JITModule(kernel, itspace, *args, **kwargs)

Bases: pyop2.host.JITModule

A cached compiled function to execute for a specified par_loop.

See par_loop() for the description of arguments.

Warning

Note to implementors. This object is cached, and therefore should not hold any long term references to objects that you want to be collected. In particular, after the args have been inspected to produce the compiled code, they must not remain part of the object’s slots, otherwise they (and the Dats, Maps and Mats they reference) will never be collected.

class pyop2.sequential.ParLoop(*args, **kwargs)

Bases: pyop2.base.ParLoop

pyop2.sparsity module

pyop2.sparsity.build_sparsity()
pyop2.sparsity.fill_with_zeros()

Fill a PETSc matrix with zeros in all slots we might end up inserting into

Parameters:
  • mat – the PETSc Mat (must already be preallocated)
  • dims – the dimensions of the sparsity (block size)
  • maps – the pairs of maps defining the sparsity pattern

pyop2.utils module

Common utility classes/functions.

pyop2.utils.as_tuple(item, type=None, length=None)
pyop2.utils.as_type(obj, typ)

Return obj if it is of dtype typ, otherwise return a copy type-cast to typ.

class pyop2.utils.validate_base(*checks)

Decorator to validate arguments

Formal parameters that don’t exist in the definition of the function being decorated as well as actual arguments not being present when the validation is called are silently ignored.

check_args(args, kwargs)
class pyop2.utils.validate_type(*checks)

Bases: pyop2.utils.validate_base

Decorator to validate argument types

The decorator expects one or more arguments, which are 3-tuples of (name, type, exception), where name is the argument name in the function being decorated, type is the argument type to be validated and exception is the exception type to be raised if validation fails.

check_arg(arg, argtype, exception)
class pyop2.utils.validate_in(*checks)

Bases: pyop2.utils.validate_base

Decorator to validate argument is in a set of valid argument values

The decorator expects one or more arguments, which are 3-tuples of (name, list, exception), where name is the argument name in the function being decorated, list is the list of valid argument values and exception is the exception type to be raised if validation fails.

check_arg(arg, values, exception)
class pyop2.utils.validate_range(*checks)

Bases: pyop2.utils.validate_base

Decorator to validate argument value is in a given numeric range

The decorator expects one or more arguments, which are 3-tuples of (name, range, exception), where name is the argument name in the function being decorated, range is a 2-tuple defining the valid argument range and exception is the exception type to be raised if validation fails.

check_arg(arg, range, exception)
class pyop2.utils.validate_dtype(*checks)

Bases: pyop2.utils.validate_base

Decorator to validate argument value is in a valid Numpy dtype

The decorator expects one or more arguments, which are 3-tuples of (name, _, exception), where name is the argument name in the function being decorated, second argument is ignored and exception is the exception type to be raised if validation fails.

check_arg(arg, ignored, exception)
pyop2.utils.verify_reshape(data, dtype, shape, allow_none=False)

Verify data is of type dtype and try to reshaped to shape.

pyop2.utils.align(bytes, alignment=16)

Align BYTES to a multiple of ALIGNMENT

pyop2.utils.flatten(iterable)

Flatten a given nested iterable.

pyop2.utils.uniquify(iterable)

Remove duplicates in given iterable, preserving order.

pyop2.utils.parser(description=None, group=False)

Create default argparse.ArgumentParser parser for pyop2 programs.

pyop2.utils.maybe_setflags(array, write=None, align=None, uic=None)

Set flags on a numpy ary.

But don’t try to set the write flag if the data aren’t owned by this array. See numpy.ndarray.setflags for details of the parameters.

pyop2.utils.parse_args(*args, **kwargs)

Return parsed arguments as variables for later use.

ARGS and KWARGS are passed into the parser instantiation. The only recognised options are group and description.

pyop2.utils.preprocess(text, include_dirs=[])
pyop2.utils.trim(docstring)

Trim a docstring according to PEP 257.

pyop2.utils.get_petsc_dir()

pyop2.version module

pyop2.versioning module

This module implements the infrastructure required for versioning of data carrying objects (chiefly Dat). Core functionality provided includes object version numbers and copy on write duplicates.

Each data carrying object is equipped with a version number. This is incremented every time the value of the object is changed, whether this is by a par_loop() or through direct user access to a data attribute. Access to the data_ro read only data attribute does not increase the version number.

Data carrying objects are also equipped with a duplicate() method. From a user perspective, this is a deep copy of the original object. In the case of Dat objects, this is implemented as a shallow copy along with a copy on write mechanism which causes the actual copy to occur if either the original or the copy is modified. The delayed copy is implemented by immediately creating a copy par_loop() and, if lazy evaluation is enabled, enqueing it. This ensures that the dependency trace will cause all operations on which the copy depends to occur before the copy. Conversely, the dependency of the copy Dat on the copying loop is artificially removed. This prevents the execution of the copy being triggered when the copy Dat is read. Instead, writes to the original and copy Dat are intercepted and execution of the copy par_loop() is forced at that point.

class pyop2.versioning.Versioned

Bases: object

Versioning class for objects with mutable data

pyop2.versioning.modifies(method)

Decorator for methods that modify their instance’s data

pyop2.versioning.zeroes(method)

Decorator for methods that zero their instance’s data

pyop2.versioning.modifies_argn(n)

Decorator for a method that modifies its nth argument

Parameters:n – the nth argument to the method (not including self) counting from 0.
pyop2.versioning.modifies_arguments(func)

Decorator for functions that modify their arguments’ data

class pyop2.versioning.CopyOnWrite

Bases: object

Class that overrides the duplicate method and performs the actual copy operation when either the original or the copy has been written. Classes that inherit from CopyOnWrite need to provide the methods:

_cow_actual_copy(self, src):
Performs an actual copy of src’s data to self
_cow_shallow_copy(self):
Returns a shallow copy of the current object, e.g. the data handle should be the same. (optionally, otherwise the standard copy.copy() is used)
duplicate()

pyop2.void module

This module contains stub implementations of core classes which are used to provide useful error messages if the user invokes them before calling pyop2.op2.init()

class pyop2.void.Access(*args, **kwargs)

Bases: object

class pyop2.void.Set(*args, **kwargs)

Bases: object

class pyop2.void.Halo(*args, **kwargs)

Bases: object

class pyop2.void.Kernel(*args, **kwargs)

Bases: object

class pyop2.void.Dat(*args, **kwargs)

Bases: object

class pyop2.void.Mat(*args, **kwargs)

Bases: object

class pyop2.void.Const(*args, **kwargs)

Bases: object

class pyop2.void.Global(*args, **kwargs)

Bases: object

class pyop2.void.Map(*args, **kwargs)

Bases: object

class pyop2.void.Sparsity(*args, **kwargs)

Bases: object

class pyop2.void.Solver(*args, **kwargs)

Bases: object

pyop2.void.par_loop(*args, **kwargs)
pyop2.void.solve(*args, **kwargs)

Module contents

PyOP2 is a library for parallel computations on unstructured meshes and delivers performance-portability across a range of platforms:

  • multi-core CPU (sequential, OpenMP, OpenCL and MPI)
  • GPU (CUDA and OpenCL)