From PAPIDocs
Jump to: navigation, search

Getting and Setting Options

The options of the PAPI library or a specific event set can be obtained and set by calling the following low-level functions, respectively:

PAPI_get_opt(option, ptr)
PAPI_set_opt(option, ptr)
PAPIF_get_domain(EventSet, domain, mode, check)
PAPIF_get_granularity(EventSet, granularity, mode, check)
PAPIF_get_preload(preload, check)

option -- is an input parameter describing the course of action. The Fortran calls are implementations of specific options. Possible values are defined in papi.h and briefly described below:

Option name Explanation
General information requests
PAPI_CLOCKRATE Get clockrate in MHz.
PAPI_MAX_CPUS Get number of CPUs.
PAPI_MAX_HWCTRS Get number of counters.
PAPI_EXEINFO Get Executable addresses for text/data/bss.
PAPI_HWINFO Get information about the hardware.
PAPI_SHLIBINFO Get shared library information used by the program.
PAPI_SUBSTRATEINFO Get the PAPI features the substrate supports.
PAPI_LIB_VERSION Get the full PAPI version of the library.
PAPI_PRELOAD Get ‘‘LD_PRELOAD’’ environment equivalent.
Defaults for the global library
PAPI_DEFDOM Get/Set the default counting domain for newly created event sets.
PAPI_DEFGRN Get/Set the default counting granularity.
PAPI_DEBUG Get/Set the PAPI debug state and the debug handler. The available debug states are defined in papi.h. The debug state is available in ptr->debug.level. The debug handler is available in ptr->debug.handler. For information regarding the behavior of the handler, please see the man page for PAPI_set_debug.
Multiplexing control
PAPI_ MULTIPLEX Get/Set options for multiplexing.
PAPI_MAX_MPX_CTRS Get maximum number of multiplexing counters.
PAPI_DEF_MPX_USEC Get/Set the sampling time slice in microseconds for multiplexing.
Manipulating individual event sets
PAPI_ATTACH Get thread or process id to which event set is attached. Returns TRUE if currently attached. Set event set specified in ptr->ptr->attach.eventset to be attached to thread or process id specified in in ptr->attach.tid.
PAPI_DETACH Get thread or process id to which event set is attached. Returns TRUE if currently detached. Set event set specified in ptr->ptr->attach.eventset to be detached from any thread or process id.
PAPI_DOMAIN Get/Set domain for a single event set. The event set is specified in ptr->domain.eventset
PAPI_GRANUL Get/Set granularity for a single event set. The event set is specified in ptr->granularity.eventset. Currently unimplemented.
Platform Specific Options
PAPI_DATA_ADDRESS Set data address range to restrict event counting for event set specified in ptr->addr.eventset. Starting and ending addresses are specified in ptr->addr.start and ptr->addr.end, respectively. If exact addresses cannot be instantiated, offsets are returned in ptr->addr.start_off and ptr->addr.end_off. Currently implemented on Itanium only.
PAPI_INSTR_ADDRESS Set instruction address range as described above. Itanium only.

ptr -- is a pointer to a structure that acts as both an input and output parameter. It is defined in papi.h and below.

EventSet -- input; a reference to an EventSetInfo structure

clockrate -- output; cycle time of this CPU in MHz; *may* be an estimate generated at init time with a quick timing routine

domain -- output; execution domain for which events are counted

granularity -- output; execution granularity for which events are counted

mode -- input; determines if domain or granularity are default or for the current event set

preload -- output; environment variable string for preloading libraries

PAPI_get_opt and PAPI_set_opt query or change the options of the PAPI library or a specific event set created by PAPI_create_eventset. In the C interface, these functions pass a pointer to the PAPI_option_t structure. Not all options require or return information in this structure. The Fortran interface is a series of calls implementing various subsets of the C interface. Not all options in C are available in Fortran.

Note that a number of options are available as separate entry points in both C and Fortran. This can make calling sequences simpler. Calls that are simply wrappers to PAPI_get_opt and PAPI_set_opt are listed below:

PAPI_get_executable_info Get the executable’s address space information.
PAPI_get_hardware_info Get information about the system hardware.
PAPI_get_multiplex Get the multiplexing status of specified event set.
PAPI_get_shared_lib_info Get information about the shared libraries used by the process.
PAPI_get_substrate_info Get information about the substrate features.
PAPI_set_debug Set the current debug level for PAPI.
PAPI_set_domain Set the default execution domain for new event sets.
PAPI_set_granularity Get/Set the default granularity for new event sets.
PAPI_set_multiplex Convert a standard event set to a multiplexed event set.

The PAPI_option_t structure is actually a union of structures that provide specific information for each of the options defined in the table above. This union is defined as shown below:

   typedef union {
      PAPI_preload_info_t preload;
      PAPI_debug_option_t debug;
      PAPI_granularity_option_t granularity;
      PAPI_granularity_option_t defgranularity;
      PAPI_domain_option_t domain;
      PAPI_domain_option_t defdomain;
      PAPI_attach_option_t attach;
      PAPI_multiplex_option_t multiplex;
      PAPI_hw_info_t *hw_info;
      PAPI_shlib_info_t *shlib_info;
      PAPI_exe_info_t *exe_info;
      PAPI_substrate_info_t *sub_info;
      PAPI_addr_range_option_t addr;
   } PAPI_option_t;

Each of these individual structures, as defined in papi.h, is shown below:


   typedef struct _papi_preload_option {
      char lib_preload_env[PAPI_MAX_STR_LEN];   
      char lib_preload_sep;
      char lib_dir_env[PAPI_MAX_STR_LEN];
      char lib_dir_sep;
   } PAPI_preload_info_t;


   typedef int (*PAPI_debug_handler_t) (int code);

   typedef struct _papi_debug_option {
      int level;
      PAPI_debug_handler_t handler;
   } PAPI_debug_option_t;


   typedef struct _papi_granularity_option {
      int eventset;
      int granularity;
   } PAPI_granularity_option_t;


   typedef struct _papi_domain_option {
      int eventset;
      int domain;
   } PAPI_domain_option_t;


   typedef struct _papi_attach_option {
      int eventset;
      unsigned long tid;
   } PAPI_attach_option_t;


   typedef struct _papi_multiplex_option {
      int eventset;
      int us;
      int flags;
   } PAPI_multiplex_option_t;


   typedef struct _papi_hw_info {
      int ncpu;                 /* Number of CPU's in an SMP Node */
      int nnodes;               /* Number of Nodes in the entire system */
      int totalcpus;            /* Total number of CPU's in the entire system */
      int vendor;               /* Vendor number of CPU */
      char vendor_string[PAPI_MAX_STR_LEN];     /* Vendor string of CPU */
      int model;                /* Model number of CPU */
      char model_string[PAPI_MAX_STR_LEN];      /* Model string of CPU */
      float revision;           /* Revision of CPU */
      float mhz;                /* Cycle time of this CPU */
      PAPI_mh_info_t mem_hierarchy;  /* PAPI memory heirarchy description */
   } PAPI_hw_info_t;


   typedef struct _papi_shared_lib_info {
      PAPI_address_map_t *map;
      int count;
   } PAPI_shlib_info_t;


   typedef struct _papi_program_info {
      char fullname[PAPI_HUGE_STR_LEN];  /* path+name */
      PAPI_address_map_t address_info;
   } PAPI_exe_info_t;


   typedef struct _papi_address_map {
      char name[PAPI_HUGE_STR_LEN];
      caddr_t text_start;       /* Start address of program text segment */
      caddr_t text_end;         /* End address of program text segment */
      caddr_t data_start;       /* Start address of program data segment */
      caddr_t data_end;         /* End address of program data segment */
      caddr_t bss_start;        /* Start address of program bss segment */
      caddr_t bss_end;          /* End address of program bss segment */
   } PAPI_address_map_t;


   typedef struct _papi_substrate_option {
     char name[PAPI_MAX_STR_LEN];    /* Name of the substrate we're using,
                                        usually CVS RCS Id */
     char version[PAPI_MIN_STR_LEN]; /* Version of this substrate,
                                        usually CVS Revision */
     char support_version[PAPI_MIN_STR_LEN]; /* Version of the support library */
     char kernel_version[PAPI_MIN_STR_LEN];  /* Version of the kernel PMC
                                                support driver */
     int num_cntrs;          /* Number of hardware counters substrate supports */
     int num_mpx_cntrs;      /* Number of multiplexed counters the substrate or
                                PAPI supports */
     int num_preset_events;   /* Number of preset events the substrate supports */
     int num_native_events;   /* Number of native events the substrate supports */
     int default_domain;      /* The default domain when this substrate is used */
     int available_domains;   /* Available domains */ 
     int default_granularity; /* Default granularity when this substrate is used */
     int available_granularities; /* Available granularities */
     int multiplex_timer_sig;     /* Signal number used by the multiplex timer,
                                     0 if not */
     int multiplex_timer_num;     /* Number of the itimer or POSIX 1 timer used
                                     by the multiplex timer */
     int multiplex_timer_us;      /* uS between switching of sets */
     int hardware_intr_sig;     /* Signal used by hardware to deliver PMC events */
     int opcode_match_width;    /* Width of opcode matcher if exists, 0 if not */
     int reserved_ints[4];
     unsigned int hardware_intr:1; /* hw overflow intr, does not need to be
                                      emulated in software*/
     unsigned int precise_intr:1;  /* Performance interrupts happen precisely */
     unsigned int posix1b_timers:1;  /* Using POSIX 1b interval timers
                                       (timer_create) instead of setitimer */
     unsigned int kernel_profile:1;   /* Has kernel profiling support (buffered
                                        interrupts or sprofil-like) */
     unsigned int kernel_multiplex:1; /* In kernel multiplexing */
     unsigned int data_address_range:1; /* Supports data address range limiting */
     unsigned int instr_address_range:1; /* Supports instruction address range
                                            limiting */
     unsigned int fast_counter_read:1;   /* Supports user level PMC read
                                            instruction */
     unsigned int fast_real_timer:1;     /* Supports a fast real timer */
     unsigned int fast_virtual_timer:1;  /* Supports a fast virtual timer */
     unsigned int attach:1;		     /* Supports attach */
     unsigned int attach_must_ptrace:1;  /* Attach must first ptrace and 
                                            stop the thread/process*/
     unsigned int edge_detect:1;         /* Supports edge detection on events */
     unsigned int invert:1;              /* Supports invert detection on events */
     unsigned int profile_ear:1;         /* Supports data/instr/tlb miss
                                            address sampling */
     unsigned int grouped_cntrs:1;   /* Underlying hardware uses counter groups */
     unsigned int reserved_bits:16;
   } PAPI_substrate_info_t;


   /* address range specification for range restricted counting */
   typedef struct _papi_addr_range_option { /* if both are zero, range disabled */
      int eventset;           /* eventset to restrict */
      caddr_t start;          /* user requested start address of address range */
      caddr_t end;            /* user requested end address of an address range */
      int start_off;          /* hardware specified offset from start address */
      int end_off;            /* hardware specified offset from end address */
   } PAPI_addr_range_option_t;

The file, papi.h, contains current definitions for the structures unioned in the PAPI_option_t structure. Users should refer to papi.h for specifics on the use of fields in these structures.

In the following code example, PAPI_get_opt is used to acquire the option, PAPI_MAX_HWCTRS, of an event set and PAPI_set_opt is used to set the option, PAPI_DOMAIN, to the same event set:

#include <papi.h>
#include <stdio.h>
int num, retval, EventSet = PAPI_NULL;
PAPI_option_t options;
/* Initialize the PAPI library */
retval = PAPI_library_init(PAPI_VER_CURRENT);
if (retval != PAPI_VER_CURRENT) {
  fprintf(stderr, "PAPI library init error!\n");
if ((num = PAPI_get_opt(PAPI_MAX_HWCTRS,NULL)) <= 0)
printf("This machine has %d counters.0,num);
if (PAPI_create_eventset(&EventSet) != PAPI_OK)
/* Set the domain of this EventSet
   to counter user and kernel modes for this
   process */
options.domain.eventset = EventSet;
options.domain.domain = PAPI_DOM_ALL;
if (PAPI_set_opt(PAPI_DOMAIN, &options) != PAPI_OK)
This machine has 4 counters.

On success, these functions return PAPI_OK and on error, a non-zero error code is returned.

For more code examples, see src/ctests/second.c in the PAPI source distribution, or search the ctests codebase for PAPI_set_opt or PAPI_get_opt.