Skip to content

PAPI Error Handling

Treece-Burgess edited this page Mar 21, 2024 · 21 revisions

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.

Error Codes

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

Converting Error Codes to Error Messages

Error codes can be converted to error messages by calling the following low-level functions:

C:

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.

Fortan:

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.

Example

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);
}

Output

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.

Handling Errors

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);
}