GOcean Examples#
Example 1: Loop transformations#
Examples of applying various transformations (loop fusion, OpenMP, OpenMP Taskloop, OpenACC, OpenCL) to the semi-PSyKAl’d version of the Shallow benchmark. (“semi” because not all kernels are called from within invoke()’s.) Also includes an example of generating a DAG from an InvokeSchedule.
Example 2: OpenACC#
This is a simple but complete example of using PSyclone to enable an
application to run on a GPU by adding OpenACC directives. A Makefile
is included which will use PSyclone to generate the PSy code and
transformed kernels and then compile the application. This compilation
requires that the dl_esm_inf library
be installed/available - it is provided as a Git submodule of the PSyclone
project (see Installation in the Developers’ Guide
for details on working with submodules).
The supplied Makefile also provides a second, profile target which
performs the same OpenACC transformations but then encloses the whole
of the resulting PSy layer in a profiling region. By linking this with
the PSyclone NVTX profiling wrapper (and the NVTX library itself), the
resulting application can be profiled using NVIDIA’s nsys tool.
Example 3: OpenCL#
Example of the use of PSyclone to generate an OpenCL driver version of
the PSy layer and OpenCL kernels. The Makefile in this example provides
a target (make compile-ocl) to compile the generated OpenCL code. This
requires an OpenCL implementation installed in the system. Read the README
provided in the example folder for more details about how to compile and
execute the generated OpenCL code.
Example 4: Kernels containing use statements#
Transforming kernels for use with either OpenACC or OpenCL requires
that we handle those that access data and/or routines via module
use statements. This example shows the various forms for which
support is being implemented. Although there is support for converting
global-data accesses into kernel arguments, PSyclone does not yet support
nested use of modules (i.e. data accessed via a module that in turn
imports that symbol from another module) and kernels that call other
kernels (Issue #342).
Example 5: PSyData#
This directory contains all examples that use the PSyData API. At this stage there are three runnable examples:
Example 5.1: Kernel data extraction#
This example shows the use of kernel data extraction in PSyclone.
It instruments each of the two invokes in the example program
with the PSyData-based kernel extraction code. Detailed compilation
instructions are in the README.md file, including how to switch
from using the stand-alone extraction library to the NetCDF-based one
(see Extraction Libraries for details).
The Makefile in this example will create the binary that extracts
the data at run time, as well as two driver programs that can read in
the extracted data, call the kernel, and compare the results. These
driver programs are independent of the dl_esm_inf infrastructure library.
These drivers can only read the corresponding file format, i.e. a NetCDF
driver program cannot read in extraction data that is based on Fortran IO
and vice versa.
Example 5.2: Profiling#
This example shows how to use the profiling support in PSyclone.
It instruments two invoke statements and can link in with any
of the following profiling wrapper libraries: template,
simple_timer, dl_timer, TAU, Vernier, and DrHook (see
Interface to Third Party Profiling Tools). The README.md
file contains detailed instructions on how to build the
different executables. By default (i.e. just using make
without additional parameters) it links in with the
template profiling library included in PSyclone. This library just
prints out the name of the module and region before and after each
invoke is executed. This example can actually be executed to
test the behaviour of the various profiling wrappers, and is
also useful if you want to develop your own wrapper libraries.
Example 5.3: Read-only-verification#
This example shows the use of read-only-verification with PSyclone.
It instruments each of the two invokes in the example program
with the PSyData-based read-only-verification code.
It uses the dl_esm_inf-specific read-only-verification library
(lib/read_only/dl_esm_inf/).
Note
The update_field_mod subroutine contains some very
buggy and non-standard code to change the value of some
read-only variables and fields, even though the variables
are all declared with
intent(in). It uses the addresses of variables and
then out-of-bound writes to a writeable array to
actually overwrite the read-only variables. Using
array bounds checking at runtime will be triggered by these
out-of-bound writes.
The Makefile in this example will link with the compiled
read-only-verification library. You can execute the created
binary and it will print two warnings about modified
read-only variables:
--------------------------------------
Double precision field b_fld has been modified in main : update
Original checksum: 4611686018427387904
New checksum: 4638355772470722560
--------------------------------------
--------------------------------------
Double precision variable z has been modified in main : update
Original value: 1.0000000000000000
New value: 123.00000000000000
--------------------------------------
Example 5.4: Value Range Check#
This example shows the use of valid-number verification with PSyclone.
It instruments each of the two invokes in the example program
with the PSyData-based Value-Range-Check code.
It uses the dl_esm_inf-specific value range check library
(lib/value_range_check/dl_esm_inf/).
Note
The update_field_mod subroutine contains code
that will trigger a division by 0 to create NaNs. If
the compiler happens to add code that handles floating point
exceptions , this will take effect before the value testing
is done by the PSyData-based verification code.
The Makefile in this example will link with the compiled
value_range_check library. You can then execute the binary
and enable the value range check by setting environments
(see value range check for
details).
PSYVERIFY__main__init__b_fld=2:3 ./value_range_check
...
PSyData: Variable b_fld has the value 0.0000000000000000 at index/indices 6 1 in module 'main', region 'init', which is not between '2.0000000000000000' and '3.0000000000000000'.
...
PSyData: Variable a_fld has the invalid value 'Inf' at index/indices 1 1 in module 'main', region 'update'.
As indicated in value range check, you can also check a variable in all kernels of a module, or in any instrumented code region (since the example has only one module, both settings below will create the same warnings):
PSYVERIFY__main__b_fld=2:3 ./value_range_check
PSYVERIFY__b_fld=2:3 ./value_range_check
...
PSyData: Variable b_fld has the value 0.0000000000000000 at index/indices 6 1 in module 'main', region 'init', which is not between '2.0000000000000000' and '3.0000000000000000'.
...
PSyData: Variable b_fld has the value 0.0000000000000000 at index/indices 6 1 in module 'main', region 'update', which is not between '2.0000000000000000' and '3.0000000000000000'.
Notice that now a warning is created for both kernels: init and update.
Support for checking arbitrary Fortran code is tracked as issue #2741.
Example 6: PSy-layer Code Creation using PSyIR#
This example informs the development of the code generation of PSy-layer code using the PSyIR language backends.