Algorithm layer¶
In the PSyKAl separation of concerns, the Algorithm layer specifies the algorithm that the scientist would like to run (in terms of calls to kernel routines and Built-in operations) and logically operates on full fields. Algorithm code in the algorithm layer is not allowed to include any parallelisation calls or directives and passes datatypes specified by the particular API.
API¶
The Algorithm layer is forbidden from calling the Kernel layer
directly. In PSyclone, if the programmer would like to call a Kernel
routine or a Built-in operation from the algorithm layer they must use
the invoke
call (which is common to all APIs). The invoke
call is not necessary (and indeed will not work) if the PSy layer is
written manually.
To make an invoke
call, the algorithm layer developer adds one or more
call invoke()
statements
to their code and within the content of the invoke
call they add a
reference to the required Kernel/Built-in and the data to pass to it. For
example,
...
call invoke(integrate_one_kernel(arg1,arg2))
...
For more information on the concept of Built-in operations see the Built-ins Section. Details of which operations are supported for a specific API are given in the documentation of that API.
The algorithm layer can consist of an arbitrary number of files
containing fortran code, any of which may contain as many invoke()
calls as is required. PSyclone is applied to an individual algorithm
layer file and must therefore be run multiple times if multiple files
containing invoke()
calls exist in the algorithm layer.
The algorithm developer is also able to reference more than one Kernel/Built-in within an invoke. In fact this feature is encouraged for performance reasons. As a general guideline the developer should aim to use as few invokes as possible with as many Kernel references within them as is possible. The reason for this is that it allows for greater freedom for optimisation in the PSy layer as PSy layer optimisations are limited to the contents of individual invoke calls - PSyclone currently does not attempt to optimise the PSy layer over multiple invoke calls.
As well as generating the PSy layer code, PSyclone modifies the
Algorithm layer code, replacing invoke
calls with calls to the
generated PSy layer so that the algorithm code is compilable and
linkable to the PSy layer and adding in the appropriate use
statement. For example, the above integrate_one_kernel
invoke is
translated into something like the following:
...
use psy, only : invoke_0_integrate_one_kernel
...
call invoke_0_integrate_one_kernel(arg1,arg2)
...
In addition, any use
statements importing Kernels
(integrate_one_kernel
in this example) are removed because they
are no longer required in the transformed algorithm code.
You may have noticed from other examples in this guide that an
algorithm specification in an invoke call references the metadata
type
in an invoke call, not the code
directly; this is by
design.
For example, in the invoke call below, integrate_one_kernel
is
used.
...
call invoke(integrate_one_kernel(arg1,arg2))
...
integrate_one_kernel
is the name of the metadata type in the module, not
the name of the subroutine in the Kernel …
module integrate_one_module
...
type, extends(kernel_type) :: integrate_one_kernel
...
end type
...
contains
...
subroutine integrate_one_code(...)
...
end subroutine integrate_one_code
...
end module integrate_one_module
Named Invokes¶
PSyclone permits the user to optionally specify a label for an invoke call like so:
...
call invoke(integrate_one_kernel(arg1,arg2), &
name="compute_something")
...
The name
argument to the invoke call is optional. If supplied it
must be a string literal. The content of this string is used in naming
the corresponding
PSy-layer routine generated by PSyclone. So, for the above example,
the generated PSy-layer subroutine will be named
“invoke_compute_something”. Each invoke label must currently be unique
within an Algorithm source file. Note that, in keeping with the
Fortran language, labels are not case-sensitive and must be valid Fortran
names (e.g. name="compute(1)"
is invalid). In the future it is
intended that the labelling of invokes will help to support
invoke-specific optimisations to be applied as well as enabling more
readable profiling output. It may also be used to instruct PSyclone to
just generate a single subroutine to implement all invokes that share
the same label.
Limitations¶
In order to re-write the Algorithm layer, as just described, PSyclone must obviously be able to parse the invoke calls. Since the Fortran expression parser used by PSyclone is relatively simple, this means there are limitations on what Fortran may be used when specifying kernel arguments in an invoke call. Since these limitations can have a direct impact on the natural science code, the PSyclone developers endeavour to keep them to a minimum.
The current list of known limitations/restrictions on the form of kernel arguments within an invoke is:
No arithmetic expressions (e.g.
kernel_type(a+b)
orkernel_type(-a)
)No named (optional) arguments (e.g.
kernel_type(fn(my_arg=a))
)
If you encounter any other limitations (or have a burning desire to use one of the above forms) then please contact the PSyclone developers.