Skip to content

1 Application Development

Graeme Bragg edited this page Jun 6, 2018 · 1 revision

This page is for application developers to help them use the PRiME Framework and API with their applications.

Code for the following example applications is provided with the Framework repository:

Source code for example applications is provided in the app/ folder. These can be used as examples to illustrate how an application may be developed to operate with the PRiME Framework and API.

Applications in the PRiME Framework

This section describes how applications are defined within the PRiME Framework and the API functions that are available for use by a developer of application code.

Application interaction in the PRiME Framework can be divided into three groups of features:

Knobs and monitors are defined to be one of two types:

  • disc denotes a discrete-type knob/monitor, whose value can be one of a finite number of possible values in a range. For example, the number of iterations performed by an algorithm is a discrete knob.
  • cont denotes a continuous-type knob/monitor, whose value can be one of an infinite number of possible values in a range. For example, the throughput of an application is a continuous monitor.

Registration & Deregistration

For applications to be controlled by an RTM they must first register with the PRiME Framework. Furthermore, before an application ends it must deregister from the PRiME Framework. Two API functions control registration and deregistration; reg and dereg.
Registration requires the process ID and the tracking ID of the application. Deregistration only requires the process ID.

API Function Fields Return Description
reg pid_t proc_id, unsigned long int ur_id void Register an application with ID proc_id and tracking ID ur_id.
dereg pid_t proc_id void Deregister the application with ID proc_id.

The tracking ID, ur_id, should be a randomly generated at application compile time. The example applications achieve this by including app_random.h and passing COMPILE_UR_ID as the ur_id argument to the registration function. app_random.h should be seeded by passing in the system epoch as COMPILE_EPOCH and a random number from rand or "echo $RANDOM" to COMPILE_RAND during make. This can be done in CMakeLists.txt with:

set_target_properties(<APPLICATION> PROPERTIES COMPILE_FLAGS "-DCOMPILE_RAND=$$(rand) -DCOMPILE_EPOCH=$$(date +%s)")

N.B. target_compile_options cannot be used in cmake as the escaping of $s and `s is broken and results in a broken makefile.

The tracking ID should not be used by an RTM to specifically identify the application. It intention is to track when the same application is re-registered with the Framework, or multiple instances are registered, to allow the recall of learning information.

Knob Interactions

Applications must expose controllable parameters for them to be managed by the RTM. These parameters are called knobs in the context of the PRiME Framework. Knobs allow the RTM to change the behaviour of an application to either satisfy monitor boundaries or optimise global objectives.
The first step is to identify what knobs exist in an application and expose them by modifying application code such that they can be controlled at runtime. For example, a parallelism knob requires the application to be written in an parallel programming language which supports runtime adjustment of the level of parallelism.
Exposed knobs must first be registered with the framework through the knob_disc_reg and `knob_cont_reg' functions. Parameters that must be passed with each knob registration include; the PID of the owning application, a min and max value and an initial value. Optionally, a unique knob ID may be passed to allow the RTM to identify the function of the knob.

API Function Fields Return Description
knob_disc_reg pid_t proc_id, unsigned int id, disc_t min, disc_t max, disc_t val knob_disc_t knob Register a discrete application knob.
knob_cont_reg pid_t proc_id, unsigned int id, cont_t min, cont_t max, cont_t val knob_cont_t knob Register a continuous application knob.

Any time after registration, but before deregistration, a knob's min and max value can be updated any number of times. This can be done directly using the knob_(disc|cont)_min and knob_(disc|cont)_max functions.

API Function Fields Return Description
knob_disc_min knob_disc_t knob, disc_t min void Update the min value of a discrete application knob.
knob_disc_max knob_disc_t knob, disc_t max void Update the max value of a discrete application knob.
knob_cont_min knob_cont_t knob, cont_t min void Update the min value of a continuous application knob.
knob_cont_max knob_cont_t knob, cont_t max void Update the max value of a continuous application knob.

The application can get an updated value for a knob by calling the knob_disc_get or knob_cont_get functions. The framework will return the latest value assigned to the knob by the RTM. However, no information is held on when this value was assigned or if the RTM has assessed whether to update the knob since the last time it was queried.

API Function Fields Return Description
knob_disc_get knob_disc_t knob disc_t val Get the current value of a discrete application knob.
knob_cont_get knob_cont_t knob cont_t val Get the current value of a continuous application knob.

Application knobs must be deregistered from the framework before an application can deregister. In addition, knobs may deregister any time after they are registered if they are no longer required or valid.

API Function Fields Return Description
knob_disc_dereg knob_disc_t knob void Deregister a discrete application knob.
knob_cont_dereg knob_cont_t knob void Deregister a continuous application knob.

Monitor Interactions

Applications must expose measurable metrics for them to be managed by the RTM. These metrics are called monitors in the context of the PRiME Framework. Monitors characterise an application's operation or behaviour and provide management targets for the RTM. The RTM should use monitors to understand how changes in knob values affects the behaviour of an application.
The first step is to identify what monitors exist in an application and expose them by modifying application code such that they can be measured at runtime. For example, a throughput monitor should be calculated at the end of every cycle of the application.
Exposed monitors must first be registered with the framework through the mon_disc_reg and mon_cont_reg functions. Parameters that must be passed with each monitor registration include; the PID of the owning application, a min and max value and a weighting value. Optionally, a unique monitor ID may be passed to allow the RTM to identify the meaning of the monitor.

API Function Fields Return Description
mon_disc_reg pid_t proc_id, unsigned int id, disc_t min, disc_t max, cont_t weight mon_disc_t mon Register a discrete application monitor.
mon_cont_reg pid_t proc_id, unsigned int id, cont_t min, cont_t max, cont_t weight mon_cont_t mon Register a continuous application monitor.

Any time after registration, but before deregistration, a monitor's min, max and weight value can be updated any number of times. This can be done directly using the mon_(disc|cont)_min, mon_(disc|cont)_max and mon_(disc|cont)_weight functions, respectively.

API Function Fields Return Description
mon_disc_min mon_disc_t mon, disc_t min void Update the min value of a discrete application monitor.
mon_disc_max mon_disc_t mon, disc_t max void Update the max value of a discrete application monitor.
mon_disc_weight mon_disc_t mon, cont_t weight void Update the weighting of a discrete application monitor.
mon_cont_min mon_cont_t mon, cont_t min void Update the min value of a continuous application monitor.
mon_cont_max mon_cont_t mon, cont_t max void Update the max value of a continuous application monitor.
mon_cont_weight mon_cont_t mon, cont_t weight void Update the weighting of a continuous application monitor.

The application can update the value of a monitor by calling the mon_disc_set or mon_cont_set functions.

API Function Fields Return Description
mon_disc_set mon_disc_t mon, disc_t val void Set the current value of a discrete application monitor.
mon_cont_set mon_cont_t mon, cont_t val void Set the current value of a continuous application monitor.

Application monitors must be deregistered from the framework before an application can deregister. In addition, monitors may deregister any time after they are registered if they are no longer required or valid.

API Function Fields Return Description
mon_disc_dereg mon_disc_t mon void Deregister a discrete application monitor.
mon_cont_dereg mon_cont_t mon void Deregister a continuous application monitor.

PRiME APP API

The following table is a complete list of the PRiME Application API functions. Code can be seen here.

API Function Fields Return Description
reg pid_t proc_id void Register an application with ID proc_id.
dereg pid_t proc_id void Deregister the application with ID proc_id.
knob_disc_reg pid_t proc_id, unsigned int id, disc_t min, disc_t max, disc_t val knob_disc_t Register a discrete application knob.
knob_cont_reg pid_t proc_id, unsigned int id, cont_t min, cont_t max, cont_t val knob_cont_t Register a continuous application knob.
knob_disc_min knob_disc_t knob, disc_t min void Update the min value of a discrete application knob.
knob_disc_max knob_disc_t knob, disc_t max void Update the max value of a discrete application knob.
knob_cont_min knob_cont_t knob, cont_t min void Update the min value of a continuous application knob.
knob_cont_max knob_cont_t knob, cont_t max void Update the max value of a continuous application knob.
knob_disc_get knob_disc_t knob disc_t val Fetch an updated value of a discrete application knob.
knob_cont_get knob_cont_t knob cont_t val Fetch an updated value of a discrete application knob.
knob_disc_dereg knob_disc_t knob void Deregister a discrete application knob.
knob_cont_dereg knob_cont_t knob void Deregister a continuous application knob.
mon_disc_reg pid_t proc_id, unsigned int id, disc_t min, disc_t max, cont_t weight mon_disc_t Register a discrete application monitor.
mon_cont_reg pid_t proc_id, unsigned int id, cont_t min, cont_t max, cont_t weight mon_cont_t Register a continuous application monitor.
mon_disc_min mon_disc_t mon, disc_t min void Update the min value of a discrete application monitor.
mon_disc_max mon_disc_t mon, disc_t max void Update the max value of a discrete application monitor.
mon_disc_weight mon_disc_t mon, cont_t weight void Update the weighting of a discrete application monitor.
mon_cont_min mon_cont_t mon, cont_t min void Update the min value of a continuous application monitor.
mon_cont_max mon_cont_t mon, cont_t max void Update the max value of a continuous application monitor.
mon_cont_weight mon_cont_t mon, cont_t weight void Update the weighting of a continuous application monitor.
mon_disc_set mon_disc_t mon, disc_t val void Set the current value of a discrete application monitor.
mon_cont_set mon_cont_t mon, cont_t val void Set the current value of a continuous application monitor.
mon_disc_dereg mon_disc_t mon void Deregister a discrete application monitor.
mon_cont_dereg mon_cont_t mon void Deregister a continuous application monitor.