OpenHMPP
OpenHMPP - programming standard for heterogeneous computing. Based on a set of compiler directives, standard is a programming model designed to handle hardware accelerators without the complexity associated with GPU programming. This approach based on directives has been implemented because they enable a loose relationship between an application code and the use of a hardware accelerator.
Introduction
The OpenHMPP directive-based programming model offers a syntax to offload computations on hardware accelerators and to optimize data movement to/from the hardware memory.The model is based on works initialized by , a common project from INRIA, CNRS, the University of Rennes 1 and the INSA of Rennes.
OpenHMPP concept
OpenHMPP is based on the concept of codelets, functions that can be remotely executed on HWAs.The OpenHMPP codelet concept
A codelet has the following properties:- It is a pure function.
- * It does not contain static or volatile variable declarations nor refer to any global variables except if these have been declared by a HMPP directive “resident”
- * It does not contain any function calls with an invisible body. This includes the use of libraries and system functions such as malloc, printf,...
- * Every function call must refer to a static pure function.
- It does not return any value.
- The number of arguments should be fixed.
- It is not recursive.
- Its parameters are assumed to be non-aliased.
- It does not contain callsite directives or other HMPP directives.
Codelet RPCs
HMPP provides synchronous and asynchronous RPC. Implementation of asynchronous operation is hardware dependent.HMPP Memory Model
HMPP considers two address spaces: the host processor one and the HWA memory.Directives concept
The OpenHMPP directives may be seen as “meta-information” added in the application source code. They are safe meta-information i.e. they do not change the original code behavior. They address the remote execution of a function as well as the transfers of data to/from the HWA memory.The table below introduces the OpenHMPP directives. OpenHMPP directives address different needs: some of them are dedicated to declarations and others are dedicated to the management of the execution.
Control flow instructions | Directives for data management | |
Declarations | codelet group | resident map mapbyname |
Operational Directives | callsite synchronize region | allocate release advancedload delegatedstore |
Concept of set of directives
One of the fundamental points of the HMPP approach is the concept of directives and their associated labels which makes it possible to expose a coherent structure on a whole set of directives disseminated in an application.There are two kinds of labels:
- One associated to a codelet. In general, the directives carrying this kind of labels are limited to the management of only one codelet.
- One associated to a group of codelets. These labels are noted as follow: “
“, where “LabelOfGroup” is a name specified by the user. In general, the directives which have a label of this type relate to the whole group. The concept of group is reserved to a class of problems which requires a specific management of the data throughout the application to obtain performance. OpenHMPP Directives Syntax
The color convention below is used for the description of syntax directives:
- Reserved HMPP keywords are in green;
- Elements of grammar which can be declined in HMPP keywords are in red;
- User's variables remain in black.
General syntax
- For C language:
- For FORTRAN language:
Where:
: is a unique identifier naming a group of codelets. In cases where no groups are defined in the application, this label can simply miss. Legal label name must follow this grammar: *. Note that the “< >” characters belong to the syntax and are mandatory for this kind of label.codelet_label
: is a unique identifier naming a codelet. Legal label name must follow this grammar: *directive
: is the name of the directive;directive_parameters
: designates some parameters associated to the directive. These parameters may be of different kinds and specify either some arguments given to the directive either a mode of execution ;: is a character used to continue the directive on the next line.
Directive parameters
Below are the directive parameters defined in OpenHMPP:
-
version = major.minor
: specifies the version of the HMPP directives to be considered by the preprocessor. -
args.size=
: specifies the size of a non scalar parameter. -
args.io=
: indicates that the specified function arguments are either input, output or both. By default, unqualified arguments are inputs. -
cond = "expr"
: specifies an execution condition as a boolean C or Fortran expression that needs to be true in order to start the execution of the group or codelets. -
target=target_name*
: specifies which targets to try to use in the given order. -
asynchronous
: specifies that the codelet execution is not blocking. -
args.advancedload=true
: indicates that the specified parameters are preloaded. Only in or inout parameters can be preloaded. -
args.noupdate=true
: this property specifies that the data is already available on the HWA and so that no transfer is needed. When this property is set, no transfer is done on the considered argument -
args.addr="
:"
is an expression that gives the address of the data to upload. -
args.const=true
: indicates that the argument is to be uploaded only once.OpenHMPP directives
Directives for declaring and executing a codelet
Acodelet
directive declares a computation to be remotely executed on a hardware accelerator.For the
codelet
directive: - The codelet label is mandatory and must be unique in the application
- The group label is not required if no group is defined.
- The codelet directive is inserted just before the function declaration.
#pragma hmpp <grp_label> codelet_label codelet
?]?
.io=*
.size=]*
.const=true]*
*]
More than one codelet directive can be added to a function in order to specify different uses or different execution contexts. However, there can be only one codelet directive for a given call site label.
The
callsite
directive specifies how the use a codelet at a given point in the program.The syntax of the directive is:
#pragma hmpp <grp_label> codelet_label callsite
?
.size=]*
.advancedload=*
.addr="expr"]*
.noupdate=true]*
An example is shown here :
/* declaration of the codelet */
#pragma hmpp simple1 codelet, args.io=inout, target=CUDA
static void matvec
Data transfers directives to optimize communication overhead
When using a HWA, the main bottleneck is often the data transfers between the HWA and the main processor.To limit the communication overhead, data transfers can be overlapped with successive executions of the same codelet by using the asynchronous property of the HWA.
- allocate directive
allocate
directive locks the HWA and allocates the needed amount of memory.#pragma hmpp <grp_label> allocate .size=]*
- release directive
release
directive specifies when to release the HWA for a group or a stand-alone codelet.#pragma hmpp <grp_label> release
- advancedload directive
advancedload
directive prefetches data before the remote execution of the codelet.#pragma hmpp <grp_label> ? advancedload
,args
.size=]*
.addr="expr"]*
.section=]*
- delegatedstore directive
delegatedstore
directive is a synchronization barrier to wait for an asynchronous codelet execution to complete and to then download the results.#pragma hmpp <grp_label> ? delegatedstore
,args
.addr="expr"]*
.section=]*
- Asynchronous Computations
synchronize
directive specifies to wait until the completion of an asynchronous callsite execution. For the synchronize directive, the codelet label is always mandatory and the group label is required if the codelet belongs to a group.
#pragma hmpp <grp_label> codelet_label synchronize
- Example
The
synchronize
directive allows to wait for the asynchronous execution of the codelet to complete before launching another iteration. Finally the delegatedstore
directive outside the loop uploads the sgemm result.int main
Sharing data between codelets
Those directives map together all the arguments sharing the given name for all the group.The types and dimensions of all mapped arguments must be identical.
The
map
directive maps several arguments on the device. #pragma hmpp <grp_label> map, args
This directive is quite similar as the
map
directive except that the arguments to be mapped are directly specified by their name. The mapbyname
directive is equivalent to multiple map
directives. #pragma hmpp <grp_label> mapbyname +
Global variable
Theresident
directive declares some variables as global within a group. Those variables can then be directly accessed from any codelet belonging to the group. This directive applies to the declaration statement just following it in the source code.
The syntax of this directive is:
#pragma hmpp <grp_label> resident
.io=*
.size=]*
.addr="expr"]*
.const=true]*
The notation
::var_name
with the prefix ::
, indicates an application's variable declared as resident.Acceleration of regions
A region is a merge of the codelet/callsite directives. The goal is to avoid code restructuration to build the codelet. Therefore, all the attributes available forcodelet
or callsite
directives can be used on regions
directives.In C language:
#pragma hmpp region
.io=*
<
.const=true]*
*]
.size=]*
.advancedload=*
.addr="expr"]*
.noupdate=true]*
?
]*
Implementations
The OpenHMPP Open Standard is based on HMPP Version 2.3.The OpenHMPP directive-based programming model is implemented in:
- CAPS Compilers, CAPS Entreprise compilers for hybrid computing
- PathScale ENZO Compiler Suite