-
Notifications
You must be signed in to change notification settings - Fork 2
1 Application Development
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.
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.
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.
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. |
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. |
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. |