-
Notifications
You must be signed in to change notification settings - Fork 59
PAPI EventSets
Event Sets are user-defined groups of hardware events (preset or native), which are used in conjunction with one another to provide meaningful information. The user specifies the events to be added to an Event Set, and other attributes, such as: the counting domain (user or kernel), whether or not the events in the Event Set are to be multiplexed, and whether the Event Set is to be used for overflow or profiling. Other settings for the Event Set are maintained by PAPI, such as: what low-level hardware registers to use, the most recently read counter values, and the state of the Event Set (running/not running). Event Sets provide an effective abstraction for the organization of information associated with counting hardware events. The PAPI library manages the memory for Event Sets with a user interface through integer handles to simplify calling conventions. The user is free to allocate and use any number of them provided the substrate can provide the required resources. Only one Event Set can be in active use at any time in a given thread or process.
An event set can be created by calling the following low-level function:
int EventSet = PAPI_NULL;
int retval = PAPI_create_eventset(&EventSet);
Arguments for PAPI_create_eventset
:
- EventSet -- address of an integer location to store the new EventSet handle.
use iso_c_binding
integer(c_int) EventSet, check
EventSet = PAPI_NULL
call PAPIF_create_eventset(EventSet, check)
Fortran arguments for PAPIF_create_eventset
:
- EventSet -- address of an integer location to store the new EventSet handle.
- check -- an error return value for Fortran.
Once it has been created, the user may add hardware events to the EventSet by calling PAPI_add_event or PAPI_add_events.
On success, this function returns PAPI_OK. On error, a non-zero error code is returned.
For a code example using this function, see the next section.
Hardware events can be added to an event set by calling the following low-level functions:
int EventSet, EventCode;
int retval = PAPI_add_event(EventSet, EventCode);
Arguments for PAPI_add_event
:
- EventSet -- an integer handle for a PAPI Event Set as created by PAPI_create_eventset.
- EventCode -- a defined event such as PAPI_TOT_INS.
int EventSet, EventCode[] = {} /* must be an array */, number;
int retval = PAPI_add_events(EventSet, EventCode, number);
Arguments for PAPI_add_events
:
- EventSet -- an integer handle for a PAPI Event Set as created by PAPI_create_eventset.
- EventCode -- array of defined events.
- number -- an integer indicating the number of events in the array *EventCode.
use iso_c_binding
integer(c_int) EventSet, EventCode, check
call PAPIF_add_event(EventSet, EventCode, check)
Fortran arguments for PAPIF_add_event
:
- EventSet -- an integer handle for a PAPI Event Set as created by PAPI_create_eventset.
- EventCode -- a defined event such as PAPI_TOT_INS.
- check -- an error return value for Fortran.
use iso_c_binding
! EventCode must be an array
integer(c_int) EventSet, EventCode(), number, check
call PAPIF_add_events(EventSet, EventCode, number, check)
Fortran arguments for PAPIF_add_events
:
- EventSet -- an integer handle for a PAPI Event Set as created by PAPI_create_eventset.
- EventCode -- an array of defined events.
- number -- an integer indicating the number of events in the array EventCode.
- check -- an error return value for Fortran.
PAPI_add_event adds a single hardware event to a PAPI event set.
PAPI_add_events does the same as PAPI_add_event, but for an array of hardware event codes.
In the following code example, the preset event, PAPI_TOT_INS is added to an event set:
#include <papi.h>
#include <stdio.h>
#include <stdlib.h>
void handle_error (int retval)
{
printf("PAPI error %d: %s\n", retval, PAPI_strerror(retval));
exit(1);
}
int main()
{
int EventSet = PAPI_NULL;
int retval;
/* Initialize the PAPI library */
retval = PAPI_library_init(PAPI_VER_CURRENT);
if (retval != PAPI_VER_CURRENT)
handle_error(retval);
/* Create an EventSet */
retval = PAPI_create_eventset(&EventSet);
if (retval != PAPI_OK)
handle_error(retval);
/* Add Total Instructions Executed to our EventSet */
retval = PAPI_add_event(EventSet, PAPI_TOT_INS);
if (retval != PAPI_OK)
handle_error(retval);
/* Executes if all low-level PAPI
function calls returned PAPI_OK */
printf("\033[0;32mPASSED\n\033[0m");
exit(0);
}
PASSED
On success, both of these PAPI functions return PAPI_OK and the above output is returned. On error, a non-zero error code is returned.
Hardware events in an event set can be started, read, added, and stopped by calling the following low-level functions, respectively:
int EventSet;
int retval = PAPI_start(EventSet);
Arguments for PAPI_start
:
- EventSet -- an integer handle for a PAPI Event Set as created by PAPI_create_eventset.
int EventSet;
long long values[]; /* must declare size of array */
int retval = PAPI_read(EventSet, values);
Arguments for PAPI_read
:
- EventSet -- an integer handle for a PAPI Event Set as created by PAPI_create_eventset.
- values -- an array to hold the counter values of the counting events.
int EventSet;
long long values[]; /* must declare size of array */
int retval = PAPI_accum(EventSet, values);
Arguments for PAPI_accum
:
- EventSet -- an integer handle for a PAPI Event Set as created by PAPI_create_eventset.
-
values -- an array to hold the counter values of the counting events.
${{\color{Darkorange}{\textsf{Note: The "values" array must be initialized for PAPI\_accum because its values are read inside the function.}}}}$
int EventSet;
long long values[]; // must declare size of array
int retval = PAPI_stop(EventSet, values);
Arguments for PAPI_stop
:
- EventSet -- an integer handle for a PAPI Event Set as created by PAPI_create_eventset.
- values -- an array to hold the counter values of the counting events.
use iso_c_binding
integer(c_int) EventSet, check
call PAPIF_start(EventSet, check)
Fortran arguments for PAPIF_start
:
- EventSet -- an integer handle for a PAPI Event Set as created by PAPI_create_eventset.
- check -- an error return value for Fortran.
use iso_c_binding
integer(c_int) EventSet, check
integer(c_long_long) values,
call PAPIF_read(EventSet, values, check)
Fortran arguments for PAPIF_read
:
- EventSet -- an integer handle for a PAPI Event Set as created by PAPI_create_eventset.
- values -- hold the counter values of the counting events.
- check -- an error return value for Fortran.
use iso_c_binding
integer(c_int) EventSet, check
integer(c_long_long) values
call PAPIF_accum(EventSet, values, check)
Fortran arguments for PAPIF_accum
:
- EventSet -- an integer handle for a PAPI Event Set as created by PAPI_create_eventset.
- values -- hold the counter values of the counting events.
- check -- an error return value for Fortran.
use iso_c_binding
integer(c_int) EventSet, check
integer(c_long_long) values
call PAPIF_stop(EventSet, values, check)
Fortran arguments for PAPIF_stop
:
- EventSet -- an integer handle for a PAPI Event Set as created by PAPI_create_eventset.
- values -- hold the counter values of the counting events.
- check -- an error return value for Fortran.
PAPI_start starts the counting events in a previously defined event set.
PAPI_read reads (copies) the counters of the indicated event set into the array, values. The counters are left counting after the read without resetting.
PAPI_accum adds the counters of the indicated event set to the array, values. The counters are reset and left counting after the call of this function. Please make sure the array (second parameter) is initialized, see not above for more details.
PAPI_stop stops the counting events in a previously defined event set and returns the current events.
The following is a code example of using PAPI_start to start the counting of events in an event set, PAPI_read to read the counters of the same event set into the array values, and PAPI_stop to stop the counting of events in the event set:
#include <papi.h>
#include <stdio.h>
#include <stdlib.h>
void handle_error (int retval)
{
printf("PAPI error %d: %s\n", retval, PAPI_strerror(retval));
exit(1);
}
int main()
{
int retval, EventSet = PAPI_NULL;
long_long values[1];
/* Initialize the PAPI library */
retval = PAPI_library_init(PAPI_VER_CURRENT);
if (retval != PAPI_VER_CURRENT)
handle_error(retval);
/* Create the Event Set */
retval = PAPI_create_eventset(&EventSet);
if (retval != PAPI_OK)
handle_error(retval);
/* Add Total Instructions Executed to our EventSet */
retval = PAPI_add_event(EventSet, PAPI_TOT_INS);
if (retval != PAPI_OK)
handle_error(retval);
/* Start counting */
retval = PAPI_start(EventSet);
if (retval != PAPI_OK)
handle_error(retval);
/* Do some computation here */
retval = PAPI_read(EventSet, values);
if (retval != PAPI_OK)
handle_error(retval);
/* Do some computation here */
retval = PAPI_stop(EventSet, values);
if (retval != PAPI_OK)
handle_error(retval);
/* Executes if all low-level PAPI
function calls returned PAPI_OK */
printf("\033[0;32mPASSED\n\033[0m");
exit(0);
}
PASSED
On success, all PAPI functions return PAPI_OK and the above output is returned. On error, a non-zero error code is returned.
The hardware event counts in an event set can be reset to zero by calling the following low-level function:
int EventSet;
int retval = PAPI_reset(EventSet);
Arguments for PAPI_reset
:
- EventSet -- an integer handle for a PAPI event set as created by PAPI_create_eventset.
use iso_c_binding
integer(c_int) EventSet, check
call PAPIF_reset(EventSet, check)
Fortran arguments for PAPIF_reset
:
- EventSet -- an integer handle for a PAPI event set as created by PAPI_create_eventset.
- check -- an error return value for Fortran.
For example, the EventSet in the code example of the previous section could have been reset to zero by adding the following lines:
retval = PAPI_reset(EventSet);
if (retval != PAPI_OK)
handle_error(retval);
On success, this function returns PAPI_OK and on error, a non-zero error code is returned.
A hardware event and an array of hardware events can be removed from an event set by calling the following low-level functions, respectively:
int EventSet, EventCode;
int retval = PAPI_remove_event(EventSet, EventCode);
Arguments for PAPI_remove_event
:
- EventSet -- an integer handle for a PAPI event set as created by PAPI_create_eventset.
- EventCode -- a defined event such as PAPI_TOT_INS or a native event.
int EventSet, number;
int EventCode[] = {}; /* must declare size of array */
int retval = PAPI_remove_events(EventSet, EventCode, number);
Arguments for PAPI_remove_events
:
- EventSet -- an integer handle for a PAPI event set as created by PAPI_create_eventset.
- EventCode -- an array of defined events.
- number -- an integer indicating the number of events in the array *EventCode.
use iso_c_binding
! EventCode must be an array
integer(c_int) EventSet, EventCode(), number, check
call PAPIF_remove_event(EventSet, EventCode, number, check)
Fortran arguments for PAPIF_remove_event
:
- EventSet -- an integer handle for a PAPI event set as created by PAPI_create_eventset.
- EventCode -- a defined event such as PAPI_TOT_INS or a native event.
- number -- an integer indicating the number of events in the array EventCode.
- check -- an error return value for Fortran.
use iso_c_binding
integer(c_int) EventSet, number, check
call PAPIF_remove_events(EventSet, EventCode, number, check)
Fortran arguments for PAPIF_remove_events
:
- EventSet -- an integer handle for a PAPI event set as created by PAPI_create_eventset.
- EventCode -- an array of defined events.
- number -- an integer indicating the number of events in the array EventCode.
- check -- an error return value for Fortran.
PAPI_remove_event removes a single hardware event from a PAPI event set.
PAPI_remove_events, does the same as PAPI_remove_event, but for an array of hardware event codes.
In the following code example, PAPI_remove_event is used to remove the event, PAPI_TOT_INS, from an event set:
#include <papi.h>
#include <stdio.h>
#include <stdlib.h>
void handle_error (int retval)
{
printf("PAPI error %d: %s\n", retval, PAPI_strerror(retval));
exit(1);
}
int main()
{
int retval, EventSet = PAPI_NULL;
/* Initialize the PAPI library */
retval = PAPI_library_init(PAPI_VER_CURRENT);
if (retval != PAPI_VER_CURRENT)
handle_error(retval);
/* Create an EventSet */
retval = PAPI_create_eventset(&EventSet);
if (retval != PAPI_OK)
handle_error(retval);
/* Add Total Instructions Executed to our EventSet */
retval = PAPI_add_event(EventSet, PAPI_TOT_INS);
if (retval != PAPI_OK)
handle_error(retval);
/* Remove event */
retval = PAPI_remove_event(EventSet, PAPI_TOT_INS);
if (retval != PAPI_OK)
handle_error(retval);
/* Executes if all low-level PAPI
function calls returned PAPI_OK */
printf("\033[0;32mPASSED\n\033[0m");
exit(0);
}
PASSED
On success, all PAPI functions return PAPI_OK and the above output is returned. On error, a non-zero error code is returned.
All the events in an event set can be emptied and destroyed by calling the following low-level functions, respectively:
int EventSet;
int retval = PAPI_cleanup_eventset(EventSet);
Arguments for PAPI_cleanup_eventset
:
- EventSet -- an integer handle for a PAPI event set as created by PAPI_create_eventset.
int EventSet;
int retval = PAPI_destroy_eventset(&EventSet);
Arguments for PAPI_destroy_eventset
:
- EventSet -- a pointer to the integer handle for a PAPI event set as created by PAPI_create_eventset. The value pointed to by EventSet is then set to PAPI_NULL on success.
use iso_c_binding
integer(c_int) EventSet, check
call PAPIF_cleanup_eventset(EventSet, check)
Fortran arguments for PAPIF_cleanup_eventset
:
- EventSet -- an integer handle for a PAPI event set as created by PAPI_create_eventset.
- check -- an error return value for Fortran.
use iso_c_binding
integer(c_int) EventSet, check
call PAPIF_destroy_eventset(EventSet, check)
Fortran arguments for PAPIF_destroy_eventset
:
- EventSet -- integer handle for a PAPI event set as created by PAPI_create_eventset. The value pointed to by EventSet is then set to PAPI_NULL on success.
- check -- an error return value for Fortran.
Note that the event set must be empty in order to use PAPI_destroy_eventset.
In the following code example, PAPI_cleanup_eventset is used to empty all the events from an event set and PAPI_destroy_eventset is used to deallocate the memory associated with the empty event set:
#include <papi.h>
#include <stdio.h>
#include <stdlib.h>
void handle_error (int retval)
{
printf("PAPI error %d: %s\n", retval, PAPI_strerror(retval));
exit(1);
}
int main()
{
int retval, EventSet = PAPI_NULL;
/* Initialize the PAPI library */
retval = PAPI_library_init(PAPI_VER_CURRENT);
if (retval != PAPI_VER_CURRENT)
handle_error(retval);
/* Create the EventSet */
retval = PAPI_create_eventset(&EventSet);
if (retval != PAPI_OK)
handle_error(retval);
/* Add Total Instructions Executed to our EventSet */
retval = PAPI_add_event(EventSet, PAPI_TOT_INS);
if (retval != PAPI_OK)
handle_error(retval);
/* Remove all events in the eventset */
retval = PAPI_cleanup_eventset(EventSet);
if (retval != PAPI_OK)
handle_error(retval);
/* Free all memory and data structures, EventSet must be empty. */
retval = PAPI_destroy_eventset(&EventSet);
if (retval != PAPI_OK)
handle_error(retval);
/* Executes if all low-level PAPI
function calls returned PAPI_OK */
printf("\033[0;32mPASSED\n\033[0m");
exit(0);
}
PASSED
On success, all PAPI functions return PAPI_OK and the above output is returned. On error, a non-zero error code is returned.
The counting state of an Event Set can be obtained by calling the following low-level function:
int EventSet, status;
int retval = PAPI_state(EventSet, &status);
Arguments for PAPI_state
:
- EventSet -- an integer handle for a PAPI event set as created by PAPI_create_eventset.
- status -- an integer containing a boolean combination of one or more of the nonzero constants as defined in the PAPI header file (papi.h). A non exhaustive list can be seen in the table below.
use iso_c_binding
integer(c_int) EventSet, status, check
call PAPIF_state(EventSet, status, check)
Fortran arguments for PAPIF_state
:
- EventSet -- an integer handle for a PAPI event set as created by PAPI_create_eventset.
- status -- an integer containing a boolean combination of one or more of the nonzero constants as defined in the PAPI header file (fpapi.h). A non exhaustive list can be seen in the table below.
- check -- an error return value for Fortran.
Status | Description |
---|---|
PAPI_STOPPED | EventSet is stopped |
PAPI_RUNNING | EventSet is running |
PAPI_PAUSED | EventSet temporarily disabled by the library |
PAPI_NOT_INIT | EventSet defined, but not initialized |
PAPI_OVERFLOWING | EventSet has overflow enabled |
PAPI_PROFILING | EventSet has profiling enabled |
PAPI_MULTIPLEXING | EventSet has multiplexing enabled |
PAPI_ATTACHED | EventSet is attached to another thread/process |
PAPI_CPU_ATTACHED | EventSet is attached to a specific cpu |
In the following code example, PAPI_state is used to return the counting state of an EventSet:
#include <papi.h>
#include <stdio.h>
#include <stdlib.h>
void handle_error (int retval)
{
printf("PAPI error %d: %s\n", retval, PAPI_strerror(retval));
exit(1);
}
int main ()
{
int retval, status = 0, EventSet = PAPI_NULL;
/* Initialize the PAPI library */
retval = PAPI_library_init(PAPI_VER_CURRENT);
if (retval != PAPI_VER_CURRENT)
handle_error(retval);
/* Create the EventSet */
retval = PAPI_create_eventset(&EventSet);
if (retval != PAPI_OK)
handle_error(retval);
/* Add Total Instructions Executed to our EventSet */
retval = PAPI_add_event(EventSet, PAPI_TOT_INS);
if (retval != PAPI_OK)
handle_error(retval);
/* Start counting */
retval = PAPI_state(EventSet, &status);
if (retval != PAPI_OK)
handle_error(retval);
printf("State is now %d\n", status);
retval = PAPI_start(EventSet);
if (retval != PAPI_OK)
handle_error(retval);
retval = PAPI_state(EventSet, &status);
if (retval != PAPI_OK)
handle_error(retval);
printf("State is now %d\n", status);
/* Executes if all low-level PAPI
function calls returned PAPI_OK */
printf("\033[0;32m\n\nPASSED\n\033[0m");
exit(0);
}
State is now 1
State is now 2
PASSED
On success, all PAPI functions return PAPI_OK and the above output is returned. On error, a non-zero error code is returned.