-
Notifications
You must be signed in to change notification settings - Fork 60
PAPI Error Handling
This section discusses the various negative error codes that are returned by the PAPI functions. A table with the names, values, and descriptions of the return codes are given as well as a discussion of the PAPI function that can be used to convert error codes to error messages along with a code example with the corresponding output.
All of the functions contained in the PAPI library return standardized error codes in which the values that are greater than or equal to zero indicate success and those that are less than zero indicate failure, as shown in the table below:
VALUE | SYMBOL | DEFINITION |
---|---|---|
0 | PAPI_OK | No error |
-1 | PAPI_EINVAL | Invalid argument |
-2 | PAPI_ENOMEM | Insufficient memory |
-3 | PAPI_ESYS | A system or C library call failed, please check errno |
-4 | PAPI_ECMP | Not supported by component |
-4 | PAPI_ESBSTR | Substrate returned an error, usually the result of an unimplemented feature |
-5 | PAPI_ECLOST | Access to the counters was lost or interrupted |
-6 | PAPI_EBUG | Internal error, please send mail to the developers |
-7 | PAPI_ENOEVNT | Hardware event does not exist |
-8 | PAPI_ECNFLCT | Hardware event exists, but cannot be counted due to counter resource limitations |
-9 | PAPI_ENOTRUN | No events or event sets are currently not counting |
-10 | PAPI_EISRUN | Event Set is currently running |
-11 | PAPI_ENOEVST | No such event set available |
-12 | PAPI_ENOTPRESET | Event is not a valid preset |
-13 | PAPI_ENOCNTR | Hardware does not support performance counters |
-14 | PAPI_EMISC | ‘Unknown error’ code |
-15 | PAPI_EPERM | You lack the necessary permissions |
-16 | PAPI_ENOINIT | PAPI hasn't been initialized yet |
-17 | PAPI_ENOCMP | Component Index isn't set |
-18 | PAPI_ENOSUPP | Not supported |
-19 | PAPI_ENOIMPL | Not implemented |
-20 | PAPI_EBUF | Buffer size exceeded |
-21 | PAPI_EINVAL_DOM | EventSet domain is not supported for the operation |
-22 | PAPI_EATTR | Invalid or missing event attributes |
-23 | PAPI_ECOUNT | Too many events or attributes |
-24 | PAPI_ECOMBO | Bad combination of features |
-25 | PAPI_ECMP_DISABLED | Component containing event is disabled |
-26 | PAPI_EDELAY_INIT | Delayed initialization component |
-27 | PAPI_EMULPASS | Event exists, but cannot be counted due to multiple passes required by hardware |
Error codes can be converted to error messages by calling the following low-level functions:
int code;
char *retval = PAPI_strerror(code);
Arguments for PAPI_strerror
:
- code -- the error code to interpret.
const char *message;
PAPI_perror(message);
Arguments for PAPI_perror
:
- message -- optional message to print before the string describing the last error message.
use iso_c_binding
character(PAPI_MAX_STR_LEN, c_char) message
call PAPIF_perror(message)
Fortran arguments for PAPI_perror
:
- message -- optional message to print before the string describing the last error message.
As a note, make sure to initialize the PAPI library to use the above low-level functions.
PAPI_perror produces a message on the standard error output describing the last error encountered during a call to PAPI. If the message is not NULL then the message is printed, followed by a colon and a space. Then the error message and a new-line are printed.
PAPI_strerror returns a pointer to the error message corresponding to the error code provided. If the call fails, the function returns a NULL pointer. Otherwise, a non-NULL pointer is returned. Note that this function is not implemented in Fortran.
In the following code example, PAPI_strerror
is used to convert error codes to error messages:
#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;
int event = 0x0;
/* Initialize the PAPI library */
retval = PAPI_library_init(PAPI_VER_CURRENT);
if (retval != PAPI_VER_CURRENT && retval > 0)
handle_error(retval);
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);
/* Add illegal PRESET event */
PAPI_event_name_to_code("PAPI_L4_DCM", &event);
retval = PAPI_add_event(EventSet, event);
if (retval != PAPI_OK)
handle_error(retval);
/* Start counting */
retval = PAPI_start(EventSet);
if (retval != PAPI_OK)
handle_error(retval);
}
PAPI error -1: Invalid argument
Notice that the above output was generated from the second to last call to handle_error.
On success, PAPI_perror returns PAPI_OK and on error, a non-zero error code is returned.
Throughout the sections of this overview, a function titled handle_error(...)
is commonly used. In the above example, you can see one implementation of handle_error(...)
being declared and defined. However, you may implement this function in whatever way makes sense for your circumstances, below is another possible implementation that could be used.
void handle_error (int retval)
{
/* print error to stderr and exit */
PAPI_perror(PAPI_strerror(retval));
exit(1);
}