Software Structure

This program provides an abstraction layer for linear algebra operations and an inversion system working with that abstraction layer.

Simplified overview

The simplified main structure is explained here for the typical use case.

        ---
config:
  theme: redux-color
---
swimlane-beta TD
  subgraph core [Core]
    dat["(1) dat = DataProvider(...)"]
    inv["(2) inv = Invertor(dat.y, dat.H, dat.R, ...)"]
    del["(3) del dat"]
    solvec["(4) inv.solve()"]
    save["(5) save to netCDF"]
  end
  subgraph Invertor
    invi[Invertor]
    solvei["solve()"]
    cost["cost(), cost_grad(), cost_hess()"]
  end
  subgraph main [Linear algebra and DataProvider on main process]
    datm[DataProvider: Read input coordinates; Split observation space; Instruct workers]
    lam[y, H, R]
  end
  subgraph worker [Linear algebra and DataProvider on worker process]
    datw["Worker DataProvider\n(reads input data)"]
    law["Worker y, H, R\n(computation intensive tasks)"]
  end
  dat --> datm
  datm -->|initializes, owns, cleans up| datw
  datm --->|creates| lam
  datw --->|creates| law
  del --x datm
  solvec === solvei --->|uses| cost
  cost -->|uses| lam
  lam -->|owns, controls| law
  inv --> invi --- solvei
  invi -->|takes ownership| lam
  dat ----> inv ----> del ----> solvec ----> save
  style dat stroke:#f00
  style del stroke:#f00
  style datm stroke:#f00
  style datw stroke:#f00
  style worker fill:#eee,stroke:#aaa
  linkStyle 4 stroke:#f00,stroke:stroke-dasharray: 0 0 8 4
  linkStyle 0 stroke:#00f
  linkStyle 1 stroke:#00f
  linkStyle 8 stroke:#00f
  linkStyle 9 stroke:#00f
  linkStyle 11 stroke:#00f
    

Fig. 1 Simplified DUBFI program flow when using the linear algebra implementation mpipad. The four columns distinguish parts of the program that use different abstraction layers. The left column marks the core module (dubfi.core) with five steps of the main program. The Bayesian inversion solver (second column, dubfi.inversion) contains the mathematical formulation of the inversion problem. It uses abstract linear algebra types. The implementation of these types (third column, dubfi.linalg) delegates the numerically expensive tasks to worker processes (right column). Blue arrows indicate ownership and red color marks objects that are deleted in step (3) after reading the input data and before running the inversion.

We follow the reduced main program flow in Fig. 1.

  1. When starting the program, the main function (dubfi.core.core.run_inversion(), 1st column) first creates the DataProvider object (dubfi.dataprovider.generic.AbstractDataProvider, 3rd column). This object is responsible for reading the input data and providing all required variables in observation space: The model-observation mismatch vector y, the observation operator H, and the error covariance matrix R of y (all in 3rd column). When using the mpipad linear algebra implementation (which is the default), the objects in the 3rd column delegate their work to worker processes (4th column).

  2. Using y, H and R from the data provider, the main function creates an dubfi.inversion.inversion.Invertor object. The invertor takes ownership of y, H and R.

  3. The data provider is deleted. This deletes also the worker process data provider.

  4. The invertor solves the Bayesian inversion problem numerically. It works with y, H and R using the abstract linear algebra interface (implementation in 3rd column). Thus, for the invertor it is irrelevant that the data of y, H and R are distributed over many worker processes (4th column).

  5. When the inversion problem is solved, the main function saves the result.

The full program involves more steps such as reading the configuration, checking existing output files, computing a first guess for the numerical solver, looping over multiple values of norm_prefactor, saving intermediate results, and saving additional diagnostics. Many details are left out, for example the distribution of the state space to the worker processes. But the main idea of DUBFI is depicted in Fig. 1.

Linear Algebra

The modules dubfi.linalg.types and dubfi.linalg.generic provide abstract types for vectors, linear operators, and parametrized vectors or linear operators. The inversion operates on this abstraction layer, i.e., it can use any implementation of the linear algebra. Linear algebra implementations based on this abstraction layer shall be subpackages of dubfi.linalg.

Data Providers

The subpackage dubfi.dataprovider contains functions for reading and filtering input data. The abstract interface to observation data for the inversion system is defined in the module dubfi.dataprovider.generic. The implementation of the data provider depends on the linear algebra implementation. This allows asynchronous reading of data for parallelized linear algebra implementations. Each linear algebra implementation shall therefore provide its own subpackage of dubfi.dataprovider.

Generic Inversion

The equations solved by the inversion are described in detail in the scientific documentation. The inversion mainly consists of optimizing a cost function. The cost function, its gradient and Hesse matrix are implemented in dubfi.inversion.inversion using the abstract linear algebra interface. Other modules in dubfi.inversion implement different a-priori probability density functions for the Bayesian inversion.