Developer Guide

A Brief Overview of the PyFR Framework

Where to Start

The symbolic link pyfr.scripts.pyfr points to the script pyfr.scripts.main, which is where it all starts! Specifically, the function process_run calls the function _process_common, which in turn calls the function get_solver, returning an Integrator – a composite of a Controller and a Stepper. The Integrator has a method named run, which is then called to run the simulation.

Controller

A Controller acts to advance the simulation in time. Specifically, a Controller has a method named advance_to which advances a System to a specified time. There are three types of Controller available in PyFR 1.5.0:

pyfr.integrators.std.controllers.StdNoneController[source]
  1. _accept_step (dt, idxcurr, err=None)
  2. _add (*args)
  3. _controller_needs_errest
  4. _get_axnpby_kerns (n, subdims=None)
  5. _get_gndofs ()
  6. _get_kernels (name, nargs, **kwargs)
  7. _get_plugins ()
  8. _get_reg_banks (nreg)
  9. _prepare_reg_banks (*bidxes)
  10. _reject_step (dt, idxold, err=None)
  11. _stepper_has_errest
  12. _stepper_nfevals
  13. _stepper_nregs
  14. _stepper_order
  15. advance_to (t)[source]
  16. call_plugin_dt (dt)
  17. cfgmeta
  18. collect_stats (stats)
  19. controller_name = 'none'
  20. formulation = 'std'
  21. nsteps
  22. run ()
  23. soln
  24. step (t, dt)
pyfr.integrators.std.controllers.StdPIController[source]
  1. _accept_step (dt, idxcurr, err=None)
  2. _add (*args)
  3. _controller_needs_errest
  4. _errest (x, y, z)[source]
  5. _get_axnpby_kerns (n, subdims=None)
  6. _get_errest_kerns ()[source]
  7. _get_gndofs ()
  8. _get_kernels (name, nargs, **kwargs)
  9. _get_plugins ()
  10. _get_reg_banks (nreg)
  11. _prepare_reg_banks (*bidxes)
  12. _reject_step (dt, idxold, err=None)
  13. _stepper_has_errest
  14. _stepper_nfevals
  15. _stepper_nregs
  16. _stepper_order
  17. advance_to (t)[source]
  18. call_plugin_dt (dt)
  19. cfgmeta
  20. collect_stats (stats)
  21. controller_name = 'pi'
  22. formulation = 'std'
  23. nsteps
  24. run ()
  25. soln
  26. step (t, dt)
pyfr.integrators.dual.controllers.DualNoneController[source]
  1. _accept_step (dt, idxcurr)
  2. _add (*args)
  3. _dual_time_source ()
  4. _get_axnpby_kerns (n, subdims=None)
  5. _get_errest_kerns ()[source]
  6. _get_gndofs ()
  7. _get_kernels (name, nargs, **kwargs)
  8. _get_plugins ()
  9. _get_reg_banks (nreg)
  10. _prepare_reg_banks (*bidxes)
  11. _resid (x, y)[source]
  12. _source_regidx
  13. _stepper_nfevals
  14. _stepper_nregs
  15. _stepper_order
  16. _stepper_regidx
  17. advance_to (t)[source]
  18. call_plugin_dt (dt)
  19. cfgmeta
  20. collect_stats (stats)
  21. controller_name = 'none'
  22. finalise_step (currsoln)
  23. formulation = 'dual'
  24. nsteps
  25. run ()
  26. soln
  27. step (t, dt)

Types of Controller are related via the following inheritance diagram:

Inheritance diagram of pyfr.integrators.std.controllers, pyfr.integrators.dual.controllers

Stepper

A Stepper acts to advance the simulation by a single time-step. Specifically, a Stepper has a method named step which advances a System by a single time-step. There are 11 types of Stepper available in PyFR 1.5.0:

pyfr.integrators.std.steppers.StdEulerStepper[source]
  1. _add (*args)
  2. _controller_needs_errest
  3. _get_axnpby_kerns (n, subdims=None)
  4. _get_gndofs ()
  5. _get_kernels (name, nargs, **kwargs)
  6. _get_plugins ()
  7. _get_reg_banks (nreg)
  8. _prepare_reg_banks (*bidxes)
  9. _stepper_has_errest
  10. _stepper_nfevals
  11. _stepper_nregs
  12. _stepper_order
  13. advance_to (t)
  14. call_plugin_dt (dt)
  15. cfgmeta
  16. collect_stats (stats)
  17. formulation = 'std'
  18. nsteps
  19. run ()
  20. soln
  21. step (t, dt)[source]
  22. stepper_name = 'euler'
pyfr.integrators.std.steppers.StdRK4Stepper[source]
  1. _add (*args)
  2. _controller_needs_errest
  3. _get_axnpby_kerns (n, subdims=None)
  4. _get_gndofs ()
  5. _get_kernels (name, nargs, **kwargs)
  6. _get_plugins ()
  7. _get_reg_banks (nreg)
  8. _prepare_reg_banks (*bidxes)
  9. _stepper_has_errest
  10. _stepper_nfevals
  11. _stepper_nregs
  12. _stepper_order
  13. advance_to (t)
  14. call_plugin_dt (dt)
  15. cfgmeta
  16. collect_stats (stats)
  17. formulation = 'std'
  18. nsteps
  19. run ()
  20. soln
  21. step (t, dt)[source]
  22. stepper_name = 'rk4'
pyfr.integrators.std.steppers.StdRK34Stepper[source]
  1. _add (*args)
  2. _controller_needs_errest
  3. _get_axnpby_kerns (n, subdims=None)
  4. _get_gndofs ()
  5. _get_kernels (name, nargs, **kwargs)
  6. _get_plugins ()
  7. _get_reg_banks (nreg)
  8. _prepare_reg_banks (*bidxes)
  9. _stepper_has_errest
  10. _stepper_nfevals
  11. _stepper_nregs
  12. _stepper_order
  13. a = [0.32416573882874605, 0.5570978645055429, -0.08605491431272755]
  14. advance_to (t)
  15. b = [0.10407986927510238, 0.6019391368822611, 2.9750900268840206, -2.681109033041384]
  16. bhat = [0.3406814840808433, 0.09091523008632837, 2.866496742725443, -2.298093456892615]
  17. call_plugin_dt (dt)
  18. cfgmeta
  19. collect_stats (stats)
  20. formulation = 'std'
  21. nsteps
  22. run ()
  23. soln
  24. step (t, dt)
  25. stepper_name = 'rk34'
pyfr.integrators.std.steppers.StdRK45Stepper[source]
  1. _add (*args)
  2. _controller_needs_errest
  3. _get_axnpby_kerns (n, subdims=None)
  4. _get_gndofs ()
  5. _get_kernels (name, nargs, **kwargs)
  6. _get_plugins ()
  7. _get_reg_banks (nreg)
  8. _prepare_reg_banks (*bidxes)
  9. _stepper_has_errest
  10. _stepper_nfevals
  11. _stepper_nregs
  12. _stepper_order
  13. a = [0.22502245872571303, 0.5440433129514047, 0.14456824349399464, 0.7866643421983568]
  14. advance_to (t)
  15. b = [0.05122930664033915, 0.3809548257264019, -0.3733525963923833, 0.5925012850263623, 0.34866717899927996]
  16. bhat = [0.13721732210321927, 0.19188076232938728, -0.2292067211595315, 0.6242946765438954, 0.27581396018302956]
  17. call_plugin_dt (dt)
  18. cfgmeta
  19. collect_stats (stats)
  20. formulation = 'std'
  21. nsteps
  22. run ()
  23. soln
  24. step (t, dt)
  25. stepper_name = 'rk45'
pyfr.integrators.std.steppers.StdTVDRK3Stepper[source]
  1. _add (*args)
  2. _controller_needs_errest
  3. _get_axnpby_kerns (n, subdims=None)
  4. _get_gndofs ()
  5. _get_kernels (name, nargs, **kwargs)
  6. _get_plugins ()
  7. _get_reg_banks (nreg)
  8. _prepare_reg_banks (*bidxes)
  9. _stepper_has_errest
  10. _stepper_nfevals
  11. _stepper_nregs
  12. _stepper_order
  13. advance_to (t)
  14. call_plugin_dt (dt)
  15. cfgmeta
  16. collect_stats (stats)
  17. formulation = 'std'
  18. nsteps
  19. run ()
  20. soln
  21. step (t, dt)[source]
  22. stepper_name = 'tvd-rk3'
pyfr.integrators.dual.steppers.DualBDF2Stepper[source]
  1. _add (*args)
  2. _dual_time_source
  3. _get_axnpby_kerns (n, subdims=None)
  4. _get_gndofs ()
  5. _get_kernels (name, nargs, **kwargs)
  6. _get_plugins ()
  7. _get_reg_banks (nreg)
  8. _prepare_reg_banks (*bidxes)
  9. _source_regidx
  10. _stepper_nfevals
  11. _stepper_nregs
  12. _stepper_order
  13. _stepper_regidx
  14. advance_to (t)
  15. call_plugin_dt (dt)
  16. cfgmeta
  17. collect_stats (stats)
  18. finalise_step (currsoln)
  19. formulation = 'dual'
  20. nsteps
  21. run ()
  22. soln
  23. step (t, dt)
  24. stepper_name = 'bdf2'
pyfr.integrators.dual.steppers.DualBDF3Stepper[source]
  1. _add (*args)
  2. _dual_time_source
  3. _get_axnpby_kerns (n, subdims=None)
  4. _get_gndofs ()
  5. _get_kernels (name, nargs, **kwargs)
  6. _get_plugins ()
  7. _get_reg_banks (nreg)
  8. _prepare_reg_banks (*bidxes)
  9. _source_regidx
  10. _stepper_nfevals
  11. _stepper_nregs
  12. _stepper_order
  13. _stepper_regidx
  14. advance_to (t)
  15. call_plugin_dt (dt)
  16. cfgmeta
  17. collect_stats (stats)
  18. finalise_step (currsoln)
  19. formulation = 'dual'
  20. nsteps
  21. run ()
  22. soln
  23. step (t, dt)
  24. stepper_name = 'bdf3'
pyfr.integrators.dual.steppers.DualBackwardEulerStepper[source]
  1. _add (*args)
  2. _dual_time_source
  3. _get_axnpby_kerns (n, subdims=None)
  4. _get_gndofs ()
  5. _get_kernels (name, nargs, **kwargs)
  6. _get_plugins ()
  7. _get_reg_banks (nreg)
  8. _prepare_reg_banks (*bidxes)
  9. _source_regidx
  10. _stepper_nfevals
  11. _stepper_nregs
  12. _stepper_order
  13. _stepper_regidx
  14. advance_to (t)
  15. call_plugin_dt (dt)
  16. cfgmeta
  17. collect_stats (stats)
  18. finalise_step (currsoln)
  19. formulation = 'dual'
  20. nsteps
  21. run ()
  22. soln
  23. step (t, dt)
  24. stepper_name = 'backward-euler'
pyfr.integrators.dual.pseudosteppers.DualPseudoRK4Stepper[source]
  1. _add (*args)
  2. _add_with_dts (*args, c)
  3. _dual_time_source ()
  4. _get_axnpby_kerns (n, subdims=None)
  5. _get_gndofs ()
  6. _get_kernels (name, nargs, **kwargs)
  7. _get_plugins ()
  8. _get_reg_banks (nreg)
  9. _prepare_reg_banks (*bidxes)
  10. _pseudo_stepper_nregs
  11. _pseudo_stepper_order
  12. _source_regidx
  13. _stepper_nfevals
  14. _stepper_nregs
  15. _stepper_order
  16. _stepper_regidx
  17. advance_to (t)
  18. call_plugin_dt (dt)
  19. cfgmeta
  20. collect_stats (stats)
  21. finalise_step (currsoln)
  22. formulation = 'dual'
  23. nsteps
  24. pseudo_stepper_name = 'rk4'
  25. run ()
  26. soln
  27. step (t, dt, dtau)[source]
pyfr.integrators.dual.pseudosteppers.DualPseudoTVDRK3Stepper[source]
  1. _add (*args)
  2. _add_with_dts (*args, c)
  3. _dual_time_source ()
  4. _get_axnpby_kerns (n, subdims=None)
  5. _get_gndofs ()
  6. _get_kernels (name, nargs, **kwargs)
  7. _get_plugins ()
  8. _get_reg_banks (nreg)
  9. _prepare_reg_banks (*bidxes)
  10. _pseudo_stepper_nregs
  11. _pseudo_stepper_order
  12. _source_regidx
  13. _stepper_nfevals
  14. _stepper_nregs
  15. _stepper_order
  16. _stepper_regidx
  17. advance_to (t)
  18. call_plugin_dt (dt)
  19. cfgmeta
  20. collect_stats (stats)
  21. finalise_step (currsoln)
  22. formulation = 'dual'
  23. nsteps
  24. pseudo_stepper_name = 'tvd-rk3'
  25. run ()
  26. soln
  27. step (t, dt, dtau)[source]
pyfr.integrators.dual.pseudosteppers.DualPseudoEulerStepper[source]
  1. _add (*args)
  2. _add_with_dts (*args, c)
  3. _dual_time_source ()
  4. _get_axnpby_kerns (n, subdims=None)
  5. _get_gndofs ()
  6. _get_kernels (name, nargs, **kwargs)
  7. _get_plugins ()
  8. _get_reg_banks (nreg)
  9. _prepare_reg_banks (*bidxes)
  10. _pseudo_stepper_nregs
  11. _pseudo_stepper_order
  12. _source_regidx
  13. _stepper_nfevals
  14. _stepper_nregs
  15. _stepper_order
  16. _stepper_regidx
  17. advance_to (t)
  18. call_plugin_dt (dt)
  19. cfgmeta
  20. collect_stats (stats)
  21. finalise_step (currsoln)
  22. formulation = 'dual'
  23. nsteps
  24. pseudo_stepper_name = 'euler'
  25. run ()
  26. soln
  27. step (t, dt, dtau)[source]

Types of Stepper are related via the following inheritance diagram:

Inheritance diagram of pyfr.integrators.dual.steppers, pyfr.integrators.dual.pseudosteppers, pyfr.integrators.std.steppers

System

A System holds information/data for the system, including Elements, Interfaces, and the Backend with which the simulation is to run. A System has a method named rhs, which obtains the divergence of the flux (the ‘right-hand-side’) at each solution point. The method rhs invokes various kernels which have been pre-generated and loaded into queues. A System also has a method named _gen_kernels which acts to generate all the kernels required by a particular System. A kernel is an instance of a ‘one-off’ class with a method named run that implements the required kernel functionality. Individual kernels are produced by a kernel provider. PyFR 1.5.0 has various types of kernel provider. A Pointwise Kernel Provider produces point-wise kernels such as Riemann solvers and flux functions etc. These point-wise kernels are specified using an in-built platform-independent templating language derived from Mako, henceforth referred to as PyFR-Mako. There are two types of System available in PyFR 1.5.0:

pyfr.solvers.euler.system.EulerSystem[source]
  1. _gen_kernels (eles, iint, mpiint, bcint)
  2. _gen_queues ()
  3. _load_bc_inters (rallocs, mesh, elemap)
  4. _load_eles (rallocs, mesh, initsoln, nreg, nonce)
  5. _load_int_inters (rallocs, mesh, elemap)
  6. _load_mpi_inters (rallocs, mesh, elemap)
  7. _nonce_seq = count(0)
  8. _nqueues = 2
  9. bbcinterscls
  10. ele_scal_upts (idx)
  11. elementscls
  12. filt (uinoutbank)
  13. intinterscls
  14. mpiinterscls
  15. name = 'euler'
  16. rhs (t, uinbank, foutbank)
pyfr.solvers.navstokes.system.NavierStokesSystem[source]
  1. _gen_kernels (eles, iint, mpiint, bcint)
  2. _gen_queues ()
  3. _load_bc_inters (rallocs, mesh, elemap)
  4. _load_eles (rallocs, mesh, initsoln, nreg, nonce)
  5. _load_int_inters (rallocs, mesh, elemap)
  6. _load_mpi_inters (rallocs, mesh, elemap)
  7. _nonce_seq = count(0)
  8. _nqueues = 2
  9. bbcinterscls
  10. ele_scal_upts (idx)
  11. elementscls
  12. filt (uinoutbank)
  13. intinterscls
  14. mpiinterscls
  15. name = 'navier-stokes'
  16. rhs (t, uinbank, foutbank)

Types of System are related via the following inheritance diagram:

Inheritance diagram of pyfr.solvers.navstokes.system, pyfr.solvers.euler.system

Elements

An Elements holds information/data for a group of elements. There are two types of Elements available in PyFR 1.5.0:

pyfr.solvers.euler.elements.EulerElements[source]
  1. _gen_pnorm_fpts ()
  2. _mag_pnorm_fpts = None
  3. _norm_pnorm_fpts = None
  4. _ploc_in_src_exprs = None
  5. _scratch_bufs
  6. _smats_djacs_mpts = None
  7. _soln_in_src_exprs = None
  8. _src_exprs = None
  9. _srtd_face_fpts = None
  10. con_to_pri (cons, cfg)
  11. convarmap = {2: ['rho', 'rhou', 'rhov', 'E'], 3: ['rho', 'rhou', 'rhov', 'rhow', 'E']}
  12. dualcoeffs = {2: ['rho', 'rhou', 'rhov', 'E'], 3: ['rho', 'rhou', 'rhov', 'rhow', 'E']}
  13. formulations = ['std', 'dual']
  14. get_mag_pnorms (eidx, fidx)
  15. get_mag_pnorms_for_inter (eidx, fidx)
  16. get_norm_pnorms (eidx, fidx)
  17. get_norm_pnorms_for_inter (eidx, fidx)
  18. get_ploc_for_inter (eidx, fidx)
  19. get_scal_fpts_for_inter (eidx, fidx)
  20. get_vect_fpts_for_inter (eidx, fidx)
  21. opmat (expr)
  22. ploc_at (name)
  23. ploc_at_np (name)
  24. plocfpts = None
  25. pri_to_con (pris, cfg)
  26. privarmap = {2: ['rho', 'u', 'v', 'p'], 3: ['rho', 'u', 'v', 'w', 'p']}
  27. rcpdjac_at (name)
  28. rcpdjac_at_np (name)
  29. set_backend (backend, nscalupts, nonce)[source]
  30. set_ics_from_cfg ()
  31. set_ics_from_soln (solnmat, solncfg)
  32. smat_at (name)
  33. smat_at_np (name)
  34. visvarmap = {2: {'pressure': ['p'], 'velocity': ['u', 'v'], 'density': ['rho']}, 3: {'pressure': ['p'], 'velocity': ['u', 'v', 'w'], 'density': ['rho']}}
pyfr.solvers.navstokes.elements.NavierStokesElements[source]
  1. _gen_pnorm_fpts ()
  2. _mag_pnorm_fpts = None
  3. _norm_pnorm_fpts = None
  4. _ploc_in_src_exprs = None
  5. _scratch_bufs
  6. _smats_djacs_mpts = None
  7. _soln_in_src_exprs = None
  8. _src_exprs = None
  9. _srtd_face_fpts = None
  10. con_to_pri (cons, cfg)
  11. convarmap = {2: ['rho', 'rhou', 'rhov', 'E'], 3: ['rho', 'rhou', 'rhov', 'rhow', 'E']}
  12. dualcoeffs = {2: ['rho', 'rhou', 'rhov', 'E'], 3: ['rho', 'rhou', 'rhov', 'rhow', 'E']}
  13. formulations = ['std', 'dual']
  14. get_artvisc_fpts_for_inter (eidx, fidx)
  15. get_mag_pnorms (eidx, fidx)
  16. get_mag_pnorms_for_inter (eidx, fidx)
  17. get_norm_pnorms (eidx, fidx)
  18. get_norm_pnorms_for_inter (eidx, fidx)
  19. get_ploc_for_inter (eidx, fidx)
  20. get_scal_fpts_for_inter (eidx, fidx)
  21. get_vect_fpts_for_inter (eidx, fidx)
  22. opmat (expr)
  23. ploc_at (name)
  24. ploc_at_np (name)
  25. plocfpts = None
  26. pri_to_con (pris, cfg)
  27. privarmap = {2: ['rho', 'u', 'v', 'p'], 3: ['rho', 'u', 'v', 'w', 'p']}
  28. rcpdjac_at (name)
  29. rcpdjac_at_np (name)
  30. set_backend (backend, nscalupts, nonce)[source]
  31. set_ics_from_cfg ()
  32. set_ics_from_soln (solnmat, solncfg)
  33. shockvar = 'rho'
  34. smat_at (name)
  35. smat_at_np (name)
  36. visvarmap = {2: {'pressure': ['p'], 'velocity': ['u', 'v'], 'density': ['rho']}, 3: {'pressure': ['p'], 'velocity': ['u', 'v', 'w'], 'density': ['rho']}}

Types of Elements are related via the following inheritance diagram:

Inheritance diagram of pyfr.solvers.navstokes.elements, pyfr.solvers.euler.elements

Interfaces

An Interfaces holds information/data for a group of interfaces. There are four types of (non-boundary) Interfaces available in PyFR 1.5.0:

pyfr.solvers.euler.inters.EulerIntInters[source]
  1. _const_mat (inter, meth)
  2. _gen_perm (lhs, rhs)
  3. _scal_view (inter, meth)
  4. _scal_xchg_view (inter, meth)
  5. _vect_view (inter, meth)
  6. _vect_xchg_view (inter, meth)
  7. _view (inter, meth, vshape=())
  8. _xchg_view (inter, meth, vshape=())
pyfr.solvers.euler.inters.EulerMPIInters[source]
  1. MPI_TAG = 2314
  2. _const_mat (inter, meth)
  3. _scal_view (inter, meth)
  4. _scal_xchg_view (inter, meth)
  5. _vect_view (inter, meth)
  6. _vect_xchg_view (inter, meth)
  7. _view (inter, meth, vshape=())
  8. _xchg_view (inter, meth, vshape=())
pyfr.solvers.navstokes.inters.NavierStokesIntInters[source]
  1. _const_mat (inter, meth)
  2. _gen_perm (lhs, rhs)
  3. _scal_view (inter, meth)
  4. _scal_xchg_view (inter, meth)
  5. _vect_view (inter, meth)
  6. _vect_xchg_view (inter, meth)
  7. _view (inter, meth, vshape=())
  8. _xchg_view (inter, meth, vshape=())
pyfr.solvers.navstokes.inters.NavierStokesMPIInters[source]
  1. MPI_TAG = 2314
  2. _const_mat (inter, meth)
  3. _scal_view (inter, meth)
  4. _scal_xchg_view (inter, meth)
  5. _vect_view (inter, meth)
  6. _vect_xchg_view (inter, meth)
  7. _view (inter, meth, vshape=())
  8. _xchg_view (inter, meth, vshape=())

Types of (non-boundary) Interfaces are related via the following inheritance diagram:

Inheritance diagram of pyfr.solvers.navstokes.inters.NavierStokesMPIInters, pyfr.solvers.navstokes.inters.NavierStokesIntInters, pyfr.solvers.euler.inters.EulerMPIInters, pyfr.solvers.euler.inters.EulerIntInters

Backend

A Backend holds information/data for a backend. There are four types of Backend available in PyFR 1.5.0:

pyfr.backends.cuda.base.CUDABackend[source]
  1. _malloc_impl (nbytes)[source]
  2. alias (obj, aobj)
  3. commit ()
  4. const_matrix (initval, extent=None, tags=set())
  5. kernel (name, *args, **kwargs)
  6. lookup = None
  7. malloc (obj, extent)
  8. matrix (ioshape, initval=None, extent=None, aliases=None, tags=set())
  9. matrix_bank (mats, initbank=0, tags=set())
  10. matrix_rslice (mat, p, q)
  11. name = 'cuda'
  12. queue ()
  13. runall (sequence)
  14. view (matmap, rmap, cmap, rstridemap=None, vshape=(), tags=set())
  15. xchg_matrix (ioshape, initval=None, extent=None, aliases=None, tags=set())
  16. xchg_matrix_for_view (view, tags=set())
  17. xchg_view (matmap, rmap, cmap, rstridemap=None, vshape=(), tags=set())
pyfr.backends.mic.base.MICBackend[source]
  1. _malloc_impl (nbytes)[source]
  2. alias (obj, aobj)
  3. commit ()
  4. const_matrix (initval, extent=None, tags=set())
  5. kernel (name, *args, **kwargs)
  6. lookup = None
  7. malloc (obj, extent)
  8. matrix (ioshape, initval=None, extent=None, aliases=None, tags=set())
  9. matrix_bank (mats, initbank=0, tags=set())
  10. matrix_rslice (mat, p, q)
  11. name = 'mic'
  12. queue ()
  13. runall (sequence)
  14. view (matmap, rmap, cmap, rstridemap=None, vshape=(), tags=set())
  15. xchg_matrix (ioshape, initval=None, extent=None, aliases=None, tags=set())
  16. xchg_matrix_for_view (view, tags=set())
  17. xchg_view (matmap, rmap, cmap, rstridemap=None, vshape=(), tags=set())
pyfr.backends.opencl.base.OpenCLBackend[source]
  1. _malloc_impl (nbytes)[source]
  2. alias (obj, aobj)
  3. commit ()
  4. const_matrix (initval, extent=None, tags=set())
  5. kernel (name, *args, **kwargs)
  6. lookup = None
  7. malloc (obj, extent)
  8. matrix (ioshape, initval=None, extent=None, aliases=None, tags=set())
  9. matrix_bank (mats, initbank=0, tags=set())
  10. matrix_rslice (mat, p, q)
  11. name = 'opencl'
  12. queue ()
  13. runall (sequence)
  14. view (matmap, rmap, cmap, rstridemap=None, vshape=(), tags=set())
  15. xchg_matrix (ioshape, initval=None, extent=None, aliases=None, tags=set())
  16. xchg_matrix_for_view (view, tags=set())
  17. xchg_view (matmap, rmap, cmap, rstridemap=None, vshape=(), tags=set())
pyfr.backends.openmp.base.OpenMPBackend[source]
  1. _malloc_impl (nbytes)[source]
  2. alias (obj, aobj)
  3. commit ()
  4. const_matrix (initval, extent=None, tags=set())
  5. kernel (name, *args, **kwargs)
  6. lookup = None
  7. malloc (obj, extent)
  8. matrix (ioshape, initval=None, extent=None, aliases=None, tags=set())
  9. matrix_bank (mats, initbank=0, tags=set())
  10. matrix_rslice (mat, p, q)
  11. name = 'openmp'
  12. queue ()
  13. runall (sequence)
  14. view (matmap, rmap, cmap, rstridemap=None, vshape=(), tags=set())
  15. xchg_matrix (ioshape, initval=None, extent=None, aliases=None, tags=set())
  16. xchg_matrix_for_view (view, tags=set())
  17. xchg_view (matmap, rmap, cmap, rstridemap=None, vshape=(), tags=set())

Types of Backend are related via the following inheritance diagram:

Inheritance diagram of pyfr.backends.cuda.base, pyfr.backends.opencl.base, pyfr.backends.openmp.base, pyfr.backends.mic.base

Pointwise Kernel Provider

A Pointwise Kernel Provider produces point-wise kernels. Specifically, a Pointwise Kernel Provider has a method named register, which adds a new method to an instance of a Pointwise Kernel Provider. This new method, when called, returns a kernel. A kernel is an instance of a ‘one-off’ class with a method named run that implements the required kernel functionality. The kernel functionality itself is specified using PyFR-Mako. Hence, a Pointwise Kernel Provider also has a method named _render_kernel, which renders PyFR-Mako into low-level platform-specific code. The _render_kernel method first sets the context for Mako (i.e. details about the Backend etc.) and then uses Mako to begin rendering the PyFR-Mako specification. When Mako encounters a pyfr:kernel an instance of a Kernel Generator is created, which is used to render the body of the pyfr:kernel. There are four types of Pointwise Kernel Provider available in PyFR 1.5.0:

pyfr.backends.cuda.provider.CUDAPointwiseKernelProvider[source]
  1. _build_arglst (dims, argn, argt, argdict)
  2. _build_kernel (name, src, argtypes)
  3. _instantiate_kernel (dims, fun, arglst)[source]
  4. _render_kernel (name, mod, tplargs)
  5. kernel_generator_cls
  6. register (mod)
pyfr.backends.mic.provider.MICPointwiseKernelProvider[source]
  1. _build_arglst (dims, argn, argt, argdict)
  2. _build_kernel (name, src, argtypes, restype=None)
  3. _instantiate_kernel (dims, fun, arglst)[source]
  4. _render_kernel (name, mod, tplargs)
  5. kernel_generator_cls
  6. register (mod)
pyfr.backends.opencl.provider.OpenCLPointwiseKernelProvider[source]
  1. _build_arglst (dims, argn, argt, argdict)
  2. _build_kernel (name, src, argtypes)
  3. _instantiate_kernel (dims, fun, arglst)[source]
  4. _render_kernel (name, mod, tplargs)
  5. kernel_generator_cls
  6. register (mod)
pyfr.backends.openmp.provider.OpenMPPointwiseKernelProvider[source]
  1. _build_arglst (dims, argn, argt, argdict)
  2. _build_kernel (name, src, argtypes, restype=None)
  3. _instantiate_kernel (dims, fun, arglst)[source]
  4. _render_kernel (name, mod, tplargs)
  5. kernel_generator_cls
  6. register (mod)

Types of Pointwise Kernel Provider are related via the following inheritance diagram:

Inheritance diagram of pyfr.backends.openmp.provider, pyfr.backends.cuda.provider, pyfr.backends.opencl.provider, pyfr.backends.mic.provider, pyfr.backends.base.kernels.BasePointwiseKernelProvider

Kernel Generator

A Kernel Generator renders the PyFR-Mako in a pyfr:kernel into low-level platform-specific code. Specifically, a Kernel Generator has a method named render, which applies Backend specific regex and adds Backend specific ‘boiler plate’ code to produce the low-level platform-specific source – which is compiled, linked, and loaded. There are four types of Kernel Generator available in PyFR 1.5.0:

pyfr.backends.cuda.generator.CUDAKernelGenerator[source]
  1. _deref_arg_array_1d (arg)
  2. _deref_arg_array_2d (arg)
  3. _deref_arg_view (arg)
  4. _render_body (body)
  5. _render_spec ()[source]
  6. argspec ()
  7. needs_ldim (arg)
  8. render ()[source]
pyfr.backends.mic.generator.MICKernelGenerator[source]
  1. _deref_arg_array_1d (arg)
  2. _deref_arg_array_2d (arg)
  3. _deref_arg_view (arg)
  4. _render_body (body)
  5. _render_spec_unpack ()[source]
  6. argspec ()
  7. needs_ldim (arg)
  8. render ()[source]
pyfr.backends.opencl.generator.OpenCLKernelGenerator[source]
  1. _deref_arg_array_1d (arg)
  2. _deref_arg_array_2d (arg)
  3. _deref_arg_view (arg)
  4. _render_body (body)
  5. _render_spec ()[source]
  6. argspec ()
  7. needs_ldim (arg)
  8. render ()[source]
pyfr.backends.openmp.generator.OpenMPKernelGenerator[source]
  1. _deref_arg_array_1d (arg)
  2. _deref_arg_array_2d (arg)
  3. _deref_arg_view (arg)
  4. _render_body (body)
  5. _render_spec ()[source]
  6. argspec ()
  7. needs_ldim (arg)
  8. render ()[source]

Types of Kernel Generator are related via the following inheritance diagram:

Inheritance diagram of pyfr.backends.cuda.generator.CUDAKernelGenerator, pyfr.backends.opencl.generator.OpenCLKernelGenerator, pyfr.backends.openmp.generator.OpenMPKernelGenerator, pyfr.backends.mic.generator.MICKernelGenerator

PyFR-Mako

PyFR-Mako Kernels

PyFR-Mako kernels are specifications of point-wise functionality that can be invoked directly from within PyFR. They are opened with a header of the form:

<%pyfr:kernel name='kernel-name' ndim='data-dimensionality' [argument-name='argument-intent argument-attribute argument-data-type' ...]>

where

  1. kernel-name — name of kernel

    string

  2. data-dimensionality — dimensionality of data

    int

  3. argument-name — name of argument

    string

  4. argument-intent — intent of argument

    in | out | inout

  5. argument-attribute — attribute of argument

    mpi | scalar | view

  6. argument-data-type — data type of argument

    string

and are closed with a footer of the form:

</%pyfr:kernel>
PyFR-Mako Macros

PyFR-Mako macros are specifications of point-wise functionality that cannot be invoked directly from within PyFR, but can be embedded into PyFR-Mako kernels. PyFR-Mako macros can be viewed as building blocks for PyFR-mako kernels. They are opened with a header of the form:

<%pyfr:macro name='macro-name' params='[parameter-name, ...]'>

where

  1. macro-name — name of macro

    string

  2. parameter-name — name of parameter

    string

and are closed with a footer of the form:

</%pyfr:macro>

PyFR-Mako macros are embedded within a kernel using an expression of the following form:

${pyfr.expand('macro-name', ['parameter-name', ...])};

where

  1. macro-name — name of the macro

    string

  2. parameter-name — name of parameter

    string

Syntax

Basic Functionality

Basic functionality can be expressed using a restricted subset of the C programming language. Specifically, use of the following is allowed:

  1. +,-,*,/ — basic arithmetic
  2. sin, cos, tan — basic trigonometric functions
  3. exp — exponential
  4. pow — power
  5. fabs — absolute value
  6. output = ( condition ? satisfied : unsatisfied ) — ternary if
  7. min — minimum
  8. max — maximum

However, conditional if statements, as well as for/while loops, are not allowed.

Expression Substitution

Mako expression substitution can be used to facilitate PyFR-Mako kernel specification. A Python expression expression prescribed thus ${expression} is substituted for the result when the PyFR-Mako kernel specification is interpreted at runtime.

Example:

E = s[${ndims - 1}]

Conditionals

Mako conditionals can be used to facilitate PyFR-Mako kernel specification. Conditionals are opened with % if condition: and closed with % endif. Note that such conditionals are evaluated when the PyFR-Mako kernel specification is interpreted at runtime, they are not embedded into the low-level kernel.

Example:

% if ndims == 2:
    fout[0][1] += t_xx;     fout[1][1] += t_xy;
    fout[0][2] += t_xy;     fout[1][2] += t_yy;
    fout[0][3] += u*t_xx + v*t_xy + ${-c['mu']*c['gamma']/c['Pr']}*T_x;
    fout[1][3] += u*t_xy + v*t_yy + ${-c['mu']*c['gamma']/c['Pr']}*T_y;
% endif

Loops

Mako loops can be used to facilitate PyFR-Mako kernel specification. Loops are opened with % for condition: and closed with % endfor. Note that such loops are unrolled when the PyFR-Mako kernel specification is interpreted at runtime, they are not embedded into the low-level kernel.

Example:

% for i in range(ndims):
    rhov[${i}] = s[${i + 1}];
    v[${i}] = invrho*rhov[${i}];
% endfor

Latest Release

PyFR 1.5.0:

  • Added dual time-stepping.
  • Added support for CUDA aware MPI.

Join our Team

Postdoctoral Position - GPU Accelerated High-Order Computational Fluid Dynamics
Summary: A fully funded Postdoctoral position is currently available. The project, will involve development of PyFR, an open-source high-order massively-parallel cross-platform CFD solver, as well as its application to solve a range of challenging unsteady flow problems. Candidates should hold, or expect to obtain, a PhD in a numerate discipline from a world-leading university.

Advert:

Twitter