From 695231338ec482467007fc3c3fa013243b1d69b3 Mon Sep 17 00:00:00 2001 From: Daniel Barry Date: Thu, 31 Oct 2024 09:19:33 -0700 Subject: [PATCH 1/8] framework: fields for component presets Create fields in the vector struct for components to define presets. These changes have been tested on the NVIDIA Hopper architecture. --- src/papi_vector.c | 3 +++ src/papi_vector.h | 1 + 2 files changed, 4 insertions(+) diff --git a/src/papi_vector.c b/src/papi_vector.c index 3f8f531d4..69d8e7187 100644 --- a/src/papi_vector.c +++ b/src/papi_vector.c @@ -144,6 +144,9 @@ _papi_hwi_innoculate_vector( papi_vector_t * v ) v->init_component = ( int ( * )( int ) ) vec_int_ok_dummy; if ( !v->init_thread ) v->init_thread = ( int ( * )( hwd_context_t * ) ) vec_int_ok_dummy; + if ( !v->init_comp_presets ) { + v->init_comp_presets = ( int ( * )( void ) ) vec_int_ok_dummy; + } if ( !v->init_control_state ) v->init_control_state = ( int ( * )( hwd_control_state_t * ptr ) ) vec_int_dummy; diff --git a/src/papi_vector.h b/src/papi_vector.h index c34db0657..2021a0e77 100644 --- a/src/papi_vector.h +++ b/src/papi_vector.h @@ -35,6 +35,7 @@ typedef struct papi_vectors { int (*init_component) (int); /**< */ int (*init_thread) (hwd_context_t *); /**< */ int (*init_control_state) (hwd_control_state_t * ptr); /**< */ + int (*init_comp_presets) (void); /**< */ int (*update_control_state) (hwd_control_state_t *, NativeInfo_t *, int, hwd_context_t *); /**< */ int (*ctl) (hwd_context_t *, int , _papi_int_option_t *); /**< */ int (*set_overflow) (EventSetInfo_t *, int, int); /**< */ From 55729a4b91092377f81e04bee17241bb5d1a3fb9 Mon Sep 17 00:00:00 2001 From: Daniel Barry Date: Mon, 28 Oct 2024 07:21:46 -0700 Subject: [PATCH 2/8] cuda: updates for presets Add functions to facilitate CUDA presets. These changes have been tested on the NVIDIA Hopper architecture. --- src/components/cuda/cupti_dispatch.c | 10 ++ src/components/cuda/cupti_dispatch.h | 2 + src/components/cuda/cupti_profiler.c | 22 ---- src/components/cuda/linux-cuda.c | 37 +++++++ src/components/cuda/papi_cuda_presets.h | 139 ++++++++++++++++++++++++ src/components/cuda/papi_cupti_common.c | 22 ++++ src/components/cuda/papi_cupti_common.h | 3 + 7 files changed, 213 insertions(+), 22 deletions(-) create mode 100644 src/components/cuda/papi_cuda_presets.h diff --git a/src/components/cuda/cupti_dispatch.c b/src/components/cuda/cupti_dispatch.c index 65c96109e..f2e485aa3 100644 --- a/src/components/cuda/cupti_dispatch.c +++ b/src/components/cuda/cupti_dispatch.c @@ -49,6 +49,16 @@ void cuptid_disabled_reason_get(const char **msg) cuptic_disabled_reason_get(msg); } +int cuptid_get_chip_name(int dev_num, char *name) +{ + return get_chip_name(dev_num, name); +} + +int cuptid_device_get_count(int *num_gpus) +{ + return cuptic_device_get_count(num_gpus); +} + int cuptid_init(void) { int papi_errno; diff --git a/src/components/cuda/cupti_dispatch.h b/src/components/cuda/cupti_dispatch.h index e3589bf8e..e9ff673d8 100644 --- a/src/components/cuda/cupti_dispatch.h +++ b/src/components/cuda/cupti_dispatch.h @@ -43,5 +43,7 @@ int cuptid_thread_info_destroy(cuptid_info_t *info); /* misc. */ void cuptid_disabled_reason_get(const char **msg); +int cuptid_get_chip_name(int dev_num, char *name); +int cuptid_device_get_count(int *num_gpus); #endif /* __CUPTI_DISPATCH_H__ */ diff --git a/src/components/cuda/cupti_profiler.c b/src/components/cuda/cupti_profiler.c index c1b6cfb64..e1aa26297 100644 --- a/src/components/cuda/cupti_profiler.c +++ b/src/components/cuda/cupti_profiler.c @@ -136,7 +136,6 @@ static int begin_profiling(cuptip_gpu_state_t *gpu_ctl); static int end_profiling(cuptip_gpu_state_t *gpu_ctl); /* NVIDIA chip functions */ -static int get_chip_name(int dev_num, char* chipName); static int find_same_chipname(int gpu_id); /* functions to check if a cuda native event requires multiple passes */ @@ -195,7 +194,6 @@ NVPA_Status ( *NVPW_MetricsContext_GetCounterNames_BeginPtr ) (NVPW_MetricsConte NVPA_Status ( *NVPW_MetricsContext_GetCounterNames_EndPtr ) (NVPW_MetricsContext_GetCounterNames_End_Params* pParams); /* cupti function pointers */ -CUptiResult ( *cuptiDeviceGetChipNamePtr ) (CUpti_Device_GetChipName_Params* params); CUptiResult ( *cuptiProfilerInitializePtr ) (CUpti_Profiler_Initialize_Params* params); CUptiResult ( *cuptiProfilerDeInitializePtr ) (CUpti_Profiler_DeInitialize_Params* params); CUptiResult ( *cuptiProfilerCounterDataImageCalculateSizePtr ) (CUpti_Profiler_CounterDataImage_CalculateSize_Params* params); @@ -229,7 +227,6 @@ static int load_cupti_perf_sym(void) goto fn_fail; } - cuptiDeviceGetChipNamePtr = DLSYM_AND_CHECK(dl_cupti, "cuptiDeviceGetChipName"); cuptiProfilerInitializePtr = DLSYM_AND_CHECK(dl_cupti, "cuptiProfilerInitialize"); cuptiProfilerDeInitializePtr = DLSYM_AND_CHECK(dl_cupti, "cuptiProfilerDeInitialize"); cuptiProfilerCounterDataImageCalculateSizePtr = DLSYM_AND_CHECK(dl_cupti, "cuptiProfilerCounterDataImageCalculateSize"); @@ -266,7 +263,6 @@ static int unload_cupti_perf_sym(void) dlclose(dl_cupti); dl_cupti = NULL; } - cuptiDeviceGetChipNamePtr = NULL; cuptiProfilerInitializePtr = NULL; cuptiProfilerDeInitializePtr = NULL; cuptiProfilerCounterDataImageCalculateSizePtr = NULL; @@ -469,24 +465,6 @@ static int initialize_perfworks_api(void) } -static int get_chip_name(int dev_num, char* chipName) -{ - int papi_errno; - CUpti_Device_GetChipName_Params getChipName = { - .structSize = CUpti_Device_GetChipName_Params_STRUCT_SIZE, - .pPriv = NULL, - .deviceIndex = 0 - }; - getChipName.deviceIndex = dev_num; - papi_errno = cuptiDeviceGetChipNamePtr(&getChipName); - if (papi_errno != CUPTI_SUCCESS) { - ERRDBG("CUPTI error %d: Failed to get chip name for device %d\n", papi_errno, dev_num); - return PAPI_EMISC; - } - strcpy(chipName, getChipName.pChipName); - return PAPI_OK; -} - /** @class get_event_names_rmr * @brief For a Cuda native event name collect raw metrics and count * of raw metrics for collection. Raw Metrics are one layer of the Metric API diff --git a/src/components/cuda/linux-cuda.c b/src/components/cuda/linux-cuda.c index 37e173864..702e105a4 100644 --- a/src/components/cuda/linux-cuda.c +++ b/src/components/cuda/linux-cuda.c @@ -42,6 +42,7 @@ static int cuda_init_thread(hwd_context_t *ctx); static int cuda_init_control_state(hwd_control_state_t *ctl); static int cuda_shutdown_thread(hwd_context_t *ctx); static int cuda_shutdown_component(void); +static int cuda_init_comp_presets(void); /* set and update component state */ static int cuda_update_control_state(hwd_control_state_t *ctl, @@ -117,6 +118,7 @@ papi_vector_t _cuda_vector = { .init_thread = cuda_init_thread, .shutdown_thread = cuda_shutdown_thread, + .init_comp_presets = cuda_init_comp_presets, .ntv_enum_events = cuda_ntv_enum_events, .ntv_code_to_name = cuda_ntv_code_to_name, @@ -314,6 +316,41 @@ static int cuda_shutdown_thread(hwd_context_t *ctx) return PAPI_OK; } +static int cuda_init_comp_presets(void) +{ + int cidx = _cuda_vector.cmp_info.CmpIdx; + char *cname = _cuda_vector.cmp_info.name; + + /* Setup presets. */ + char arch_name[PAPI_2MAX_STR_LEN]; + int devIdx = -1; + int numDevices = 0; + + int retval = cuptid_device_get_count(&numDevices); + if ( retval != PAPI_OK ) { + return PAPI_EMISC; + } + + /* Load preset table for every device type available on the system. + * As long as one of the cards has presets defined, then they should + * be available. */ + for( devIdx = 0; devIdx < numDevices; ++devIdx ) { + retval = cuptid_get_chip_name(devIdx, arch_name); + if ( retval == PAPI_OK ) { + break; + } + } + + if ( devIdx > -1 && devIdx < numDevices ) { + retval = _papi_load_preset_table_component( cname, arch_name, cidx ); + if ( retval != PAPI_OK ) { + return PAPI_ENOEVNT; + } + } + + return PAPI_OK; +} + static int cuda_init_control_state(hwd_control_state_t __attribute__((unused)) *ctl) { COMPDBG("Entering.\n"); diff --git a/src/components/cuda/papi_cuda_presets.h b/src/components/cuda/papi_cuda_presets.h new file mode 100644 index 000000000..c35d740a4 --- /dev/null +++ b/src/components/cuda/papi_cuda_presets.h @@ -0,0 +1,139 @@ +#ifndef __PAPI_CUDA_PRESETS_H__ +#define __PAPI_CUDA_PRESETS_H__ + +#define PAPI_MAX_cuda_PRESETS 128 + +hwi_presets_t _cuda_presets[PAPI_MAX_cuda_PRESETS] = { +/* 0 */ {"PAPI_CUDA_FP16_FMA", + "CUDA FP16 FMA instr", + "CUDA Half precision (FP16) FMA instructions", 0, + 0, PAPI_PRESET_BIT_MSC, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 1 */ {"PAPI_CUDA_BF16_FMA", + "CUDA BF16 FMA instr", + "CUDA Half precision (BF16) FMA instructions", 0, + 0, PAPI_PRESET_BIT_MSC, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 2 */ {"PAPI_CUDA_FP32_FMA", + "CUDA FP32 FMA instr", + "CUDA Single precision (FP32) FMA instructions", 0, + 0, PAPI_PRESET_BIT_MSC, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 3 */ {"PAPI_CUDA_FP64_FMA", + "CUDA FP64 FMA instr", + "CUDA Double precision (FP64) FMA instructions", 0, + 0, PAPI_PRESET_BIT_MSC, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 4 */ {"PAPI_CUDA_FMA", + "CUDA FMA instr", + "CUDA FMA instructions", 0, + 0, PAPI_PRESET_BIT_MSC, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 4 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 5 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 6 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 7 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 8 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 9 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 10 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 11 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 12 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 13 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 14 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 15 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 16 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 17 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 18 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 19 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 21 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 22 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 23 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 24 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 25 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 26 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 27 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 28 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 29 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 30 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 31 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 32 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 33 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 34 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 35 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 36 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 37 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 38 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 39 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 40 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 41 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 42 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 43 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 44 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 45 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 46 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 47 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 48 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 49 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 50 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 51 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 52 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 53 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 54 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 55 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 56 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 57 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 58 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 59 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 60 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 61 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 62 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 63 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 64 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 65 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 66 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 67 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 68 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 69 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 70 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 71 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 72 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 73 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 74 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 75 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 76 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 77 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 78 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 79 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 80 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 81 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 82 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 83 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 84 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 85 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 86 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 87 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 88 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 89 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 90 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 91 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 92 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 93 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 94 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 95 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 96 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 97 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 98 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/* 99 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*100 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*110 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*120 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*121 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*122 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*123 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*124 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*125 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*126 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*127 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +}; + +#endif /* __PAPI_CUDA_PRESETS_H__ */ diff --git a/src/components/cuda/papi_cupti_common.c b/src/components/cuda/papi_cupti_common.c index f3aeb9e08..809d35455 100644 --- a/src/components/cuda/papi_cupti_common.c +++ b/src/components/cuda/papi_cupti_common.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "papi_memory.h" #include "cupti_config.h" @@ -52,6 +53,7 @@ cudaError_t ( *cudaRuntimeGetVersionPtr ) (int *); /* cupti function pointer */ CUptiResult ( *cuptiGetVersionPtr ) (uint32_t* ); +CUptiResult ( *cuptiDeviceGetChipNamePtr ) (CUpti_Device_GetChipName_Params* params); /**@class load_cuda_sym * @brief Search for libcuda.so. @@ -278,6 +280,7 @@ static int load_cupti_common_sym(void) } cuptiGetVersionPtr = DLSYM_AND_CHECK(dl_cupti, "cuptiGetVersion"); + cuptiDeviceGetChipNamePtr = DLSYM_AND_CHECK(dl_cupti, "cuptiDeviceGetChipName"); Dl_info info; dladdr(cuptiGetVersionPtr, &info); @@ -294,6 +297,7 @@ static int unload_cupti_common_sym(void) dl_cupti = NULL; } cuptiGetVersionPtr = NULL; + cuptiDeviceGetChipNamePtr = NULL; return PAPI_OK; } @@ -764,3 +768,21 @@ int cuptiu_dev_check(cuptiu_bitmap_t bitmap, int i) { return (bitmap & (1ULL << i)); } + +int get_chip_name(int dev_num, char* chipName) +{ + int papi_errno; + CUpti_Device_GetChipName_Params getChipName = { + .structSize = CUpti_Device_GetChipName_Params_STRUCT_SIZE, + .pPriv = NULL, + .deviceIndex = 0 + }; + getChipName.deviceIndex = dev_num; + papi_errno = cuptiDeviceGetChipNamePtr(&getChipName); + if (papi_errno != CUPTI_SUCCESS) { + ERRDBG("CUPTI error %d: Failed to get chip name for device %d\n", papi_errno, dev_num); + return PAPI_EMISC; + } + strcpy(chipName, getChipName.pChipName); + return PAPI_OK; +} diff --git a/src/components/cuda/papi_cupti_common.h b/src/components/cuda/papi_cupti_common.h index 13a30828f..cd8330949 100644 --- a/src/components/cuda/papi_cupti_common.h +++ b/src/components/cuda/papi_cupti_common.h @@ -77,6 +77,9 @@ int cuptic_device_release(cuptiu_event_table_t *evt_table); int cuptiu_dev_set(cuptiu_bitmap_t *bitmap, int i); int cuptiu_dev_check(cuptiu_bitmap_t bitmap, int i); +/* misc. */ +int get_chip_name(int dev_num, char* chipName); + #define DLSYM_AND_CHECK( dllib, name ) dlsym( dllib, name ); \ if (dlerror() != NULL) { \ ERRDBG("A CUDA required function '%s' was not found in lib '%s'.\n", name, #dllib); \ From 96a73d1a7513669a5008f7ba041a8a7d8f31b1fb Mon Sep 17 00:00:00 2001 From: Daniel Barry Date: Mon, 28 Oct 2024 07:40:10 -0700 Subject: [PATCH 3/8] presets: support for NVIDIA Hopper and Ampere --- src/papi_events.csv | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/papi_events.csv b/src/papi_events.csv index caa6f4f11..62ea7c5e5 100644 --- a/src/papi_events.csv +++ b/src/papi_events.csv @@ -2321,6 +2321,15 @@ PRESET,PAPI_HW_INT,DERIVED_ADD,EXC_IRQ,EXC_FIQ PRESET,PAPI_SYC_INS,DERIVED_ADD,ISB_SPEC,DSB_SPEC,DMB_SPEC PRESET,PAPI_TLB_DM,NOT_DERIVED,L2D_TLB_REFILL +cuda,GH100 +cuda,GA106 +cuda,GA100 +# +PRESET,PAPI_CUDA_FP16_FMA,NOT_DERIVED,cuda:::sm__sass_thread_inst_executed_op_hfma_pred_on.sum +PRESET,PAPI_CUDA_FP32_FMA,NOT_DERIVED,cuda:::sm__sass_thread_inst_executed_op_ffma_pred_on.sum +PRESET,PAPI_CUDA_FP64_FMA,NOT_DERIVED,cuda:::sm__sass_thread_inst_executed_op_dfma_pred_on.sum +PRESET,PAPI_CUDA_FMA,DERIVED_POSTFIX,N0|N1|+|N2|+|,cuda:::sm__sass_thread_inst_executed_op_hfma_pred_on.sum,cuda:::sm__sass_thread_inst_executed_op_ffma_pred_on.sum,cuda:::sm__sass_thread_inst_executed_op_dfma_pred_on.sum + ######################### # ARM Neoverse V2 # ######################### From 3f540eaa9e3557dea648bdf8aa7755c92d53284d Mon Sep 17 00:00:00 2001 From: Daniel Barry Date: Thu, 31 Oct 2024 09:15:56 -0700 Subject: [PATCH 4/8] config: updates for component presets Update configure to track both the number of presets per component and the arrays of presets belonging to each component. These changes have been tested on the NVIDIA Hopper architecture. --- src/configure | 87 ++++++++++++++++++++++++++++++++++++++++++++++-- src/configure.in | 65 ++++++++++++++++++++++++++++++++++-- 2 files changed, 147 insertions(+), 5 deletions(-) diff --git a/src/configure b/src/configure index 89c15e8ce..f2791bd33 100755 --- a/src/configure +++ b/src/configure @@ -6762,6 +6762,9 @@ if test "${with_components+set}" = set; then : fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $components" >&5 +$as_echo "$components" >&6; } + # This is an ugly hack to keep building on configurations covered by any-null in the past. if test "$VECTOR" = "_papi_dummy_vector"; then if test "x$components" = "x"; then @@ -6820,6 +6823,87 @@ if test "$with_sysdetect" = "yes"; then components="$components sysdetect" fi +# includes for preset headers +for comp in $components; do + idx=`echo "$comp" | sed -n "s/\/.*//p" | wc -c` + if test "$idx" = 0; then + subcomp=$comp + else + subcomp=`echo $comp | sed -E "s/^.{${idx}}//"` + fi + if test "${subcomp}" != "perf_event"; then + subcomp_preset_inc=components/${subcomp}/papi_${subcomp}_presets.h + as_ac_File=`$as_echo "ac_cv_file_${subcomp_preset_inc}" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${subcomp_preset_inc}" >&5 +$as_echo_n "checking for ${subcomp_preset_inc}... " >&6; } +if eval \${$as_ac_File+:} false; then : + $as_echo_n "(cached) " >&6 +else + test "$cross_compiling" = yes && + as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 +if test -r "${subcomp_preset_inc}"; then + eval "$as_ac_File=yes" +else + eval "$as_ac_File=no" +fi +fi +eval ac_res=\$$as_ac_File + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_File"\" = x"yes"; then : + `echo "#include \"${subcomp_preset_inc}\"" >> components_config.h` +fi + + fi +done +echo "" >> components_config.h + +# array tracking max number of presets per component +echo "int _papi_hwi_max_presets[] = {" >> components_config.h +echo " PAPI_MAX_PRESET_EVENTS," >> components_config.h +for comp in $components; do + idx=`echo "$comp" | sed -n "s/\/.*//p" | wc -c` + if test "$idx" = 0; then + subcomp=$comp + else + subcomp=`echo $comp | sed -E "s/^.{${idx}}//"` + fi + if test "${subcomp}" != "perf_event"; then + subcomp_preset_inc=components/${subcomp}/papi_${subcomp}_presets.h + if test -f ${subcomp_preset_inc}; then + `echo " PAPI_MAX_${subcomp}_PRESETS," >> components_config.h` + else + `echo " 0," >> components_config.h` + fi + fi +done +echo " 0" >> components_config.h +echo "};" >> components_config.h +echo "" >> components_config.h + +# preset arrays +echo "hwi_presets_t *_papi_hwi_comp_presets[] = {" >> components_config.h +echo " _papi_hwi_presets," >> components_config.h +for comp in $components; do + idx=`echo "$comp" | sed -n "s/\/.*//p" | wc -c` + if test "$idx" = 0; then + subcomp=$comp + else + subcomp=`echo $comp | sed -E "s/^.{${idx}}//"` + fi + if test "${subcomp}" != "perf_event"; then + subcomp_preset_inc=components/${subcomp}/papi_${subcomp}_presets.h + if test -f ${subcomp_preset_inc}; then + `echo " _${subcomp}_presets," >> components_config.h` + else + `echo " NULL," >> components_config.h` + fi + fi +done +echo " NULL" >> components_config.h +echo "};" >> components_config.h +echo "" >> components_config.h + PAPI_NUM_COMP=0 for comp in $components; do idx=`echo "$comp" | sed -n "s/\/.*//p" | wc -c` @@ -6901,9 +6985,6 @@ done CFLAGS="$CFLAGS -DPAPI_NUM_COMP=$PAPI_NUM_COMP" -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $components" >&5 -$as_echo "$components" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PAPI event CSV filename to use" >&5 $as_echo_n "checking for PAPI event CSV filename to use... " >&6; } if test "x$PAPI_EVENTS_CSV" == "x"; then diff --git a/src/configure.in b/src/configure.in index 99d2d90ef..d2ba95f53 100644 --- a/src/configure.in +++ b/src/configure.in @@ -1766,6 +1766,8 @@ AC_ARG_WITH(components, [Specify which components to build])], [components="$components $withval"]) +AC_MSG_RESULT($components) + # This is an ugly hack to keep building on configurations covered by any-null in the past. if test "$VECTOR" = "_papi_dummy_vector"; then if test "x$components" = "x"; then @@ -1824,6 +1826,67 @@ if test "$with_sysdetect" = "yes"; then components="$components sysdetect" fi +# includes for preset headers +for comp in $components; do + idx=`echo "$comp" | sed -n "s/\/.*//p" | wc -c` + if test "$idx" = 0; then + subcomp=$comp + else + subcomp=`echo $comp | sed -E "s/^.{${idx}}//"` + fi + if test "${subcomp}" != "perf_event"; then + subcomp_preset_inc=components/${subcomp}/papi_${subcomp}_presets.h + AC_CHECK_FILE(${subcomp_preset_inc}, [`echo "#include \"${subcomp_preset_inc}\"" >> components_config.h`]) + fi +done +echo "" >> components_config.h + +# array tracking max number of presets per component +echo "int _papi_hwi_max_presets[[]] = {" >> components_config.h +echo " PAPI_MAX_PRESET_EVENTS," >> components_config.h +for comp in $components; do + idx=`echo "$comp" | sed -n "s/\/.*//p" | wc -c` + if test "$idx" = 0; then + subcomp=$comp + else + subcomp=`echo $comp | sed -E "s/^.{${idx}}//"` + fi + if test "${subcomp}" != "perf_event"; then + subcomp_preset_inc=components/${subcomp}/papi_${subcomp}_presets.h + if test -f ${subcomp_preset_inc}; then + `echo " PAPI_MAX_${subcomp}_PRESETS," >> components_config.h` + else + `echo " 0," >> components_config.h` + fi + fi +done +echo " 0" >> components_config.h +echo "};" >> components_config.h +echo "" >> components_config.h + +# preset arrays +echo "hwi_presets_t *_papi_hwi_comp_presets[[]] = {" >> components_config.h +echo " _papi_hwi_presets," >> components_config.h +for comp in $components; do + idx=`echo "$comp" | sed -n "s/\/.*//p" | wc -c` + if test "$idx" = 0; then + subcomp=$comp + else + subcomp=`echo $comp | sed -E "s/^.{${idx}}//"` + fi + if test "${subcomp}" != "perf_event"; then + subcomp_preset_inc=components/${subcomp}/papi_${subcomp}_presets.h + if test -f ${subcomp_preset_inc}; then + `echo " _${subcomp}_presets," >> components_config.h` + else + `echo " NULL," >> components_config.h` + fi + fi +done +echo " NULL" >> components_config.h +echo "};" >> components_config.h +echo "" >> components_config.h + PAPI_NUM_COMP=0 for comp in $components; do idx=`echo "$comp" | sed -n "s/\/.*//p" | wc -c` @@ -1905,8 +1968,6 @@ done CFLAGS="$CFLAGS -DPAPI_NUM_COMP=$PAPI_NUM_COMP" -AC_MSG_RESULT($components) - AC_MSG_CHECKING(for PAPI event CSV filename to use) if test "x$PAPI_EVENTS_CSV" == "x"; then PAPI_EVENTS_CSV="papi_events.csv" From 773255ee4ab24532964845f54c5f502f1b3df765 Mon Sep 17 00:00:00 2001 From: Daniel Barry Date: Thu, 31 Oct 2024 09:55:01 -0700 Subject: [PATCH 5/8] framework: support for component presets Updates to framework to facilitate preset events defined by native events of non-perf_event components. These changes have been tested on the NVIDIA Hopper architecture. --- src/papi.c | 326 +++++++++++++++++----- src/papi.h | 8 + src/papi_common_strings.h | 256 +++++++++--------- src/papi_internal.c | 186 ++++++++++--- src/papi_internal.h | 7 + src/papi_preset.c | 553 +++++++++++++++++++++++++++++++++++--- src/papi_preset.h | 14 +- 7 files changed, 1082 insertions(+), 268 deletions(-) diff --git a/src/papi.c b/src/papi.c index 5ddea8b11..0ffb38dfd 100644 --- a/src/papi.c +++ b/src/papi.c @@ -586,6 +586,11 @@ _rate_calls( float *real_time, float *proc_time, int *events, extern hwi_presets_t user_defined_events[PAPI_MAX_USER_EVENTS]; extern int user_defined_events_count; +extern int num_all_presets; +extern int _papi_hwi_start_idx[PAPI_NUM_COMP]; +extern int pe_idx; +extern int comp_idx; +extern int first_comp_preset_idx; #ifdef DEBUG @@ -1186,6 +1191,17 @@ PAPI_library_init( int version ) _in_papi_library_init_cnt--; papi_return( init_retval ); } + + + /* Initialize component preset globals. */ + + tmp = _papi_hwi_init_global_presets(); + if ( tmp ) { + init_retval = tmp; + _papi_hwi_shutdown_global_internal( ); + _in_papi_library_init_cnt--; + papi_return( init_retval ); + } init_level = PAPI_LOW_LEVEL_INITED; _in_papi_library_init_cnt--; @@ -1240,10 +1256,16 @@ PAPI_query_event( int EventCode ) APIDBG( "Entry: EventCode: %#x\n", EventCode); if ( IS_PRESET(EventCode) ) { EventCode &= PAPI_PRESET_AND_MASK; - if ( EventCode < 0 || EventCode >= PAPI_MAX_PRESET_EVENTS ) + if ( EventCode < 0 || EventCode >= num_all_presets ) papi_return( PAPI_ENOTPRESET ); - if ( _papi_hwi_presets[EventCode].count ) + int preset_index = EventCode; + int compIdx = get_preset_cmp(&preset_index); + if( compIdx < 0 ) { + return ( PAPI_ENOEVNT ); + } + + if ( _papi_hwi_comp_presets[compIdx][preset_index].count ) papi_return (PAPI_OK); else return PAPI_ENOEVNT; @@ -1396,8 +1418,9 @@ PAPI_get_event_info( int EventCode, PAPI_event_info_t *info ) if ( IS_PRESET(EventCode) ) { i = EventCode & PAPI_PRESET_AND_MASK; - if ( i >= PAPI_MAX_PRESET_EVENTS ) + if ( i >= num_all_presets ) { papi_return( PAPI_ENOTPRESET ); + } papi_return( _papi_hwi_get_preset_event_info( EventCode, info ) ); } @@ -1474,13 +1497,19 @@ PAPI_event_code_to_name( int EventCode, char *out ) if ( IS_PRESET(EventCode) ) { EventCode &= PAPI_PRESET_AND_MASK; - if ( EventCode < 0 || EventCode >= PAPI_MAX_PRESET_EVENTS ) + if ( EventCode < 0 || EventCode >= num_all_presets ) papi_return( PAPI_ENOTPRESET ); if (_papi_hwi_presets[EventCode].symbol == NULL ) papi_return( PAPI_ENOTPRESET ); - strncpy( out, _papi_hwi_presets[EventCode].symbol, PAPI_MAX_STR_LEN-1 ); + int preset_index = EventCode; + int compIdx = get_preset_cmp(&preset_index); + if( compIdx < 0 ) { + return ( PAPI_ENOEVNT ); + } + + strncpy( out, _papi_hwi_comp_presets[compIdx][preset_index].symbol, PAPI_MAX_STR_LEN-1 ); out[PAPI_MAX_STR_LEN-1] = '\0'; papi_return( PAPI_OK ); } @@ -1569,13 +1598,96 @@ PAPI_event_name_to_code( const char *in, int *out ) /* All presets start with "PAPI_" so no need to */ /* do an exhaustive search if that's not there */ if (strncmp(in, "PAPI_", 5) == 0) { - for(i = 0; i < PAPI_MAX_PRESET_EVENTS; i++ ) { - if ( ( _papi_hwi_presets[i].symbol ) - && ( strcasecmp( _papi_hwi_presets[i].symbol, in ) == 0) ) { - *out = ( int ) ( i | PAPI_PRESET_MASK ); - papi_return( PAPI_OK ); - } - } + + /* Split event name into base name and qualifier. */ + int preset_idx = -1; + char *evt_name_copy = strdup(in); + if( NULL == evt_name_copy ) { + fprintf(stdout, "evt_name_copy is NULL\n"); + fflush(stdout); + papi_return( PAPI_EINVAL ); + } + + char *evt_base_name = strtok(evt_name_copy, ":"); + if( NULL == evt_base_name ) { + fprintf(stdout, "evt_base_name is NULL\n"); + fflush(stdout); + papi_return( PAPI_EINVAL ); + } + + char *qual_str = NULL; + if( NULL != evt_base_name ) { + qual_str = index(in, ':'); + } else { + fprintf(stdout, "premature return 1: NULL\n"); + fflush(stdout); + papi_return( PAPI_EINVAL ); + } + + /* Since the preset could live inside of either the CPU or component preset list, + * set the list pointer appropriately. */ + hwi_presets_t *_papi_hwi_list = NULL; + + /* Now check the component presets. */ + int cmpnt, breakFlag = 0; + for(cmpnt = 0; cmpnt < PAPI_NUM_COMP; cmpnt++ ) { + _papi_hwi_list = _papi_hwi_comp_presets[cmpnt]; + for(i = 0; i < _papi_hwi_max_presets[cmpnt]; i++ ) { + if ( ( _papi_hwi_list[i].symbol ) + && ( strcasecmp( _papi_hwi_list[i].symbol, evt_base_name ) == 0) ) { + *out = ( int ) ( (i + _papi_hwi_start_idx[cmpnt]) | PAPI_PRESET_MASK ); + preset_idx = i; + breakFlag = 1; + break; + } + } + /* Checks whether preset was found. */ + if( breakFlag ) { + break; + } + } + + free(evt_name_copy); + + /* User may have provided an invalid event name. */ + if( NULL != _papi_hwi_list ) { + + /* Apply qualifier to each native event and update each code. + * If no qualifier was given, do not append to constituent native events. */ + int retval, len; + unsigned int j; + char *new_ntv_name = NULL; + for(j = 0; j < _papi_hwi_list[preset_idx].count; j++ ) { + /* Base name, default name, nor default code do not get updated. There + * are set once and only once when the preset table is initialized. + * Qualified name and code, however, do get updated. */ + len = strlen(_papi_hwi_list[preset_idx].base_name[j]) + 1; + if( qual_str == NULL ) { + new_ntv_name = (char*)malloc(len*sizeof(char)); + retval = sprintf(new_ntv_name, "%s", _papi_hwi_list[preset_idx].base_name[j]); + } else { + len += strlen(qual_str); + new_ntv_name = (char*)malloc(len*sizeof(char)); + retval = sprintf(new_ntv_name, "%s%s", _papi_hwi_list[preset_idx].base_name[j], qual_str); + } //need to use snprintf? + + if( retval != len ) { + } + + /* Set the new name, which includes the qualifier. */ + free(_papi_hwi_list[preset_idx].name[j]); + _papi_hwi_list[preset_idx].name[j] = strdup(new_ntv_name); + + /* Set the corresponding new code. */ + retval = _papi_hwi_native_name_to_code( new_ntv_name, &(_papi_hwi_list[preset_idx].code[j]) ); + /*if( PAPI_OK != retval ) { + }*/ + + free(new_ntv_name); + } + + papi_return( PAPI_OK ); + } } // check to see if it is a user defined event @@ -1687,42 +1799,99 @@ PAPI_enum_event( int *EventCode, int modifier ) cidx = _papi_hwi_component_index( *EventCode ); if (cidx < 0) return PAPI_ENOCMP; - /* Do we handle presets in componets other than CPU? */ - /* if (( IS_PRESET(i) ) && cidx > 0 )) return PAPI_ENOCMP; */ - /* check to see if a valid modifier is provided */ if (modifier != PAPI_ENUM_EVENTS && modifier != PAPI_ENUM_FIRST && modifier != PAPI_ENUM_ALL && modifier != PAPI_PRESET_ENUM_AVAIL && + modifier != PAPI_PRESET_ENUM_CPU && + modifier != PAPI_PRESET_ENUM_CPU_AVAIL && + modifier != PAPI_ENUM_FIRST_COMP && modifier != PAPI_NTV_ENUM_UMASKS && modifier != PAPI_NTV_ENUM_UMASK_COMBOS) { return PAPI_EINVAL; } - if ( IS_PRESET(i) ) { - if ( modifier == PAPI_ENUM_FIRST ) { - *EventCode = ( int ) PAPI_PRESET_MASK; - APIDBG("EXIT: *EventCode: %#x\n", *EventCode); - return ( PAPI_OK ); - } - i &= PAPI_PRESET_AND_MASK; - while ( ++i < PAPI_MAX_PRESET_EVENTS ) { - if ( _papi_hwi_presets[i].symbol == NULL ) { - APIDBG("EXIT: PAPI_ENOEVNT\n"); - return ( PAPI_ENOEVNT ); /* NULL pointer terminates list */ - } - if ( modifier & PAPI_PRESET_ENUM_AVAIL ) { - if ( _papi_hwi_presets[i].count == 0 ) - continue; - } - *EventCode = ( int ) ( i | PAPI_PRESET_MASK ); - APIDBG("EXIT: *EventCode: %#x\n", *EventCode); - return ( PAPI_OK ); - } - papi_return( PAPI_EINVAL ); - } + /* If it is a component preset, it will be in a separate array. */ + int preset_index; + hwi_presets_t *_papi_hwi_list; + + if ( IS_PRESET(i) ) { + + /* Set to the first preset. */ + if ( modifier == PAPI_ENUM_FIRST ) { + *EventCode = ( int ) PAPI_PRESET_MASK; + APIDBG("EXIT: *EventCode: %#x\n", *EventCode); + return ( PAPI_OK ); + } + + i &= PAPI_PRESET_AND_MASK; + + /* Iterate over all or all available presets. */ + if ( modifier == PAPI_ENUM_EVENTS || modifier == PAPI_PRESET_ENUM_AVAIL ) { + + /* NULL pointer used to terminate the list. However, now we have + * more presets that exist beyond the bounds of the original + * array, so skip over the NULL entries. */ + do { + if ( ++i >= num_all_presets ) { + return ( PAPI_EINVAL ); + } + + /* Find the component to which the preset belongs and set the + * preset index relative to the component's presets' index range. */ + preset_index = i; + int compIdx = get_preset_cmp(&preset_index); + if( compIdx < 0 ) { + return ( PAPI_ENOEVNT ); + } + + _papi_hwi_list = _papi_hwi_comp_presets[compIdx]; + + if ( modifier == PAPI_PRESET_ENUM_AVAIL + && _papi_hwi_list[preset_index].count == 0 ) { + continue; + } + } while ( _papi_hwi_list[preset_index].symbol == NULL ); + + *EventCode = ( int ) ( i | PAPI_PRESET_MASK ); + APIDBG("EXIT: *EventCode: %#x\n", *EventCode); + return ( PAPI_OK ); + } + + /* Set to the first component preset. */ + if ( modifier == PAPI_ENUM_FIRST_COMP ) { + + preset_index = get_first_cmp_preset_idx(); + if( preset_index < 0 ) { + return ( PAPI_ENOEVNT ); + } + *EventCode = ( int ) ( preset_index | PAPI_PRESET_MASK ); + APIDBG("EXIT: *EventCode: %#x\n", *EventCode); + return ( PAPI_OK ); + } + + /* Iterate over CPU presets. */ + if ( modifier == PAPI_PRESET_ENUM_CPU || modifier == PAPI_PRESET_ENUM_CPU_AVAIL ) { + + while ( ++i < PAPI_MAX_PRESET_EVENTS ) { + if ( _papi_hwi_presets[i].symbol == NULL ) { + APIDBG("EXIT: PAPI_ENOEVNT\n"); + return ( PAPI_ENOEVNT ); /* NULL pointer terminates list */ + } + if ( modifier == PAPI_PRESET_ENUM_CPU_AVAIL + && _papi_hwi_presets[i].count == 0 ) { + continue; + } + *EventCode = ( int ) ( i | PAPI_PRESET_MASK ); + APIDBG("EXIT: *EventCode: %#x\n", *EventCode); + return ( PAPI_OK ); + } + } + + papi_return( PAPI_EINVAL ); + } if ( IS_NATIVE(i) ) { // save event code so components can get it with call to: _papi_hwi_get_papi_event_code() @@ -1899,7 +2068,7 @@ PAPI_enum_cmp_event( int *EventCode, int modifier, int cidx ) int event_code; char *evt_name; - if ( _papi_hwi_invalid_cmp(cidx) || ( (IS_PRESET(i)) && cidx > 0 ) ) { + if ( _papi_hwi_invalid_cmp(cidx) ) { return PAPI_ENOCMP; } @@ -1908,28 +2077,46 @@ PAPI_enum_cmp_event( int *EventCode, int modifier, int cidx ) return PAPI_ENOCMP; } - if ( IS_PRESET(i) ) { - if ( modifier == PAPI_ENUM_FIRST ) { - *EventCode = ( int ) PAPI_PRESET_MASK; - APIDBG("EXIT: *EventCode: %#x\n", *EventCode); - return PAPI_OK; - } - i &= PAPI_PRESET_AND_MASK; - while ( ++i < PAPI_MAX_PRESET_EVENTS ) { - if ( _papi_hwi_presets[i].symbol == NULL ) { - APIDBG("EXIT: PAPI_ENOEVNT\n"); - return ( PAPI_ENOEVNT ); /* NULL pointer terminates list */ - } - if ( modifier & PAPI_PRESET_ENUM_AVAIL ) { - if ( _papi_hwi_presets[i].count == 0 ) - continue; - } - *EventCode = ( int ) ( i | PAPI_PRESET_MASK ); - APIDBG("EXIT: *EventCode: %#x\n", *EventCode); - return PAPI_OK; - } - papi_return( PAPI_EINVAL ); - } + if ( IS_PRESET(i) ) { + + hwi_presets_t *_papi_hwi_list; + + /* Set to the first preset. */ + if ( modifier == PAPI_ENUM_FIRST ) { + *EventCode = ( int ) ( _papi_hwi_start_idx[cidx] | PAPI_PRESET_MASK ); + APIDBG("EXIT: *EventCode: %#x\n", *EventCode); + return ( PAPI_OK ); + } + + i &= PAPI_PRESET_AND_MASK; + + /* Iterate over all or all available presets. */ + if ( modifier == PAPI_ENUM_EVENTS || modifier == PAPI_PRESET_ENUM_AVAIL ) { + + /* NULL pointer used to terminate the list. However, now we have + * more presets that exist beyond the bounds of the original + * array, so skip over the NULL entries. */ + do { + if ( ++i >= _papi_hwi_start_idx[cidx] + _papi_hwi_max_presets[cidx] ) { + return ( PAPI_EINVAL ); + } + + /* Find the component to which the preset belongs. */ + _papi_hwi_list = _papi_hwi_comp_presets[cidx]; + + if ( modifier == PAPI_PRESET_ENUM_AVAIL + && _papi_hwi_list[i].count == 0 ) { + continue; + } + } while ( _papi_hwi_list[i].symbol == NULL ); + + *EventCode = ( int ) ( i | PAPI_PRESET_MASK ); + APIDBG("EXIT: *EventCode: %#x\n", *EventCode); + return ( PAPI_OK ); + } + + papi_return( PAPI_EINVAL ); + } if ( IS_NATIVE(i) ) { // save event code so components can get it with call to: _papi_hwi_get_papi_event_code() @@ -2366,8 +2553,8 @@ PAPI_remove_event( int EventSet, int EventCode ) * * @param EventSet * An integer handle for a PAPI Event Set as created by PAPI_create_eventset. - * @param EventName - * A string containing the event name as listed in papi_avail or papi_native_avail. + * @param EventCode + * A defined event such as PAPI_TOT_INS. * * @retval Positive-Integer * The number of consecutive elements that succeeded before the error. @@ -3055,10 +3242,8 @@ PAPI_reset( int EventSet ) * * The counters continue counting after the read. * - * Note the differences between PAPI_read() and PAPI_accum(). Specifically, - * PAPI_accum() adds the values of the counters to the values stored in the - * array (the second parameter in PAPI_accum()) and then resets the counters - * to zero. + * Note the differences between PAPI_read() and PAPI_accum(), specifically + * that PAPI_accum() resets the values array to zero. * * PAPI_read() assumes an initialized PAPI library and a properly added * event set. @@ -3247,13 +3432,8 @@ PAPI_read_ts( int EventSet, long long *values, long long *cycles ) * These calls assume an initialized PAPI library and a properly added event set. * PAPI_accum adds the counters of the indicated event set into the array values. * The counters are zeroed and continue counting after the operation. - * Note the differences between PAPI_read() and PAPI_accum(). Specifically, - * PAPI_accum() adds the values of the counters to the values stored in the - * array (the second parameter in PAPI_accum()) and then resets the counters - * to zero. - * - * Note: The provided array (second parameter in PAPI_accum) must be initialized for PAPI_accum - * because its values are read inside the function. + * Note the differences between PAPI_read and PAPI_accum, specifically + * that PAPI_accum resets the values array to zero. * * @param EventSet * an integer handle for a PAPI Event Set diff --git a/src/papi.h b/src/papi.h index f9b60ad31..9cc8f7b28 100644 --- a/src/papi.h +++ b/src/papi.h @@ -488,6 +488,7 @@ All of the functions in the PerfAPI should use the following set of constants. enum { PAPI_ENUM_EVENTS = 0, /**< Always enumerate all events */ PAPI_ENUM_FIRST, /**< Enumerate first event (preset or native) */ + PAPI_ENUM_FIRST_COMP, /**< Enumerate first component preset event */ PAPI_PRESET_ENUM_AVAIL, /**< Enumerate events that exist here */ /* PAPI PRESET section */ @@ -503,6 +504,8 @@ enum { PAPI_PRESET_ENUM_L3, /**< L3 cache related preset events */ PAPI_PRESET_ENUM_TLB, /**< Translation Lookaside Buffer events */ PAPI_PRESET_ENUM_FP, /**< Floating Point related preset events */ + PAPI_PRESET_ENUM_CPU, /**< CPU preset events */ + PAPI_PRESET_ENUM_CPU_AVAIL, /**< Available CPU preset events */ /* PAPI native event related section */ PAPI_NTV_ENUM_UMASKS, /**< all individual bits for given group */ @@ -895,6 +898,7 @@ typedef char* PAPI_user_defined_events_file_t; #define PAPIF_DMEM_MAXVAL 12 #define PAPI_MAX_INFO_TERMS 12 /* should match PAPI_EVENTS_IN_DERIVED_EVENT defined in papi_internal.h */ +#define PAPI_MAX_COMP_QUALS 8 /** @ingroup papi_data_structures @@ -1010,6 +1014,10 @@ enum { to delineate platform specific anomalies or restrictions */ + int compIdx; /**< component ID */ + int num_quals; /**< number of qualifiers */ + char quals[PAPI_MAX_COMP_QUALS][PAPI_HUGE_STR_LEN]; /**< qualifiers */ + char descrs[PAPI_MAX_COMP_QUALS][PAPI_HUGE_STR_LEN]; /**< qualifier descriptions */ } PAPI_event_info_t; diff --git a/src/papi_common_strings.h b/src/papi_common_strings.h index bc2e0a14e..9fad38423 100644 --- a/src/papi_common_strings.h +++ b/src/papi_common_strings.h @@ -8,562 +8,562 @@ hwi_presets_t _papi_hwi_presets[PAPI_MAX_PRESET_EVENTS] = { "L1D cache misses", "Level 1 data cache misses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L1, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 1 */ {"PAPI_L1_ICM", "L1I cache misses", "Level 1 instruction cache misses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L1 + PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 2 */ {"PAPI_L2_DCM", "L2D cache misses", "Level 2 data cache misses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 3 */ {"PAPI_L2_ICM", "L2I cache misses", "Level 2 instruction cache misses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2 + PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 4 */ {"PAPI_L3_DCM", "L3D cache misses", "Level 3 data cache misses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L3, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 5 */ {"PAPI_L3_ICM", "L3I cache misses", "Level 3 instruction cache misses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L3 + PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 6 */ {"PAPI_L1_TCM", "L1 cache misses", "Level 1 cache misses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L1, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 7 */ {"PAPI_L2_TCM", "L2 cache misses", "Level 2 cache misses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 8 */ {"PAPI_L3_TCM", "L3 cache misses", "Level 3 cache misses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L3, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 9 */ {"PAPI_CA_SNP", "Snoop Requests", "Requests for a snoop", 0, 0, PAPI_PRESET_BIT_CACH, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 10 */ {"PAPI_CA_SHR", "Ex Acces shared CL", "Requests for exclusive access to shared cache line", 0, 0, PAPI_PRESET_BIT_CACH, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 11 */ {"PAPI_CA_CLN", "Ex Access clean CL", "Requests for exclusive access to clean cache line", 0, 0, PAPI_PRESET_BIT_CACH, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 12 */ {"PAPI_CA_INV", "Cache ln invalid", "Requests for cache line invalidation", 0, 0, PAPI_PRESET_BIT_CACH, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 13 */ {"PAPI_CA_ITV", "Cache ln intervene", "Requests for cache line intervention", 0, 0, PAPI_PRESET_BIT_CACH, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 14 */ {"PAPI_L3_LDM", "L3 load misses", "Level 3 load misses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L3, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 15 */ {"PAPI_L3_STM", "L3 store misses", "Level 3 store misses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L3, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 16 */ {"PAPI_BRU_IDL", "Branch idle cycles", "Cycles branch units are idle", 0, 0, PAPI_PRESET_BIT_IDL + PAPI_PRESET_BIT_BR, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 17 */ {"PAPI_FXU_IDL", "IU idle cycles", "Cycles integer units are idle", 0, 0, PAPI_PRESET_BIT_IDL, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 18 */ {"PAPI_FPU_IDL", "FPU idle cycles", "Cycles floating point units are idle", 0, 0, PAPI_PRESET_BIT_IDL + PAPI_PRESET_BIT_FP, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 19 */ {"PAPI_LSU_IDL", "L/SU idle cycles", "Cycles load/store units are idle", 0, 0, PAPI_PRESET_BIT_IDL + PAPI_PRESET_BIT_MEM, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 20 */ {"PAPI_TLB_DM", "Data TLB misses", "Data translation lookaside buffer misses", 0, 0, PAPI_PRESET_BIT_TLB, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 21 */ {"PAPI_TLB_IM", "Instr TLB misses", "Instruction translation lookaside buffer misses", 0, 0, PAPI_PRESET_BIT_TLB + PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 22 */ {"PAPI_TLB_TL", "Total TLB misses", "Total translation lookaside buffer misses", 0, 0, PAPI_PRESET_BIT_TLB, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 23 */ {"PAPI_L1_LDM", "L1 load misses", "Level 1 load misses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L1, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 24 */ {"PAPI_L1_STM", "L1 store misses", "Level 1 store misses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L1, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 25 */ {"PAPI_L2_LDM", "L2 load misses", "Level 2 load misses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 26 */ {"PAPI_L2_STM", "L2 store misses", "Level 2 store misses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 27 */ {"PAPI_BTAC_M", "Br targt addr miss", "Branch target address cache misses", 0, 0, PAPI_PRESET_BIT_BR, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 28 */ {"PAPI_PRF_DM", "Data prefetch miss", "Data prefetch cache misses", 0, 0, PAPI_PRESET_BIT_CACH, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 29 */ {"PAPI_L3_DCH", "L3D cache hits", "Level 3 data cache hits", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 30 */ {"PAPI_TLB_SD", "TLB shootdowns", "Translation lookaside buffer shootdowns", 0, 0, PAPI_PRESET_BIT_TLB, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 31 */ {"PAPI_CSR_FAL", "Failed store cond", "Failed store conditional instructions", 0, 0, PAPI_PRESET_BIT_CND + PAPI_PRESET_BIT_MEM, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 32 */ {"PAPI_CSR_SUC", "Good store cond", "Successful store conditional instructions", 0, 0, PAPI_PRESET_BIT_CND + PAPI_PRESET_BIT_MEM, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 33 */ {"PAPI_CSR_TOT", "Total store cond", "Total store conditional instructions", 0, 0, PAPI_PRESET_BIT_CND + PAPI_PRESET_BIT_MEM, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 34 */ {"PAPI_MEM_SCY", "Stalled mem cycles", "Cycles Stalled Waiting for memory accesses", 0, 0, PAPI_PRESET_BIT_MEM, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 35 */ {"PAPI_MEM_RCY", "Stalled rd cycles", "Cycles Stalled Waiting for memory Reads", 0, 0, PAPI_PRESET_BIT_MEM, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 36 */ {"PAPI_MEM_WCY", "Stalled wr cycles", "Cycles Stalled Waiting for memory writes", 0, 0, PAPI_PRESET_BIT_MEM, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 37 */ {"PAPI_STL_ICY", "No instr issue", "Cycles with no instruction issue", 0, 0, PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 38 */ {"PAPI_FUL_ICY", "Max instr issue", "Cycles with maximum instruction issue", 0, 0, PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 39 */ {"PAPI_STL_CCY", "No instr done", "Cycles with no instructions completed", 0, 0, PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 40 */ {"PAPI_FUL_CCY", "Max instr done", "Cycles with maximum instructions completed", 0, 0, PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 41 */ {"PAPI_HW_INT", "Hdw interrupts", "Hardware interrupts", 0, 0, PAPI_PRESET_BIT_MSC, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 42 */ {"PAPI_BR_UCN", "Uncond branch", "Unconditional branch instructions", 0, 0, PAPI_PRESET_BIT_BR + PAPI_PRESET_BIT_CND, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 43 */ {"PAPI_BR_CN", "Cond branch", "Conditional branch instructions", 0, 0, PAPI_PRESET_BIT_BR + PAPI_PRESET_BIT_CND, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 44 */ {"PAPI_BR_TKN", "Cond branch taken", "Conditional branch instructions taken", 0, 0, PAPI_PRESET_BIT_BR + PAPI_PRESET_BIT_CND, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 45 */ {"PAPI_BR_NTK", "Cond br not taken", "Conditional branch instructions not taken", 0, 0, PAPI_PRESET_BIT_BR + PAPI_PRESET_BIT_CND, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 46 */ {"PAPI_BR_MSP", "Cond br mspredictd", "Conditional branch instructions mispredicted", 0, 0, PAPI_PRESET_BIT_BR + PAPI_PRESET_BIT_CND, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 47 */ {"PAPI_BR_PRC", "Cond br predicted", "Conditional branch instructions correctly predicted", 0, 0, PAPI_PRESET_BIT_BR + PAPI_PRESET_BIT_CND, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 48 */ {"PAPI_FMA_INS", "FMAs completed", "FMA instructions completed", 0, 0, PAPI_PRESET_BIT_INS + PAPI_PRESET_BIT_FP, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 49 */ {"PAPI_TOT_IIS", "Instr issued", "Instructions issued", 0, 0, PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 50 */ {"PAPI_TOT_INS", "Instr completed", "Instructions completed", 0, 0, PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 51 */ {"PAPI_INT_INS", "Int instructions", "Integer instructions", 0, 0, PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 52 */ {"PAPI_FP_INS", "FP instructions", "Floating point instructions", 0, 0, PAPI_PRESET_BIT_INS + PAPI_PRESET_BIT_FP, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 53 */ {"PAPI_LD_INS", "Loads", "Load instructions", 0, 0, PAPI_PRESET_BIT_MEM, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 54 */ {"PAPI_SR_INS", "Stores", "Store instructions", 0, 0, PAPI_PRESET_BIT_MEM, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 55 */ {"PAPI_BR_INS", "Branches", "Branch instructions", 0, 0, PAPI_PRESET_BIT_BR, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 56 */ {"PAPI_VEC_INS", "Vector/SIMD instr", "Vector/SIMD instructions (could include integer)", 0, 0, PAPI_PRESET_BIT_MSC, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 57 */ {"PAPI_RES_STL", "Stalled res cycles", "Cycles stalled on any resource", 0, 0, PAPI_PRESET_BIT_IDL + PAPI_PRESET_BIT_MSC, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 58 */ {"PAPI_FP_STAL", "Stalled FPU cycles", "Cycles the FP unit(s) are stalled", 0, 0, PAPI_PRESET_BIT_IDL + PAPI_PRESET_BIT_FP, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 59 */ {"PAPI_TOT_CYC", "Total cycles", "Total cycles", 0, 0, PAPI_PRESET_BIT_MSC, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 60 */ {"PAPI_LST_INS", "L/S completed", "Load/store instructions completed", 0, 0, PAPI_PRESET_BIT_INS + PAPI_PRESET_BIT_MEM, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 61 */ {"PAPI_SYC_INS", "Syncs completed", "Synchronization instructions completed", 0, 0, PAPI_PRESET_BIT_INS + PAPI_PRESET_BIT_MSC, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 62 */ {"PAPI_L1_DCH", "L1D cache hits", "Level 1 data cache hits", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L1, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 63 */ {"PAPI_L2_DCH", "L2D cache hits", "Level 2 data cache hits", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 64 */ {"PAPI_L1_DCA", "L1D cache accesses", "Level 1 data cache accesses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L1, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 65 */ {"PAPI_L2_DCA", "L2D cache accesses", "Level 2 data cache accesses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 66 */ {"PAPI_L3_DCA", "L3D cache accesses", "Level 3 data cache accesses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L3, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 67 */ {"PAPI_L1_DCR", "L1D cache reads", "Level 1 data cache reads", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L1, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 68 */ {"PAPI_L2_DCR", "L2D cache reads", "Level 2 data cache reads", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 69 */ {"PAPI_L3_DCR", "L3D cache reads", "Level 3 data cache reads", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L3, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 70 */ {"PAPI_L1_DCW", "L1D cache writes", "Level 1 data cache writes", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L1, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 71 */ {"PAPI_L2_DCW", "L2D cache writes", "Level 2 data cache writes", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 72 */ {"PAPI_L3_DCW", "L3D cache writes", "Level 3 data cache writes", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L3, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 73 */ {"PAPI_L1_ICH", "L1I cache hits", "Level 1 instruction cache hits", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L1 + PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 74 */ {"PAPI_L2_ICH", "L2I cache hits", "Level 2 instruction cache hits", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2 + PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 75 */ {"PAPI_L3_ICH", "L3I cache hits", "Level 3 instruction cache hits", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L3 + PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 76 */ {"PAPI_L1_ICA", "L1I cache accesses", "Level 1 instruction cache accesses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L1 + PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 77 */ {"PAPI_L2_ICA", "L2I cache accesses", "Level 2 instruction cache accesses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2 + PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 78 */ {"PAPI_L3_ICA", "L3I cache accesses", "Level 3 instruction cache accesses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L3 + PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 79 */ {"PAPI_L1_ICR", "L1I cache reads", "Level 1 instruction cache reads", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L1 + PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 80 */ {"PAPI_L2_ICR", "L2I cache reads", "Level 2 instruction cache reads", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2 + PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 81 */ {"PAPI_L3_ICR", "L3I cache reads", "Level 3 instruction cache reads", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L3 + PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 82 */ {"PAPI_L1_ICW", "L1I cache writes", "Level 1 instruction cache writes", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L1 + PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 83 */ {"PAPI_L2_ICW", "L2I cache writes", "Level 2 instruction cache writes", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2 + PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 84 */ {"PAPI_L3_ICW", "L3I cache writes", "Level 3 instruction cache writes", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L3 + PAPI_PRESET_BIT_INS, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 85 */ {"PAPI_L1_TCH", "L1 cache hits", "Level 1 total cache hits", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L1, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 86 */ {"PAPI_L2_TCH", "L2 cache hits", "Level 2 total cache hits", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 87 */ {"PAPI_L3_TCH", "L3 cache hits", "Level 3 total cache hits", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L3, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 88 */ {"PAPI_L1_TCA", "L1 cache accesses", "Level 1 total cache accesses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L1, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 89 */ {"PAPI_L2_TCA", "L2 cache accesses", "Level 2 total cache accesses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 90 */ {"PAPI_L3_TCA", "L3 cache accesses", "Level 3 total cache accesses", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L3, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 91 */ {"PAPI_L1_TCR", "L1 cache reads", "Level 1 total cache reads", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L1, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 92 */ {"PAPI_L2_TCR", "L2 cache reads", "Level 2 total cache reads", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 93 */ {"PAPI_L3_TCR", "L3 cache reads", "Level 3 total cache reads", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L3, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 94 */ {"PAPI_L1_TCW", "L1 cache writes", "Level 1 total cache writes", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L1, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 95 */ {"PAPI_L2_TCW", "L2 cache writes", "Level 2 total cache writes", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L2, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 96 */ {"PAPI_L3_TCW", "L3 cache writes", "Level 3 total cache writes", 0, 0, PAPI_PRESET_BIT_CACH + PAPI_PRESET_BIT_L3, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 97 */ {"PAPI_FML_INS", "FPU multiply", "Floating point multiply instructions", 0, 0, PAPI_PRESET_BIT_INS + PAPI_PRESET_BIT_FP, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 98 */ {"PAPI_FAD_INS", "FPU add", "Floating point add instructions", 0, 0, PAPI_PRESET_BIT_INS + PAPI_PRESET_BIT_FP, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 99 */ {"PAPI_FDV_INS", "FPU divide", "Floating point divide instructions", 0, 0, PAPI_PRESET_BIT_INS + PAPI_PRESET_BIT_FP, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /*100 */ {"PAPI_FSQ_INS", "FPU square root", "Floating point square root instructions", 0, 0, PAPI_PRESET_BIT_INS + PAPI_PRESET_BIT_FP, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /*101 */ {"PAPI_FNV_INS", "FPU inverse", "Floating point inverse instructions", 0, 0, PAPI_PRESET_BIT_INS + PAPI_PRESET_BIT_FP, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /*102 */ {"PAPI_FP_OPS", "FP operations", "Floating point operations", 0, 0, PAPI_PRESET_BIT_INS + PAPI_PRESET_BIT_FP, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /*103 */ {"PAPI_SP_OPS", "SP operations", "Floating point operations; optimized to count scaled single precision vector operations", 0, 0, PAPI_PRESET_BIT_INS + PAPI_PRESET_BIT_FP, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /*104 */ {"PAPI_DP_OPS", "DP operations", "Floating point operations; optimized to count scaled double precision vector operations", 0, 0, PAPI_PRESET_BIT_INS + PAPI_PRESET_BIT_FP, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /*105 */ {"PAPI_VEC_SP", "SP Vector/SIMD instr", "Single precision vector/SIMD instructions", 0, 0, PAPI_PRESET_BIT_INS + PAPI_PRESET_BIT_FP, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /*106 */ {"PAPI_VEC_DP", "DP Vector/SIMD instr", "Double precision vector/SIMD instructions", 0, 0, PAPI_PRESET_BIT_INS + PAPI_PRESET_BIT_FP, - NULL, {0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, /* 107 */ {"PAPI_REF_CYC", "Reference cycles", "Reference clock cycles", 0, 0, PAPI_PRESET_BIT_MSC, - NULL, {0},{NULL}, NULL}, -/*108 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*109 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*110 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*111 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*112 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*113 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*114 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*115 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*116 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*117 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*118 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*119 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*120 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*121 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*122 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*123 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*124 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*125 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*126 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, -/*127 */ {NULL, NULL, NULL,0,0,0,NULL,{0},{NULL}, NULL}, + NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*108 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*109 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*110 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*111 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*112 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*113 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*114 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*115 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*116 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*117 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*118 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*119 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*120 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*121 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*122 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*123 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*124 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*125 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*126 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, +/*127 */ {NULL, NULL, NULL, 0, 0, 0, NULL, {0}, {NULL}, {NULL}, {0}, {NULL}, NULL, 0, 0, {NULL}, {NULL}}, }; #if 0 diff --git a/src/papi_internal.c b/src/papi_internal.c index 5e11bde0b..97b0f8452 100644 --- a/src/papi_internal.c +++ b/src/papi_internal.c @@ -50,6 +50,12 @@ static int default_debug_handler( int errorCode ); static long long handle_derived( EventInfo_t * evi, long long *from ); /* Global definitions used by other files */ +int num_all_presets = 0; // total number of presets +int _papi_hwi_start_idx[PAPI_NUM_COMP]; // first index for given component +int pe_idx = -1; // track the perf_event component index +int comp_idx = -1; // track the first non-perf_event component index +int first_comp_preset_idx = 0; // track the first non-perf_event component preset index + int init_level = PAPI_NOT_INITED; int _papi_hwi_error_level = PAPI_QUIET; PAPI_debug_handler_t _papi_hwi_debug_handler = default_debug_handler; @@ -84,7 +90,6 @@ static int num_native_chunks=0; char **_papi_errlist= NULL; static int num_error_chunks = 0; - // pointer to event:mask string associated with last enum call to a components // will be NULL for non libpfm4 components // this is needed because libpfm4 event codes and papi event codes do not contain mask information @@ -525,10 +530,14 @@ _papi_hwi_component_index( int event_code ) { int cidx; int event_index; - /* currently assume presets are for component 0 only */ if (IS_PRESET(event_code)) { INTDBG("EXIT: Event %#x is a PRESET, assigning component %d\n", event_code,0); - return 0; + hwi_presets_t *_preset_ptr = get_preset(event_code); + if( NULL == _preset_ptr ) { + return -1; + } else { + return _preset_ptr->compIdx; + } } /* user defined events are treated like preset events (component 0 only) */ @@ -632,6 +641,52 @@ PAPIWARN( char *format, ... ) } } +/* Return index of first non-perf_event component's preset. */ +int +get_first_cmp_preset_idx( void ) { + + int cmpnt = comp_idx; + if( cmpnt < 0 ) { + return -1; + } + + return first_comp_preset_idx; +} + +/* Return index of component containing preset with given index. */ +int +get_preset_cmp( unsigned int *index ) { + + int i; + unsigned int sum = 0; + for(i = 0; i < PAPI_NUM_COMP; ++i) { + sum += _papi_hwi_max_presets[i]; + if(*index < sum) { + *index = *index - (sum - _papi_hwi_max_presets[i]); + return i; + } + } + + /* If we did not find the component to which the preset belongs. */ + return -1; +} + +/* Return a pointer to preset which has given event code. */ +hwi_presets_t* +get_preset( int event_code ) { + unsigned int preset_index = ( event_code & PAPI_PRESET_AND_MASK ); + hwi_presets_t *_papi_hwi_list; + + int i = get_preset_cmp(&preset_index); + if( i < 0 ) { + return NULL; + } + + _papi_hwi_list = _papi_hwi_comp_presets[i]; + + return &_papi_hwi_list[preset_index]; +} + static int default_debug_handler( int errorCode ) { @@ -1102,11 +1157,16 @@ _papi_hwi_map_events_to_native( EventSetInfo_t *ESI) /* If it's a preset */ if ( IS_PRESET(ESI->EventInfoArray[event].event_code) ) { - preset_index = ( int ) ESI->EventInfoArray[event].event_code & PAPI_PRESET_AND_MASK; + + /* If it is a component preset, it will be in a separate array. */ + hwi_presets_t *_preset_ptr = get_preset((int)ESI->EventInfoArray[event].event_code); + if( NULL == _preset_ptr ) { + return; + } /* walk all sub-events in the preset */ for( k = 0; k < PAPI_EVENTS_IN_DERIVED_EVENT; k++ ) { - nevt = _papi_hwi_presets[preset_index].code[k]; + nevt = _preset_ptr->code[k]; if ( nevt == PAPI_NULL ) { break; } @@ -1380,17 +1440,22 @@ _papi_hwi_add_event( EventSetInfo_t * ESI, int EventCode ) if ( !_papi_hwi_is_sw_multiplex( ESI ) ) { /* Handle preset case */ - if ( IS_PRESET(EventCode) ) { + if ( IS_PRESET(EventCode) ) { /* begin preset case */ int count; int preset_index = EventCode & ( int ) PAPI_PRESET_AND_MASK; /* Check if it's within the valid range */ - if ( ( preset_index < 0 ) || ( preset_index >= PAPI_MAX_PRESET_EVENTS ) ) { + if ( ( preset_index < 0 ) || ( preset_index >= num_all_presets ) ) { return PAPI_EINVAL; } + hwi_presets_t *_preset_ptr = get_preset(EventCode); + if( NULL == _preset_ptr ) { + return PAPI_ENOEVNT; + } + /* count the number of native events in this preset */ - count = ( int ) _papi_hwi_presets[preset_index].count; + count = ( int ) _preset_ptr->count; /* Check if event exists */ if ( !count ) { @@ -1403,7 +1468,7 @@ _papi_hwi_add_event( EventSetInfo_t * ESI, int EventCode ) for( i = 0; i < count; i++ ) { for( j = 0; j < ESI->overflow.event_counter; j++ ) { if ( ESI->overflow.EventCode[j] ==(int) - ( _papi_hwi_presets[preset_index].code[i] ) ) { + ( _preset_ptr->code[i] ) ) { return PAPI_ECNFLCT; } } @@ -1413,7 +1478,7 @@ _papi_hwi_add_event( EventSetInfo_t * ESI, int EventCode ) /* Try to add the preset. */ remap = add_native_events( ESI, - _papi_hwi_presets[preset_index].code, + _preset_ptr->code, count, &ESI->EventInfoArray[thisindex] ); if ( remap < 0 ) { return remap; @@ -1423,14 +1488,15 @@ _papi_hwi_add_event( EventSetInfo_t * ESI, int EventCode ) ESI->EventInfoArray[thisindex].event_code = ( unsigned int ) EventCode; ESI->EventInfoArray[thisindex].derived = - _papi_hwi_presets[preset_index].derived_int; + _preset_ptr->derived_int; ESI->EventInfoArray[thisindex].ops = - _papi_hwi_presets[preset_index].postfix; + _preset_ptr->postfix; ESI->NumberOfEvents++; _papi_hwi_map_events_to_native( ESI ); } } + /* Handle adding Native events */ else if ( IS_NATIVE(EventCode) ) { @@ -1975,6 +2041,49 @@ _papi_hwi_init_global( int PE_OR_PEU ) return PAPI_OK; } + +/* + * Routine that initializes the presets for all components other + * than perf_event. Ignore perf_event component. + */ +int +_papi_hwi_init_global_presets( void ) +{ + int retval = PAPI_OK, is_pe = 0, i = 0; + + while ( _papi_hwd[i] ) { + is_pe = 0; + if (strcmp(_papi_hwd[i]->cmp_info.name, "perf_event") == 0) { + is_pe = 1; + pe_idx = i; + first_comp_preset_idx += _papi_hwi_max_presets[i]; + } else { + /* Only set the first non-perf_event component index once. */ + if ( -1 == comp_idx ) { + comp_idx = i; + } + } + + /* Force initialization of component if needed. */ + if (_papi_hwd[i]->cmp_info.disabled == PAPI_EDELAY_INIT) { + int junk; + _papi_hwd[i]->ntv_enum_events(&junk, PAPI_ENUM_FIRST); + } + + if ( (NULL != _papi_hwd[i]->init_comp_presets) && !is_pe + && ( !_papi_hwd[i]->cmp_info.disabled || + _papi_hwd[i]->cmp_info.disabled == PAPI_EDELAY_INIT ) ) { + retval = _papi_hwd[i]->init_comp_presets(); + } + + _papi_hwi_start_idx[i] = num_all_presets; + num_all_presets += _papi_hwi_max_presets[i]; + i++; + } + return retval; +} + + /* Machine info struct initialization using defaults */ /* See _papi_mdi definition in papi_internal.h */ @@ -2292,45 +2401,48 @@ _papi_hwi_get_preset_event_info( int EventCode, PAPI_event_info_t * info ) { INTDBG("ENTER: EventCode: %#x, info: %p\n", EventCode, info); - int i = EventCode & PAPI_PRESET_AND_MASK; unsigned int j; + hwi_presets_t *_preset_ptr = get_preset(EventCode); + if( NULL == _preset_ptr ) { + return PAPI_ENOEVNT; + } - if ( _papi_hwi_presets[i].symbol ) { /* if the event is in the preset table */ + if ( _preset_ptr->symbol ) { /* if the event is in the preset table */ // since we are setting the whole structure to zero the strncpy calls below will // be leaving NULL terminates strings as long as they copy 1 less byte than the // buffer size of the field. - INTDBG("ENTER: Configuring: %s\n", _papi_hwi_presets[i].symbol); + INTDBG("ENTER: Configuring: %s\n", _preset_ptr->symbol); memset( info, 0, sizeof ( PAPI_event_info_t ) ); /* set up eventcode and name */ info->event_code = ( unsigned int ) EventCode; - strncpy( info->symbol, _papi_hwi_presets[i].symbol, + strncpy( info->symbol, _preset_ptr->symbol, sizeof(info->symbol)-1); /* set up short description, if available */ - if ( _papi_hwi_presets[i].short_descr != NULL ) { - strncpy( info->short_descr, _papi_hwi_presets[i].short_descr, + if ( _preset_ptr->short_descr != NULL ) { + strncpy( info->short_descr, _preset_ptr->short_descr, sizeof ( info->short_descr )-1 ); } /* set up long description, if available */ - if ( _papi_hwi_presets[i].long_descr != NULL ) { - strncpy( info->long_descr, _papi_hwi_presets[i].long_descr, + if ( _preset_ptr->long_descr != NULL ) { + strncpy( info->long_descr, _preset_ptr->long_descr, sizeof ( info->long_descr )-1 ); } - info->event_type = _papi_hwi_presets[i].event_type; - info->count = _papi_hwi_presets[i].count; + info->event_type = _preset_ptr->event_type; + info->count = _preset_ptr->count; /* set up if derived event */ - _papi_hwi_derived_string( _papi_hwi_presets[i].derived_int, + _papi_hwi_derived_string( _preset_ptr->derived_int, info->derived, sizeof ( info->derived )-1 ); - if ( _papi_hwi_presets[i].postfix != NULL ) { - strncpy( info->postfix, _papi_hwi_presets[i].postfix, + if ( _preset_ptr->postfix != NULL ) { + strncpy( info->postfix, _preset_ptr->postfix, sizeof ( info->postfix )-1 ); } @@ -2342,22 +2454,34 @@ _papi_hwi_get_preset_event_info( int EventCode, PAPI_event_info_t * info ) /* ideally that should never happen, but also ideally */ /* we wouldn't segfault if it does */ - if (_papi_hwi_presets[i].name[j]==NULL) { - INTDBG("ERROR in event definition of %s\n", _papi_hwi_presets[i].symbol); + if (_preset_ptr->name[j]==NULL) { + INTDBG("ERROR in event definition of %s\n", _preset_ptr->symbol); return PAPI_ENOEVNT; } else { - info->code[j]=_papi_hwi_presets[i].code[j]; - strncpy(info->name[j], _papi_hwi_presets[i].name[j], + info->code[j]=_preset_ptr->code[j]; + strncpy(info->name[j], _preset_ptr->name[j], sizeof(info->name[j])-1); } } - if ( _papi_hwi_presets[i].note != NULL ) { - strncpy( info->note, _papi_hwi_presets[i].note, + if ( _preset_ptr->note != NULL ) { + strncpy( info->note, _preset_ptr->note, sizeof ( info->note )-1 ); } + /* Copy the qualifiers and their associated descriptions into + * the info struct. */ + int k; + for( k = 0; k < _preset_ptr->num_quals; ++k ) { + strncpy( info->quals[k], _preset_ptr->quals[k], + sizeof ( info->quals[k] )-1 ); + strncpy( info->descrs[k], _preset_ptr->descrs[k], + sizeof ( info->descrs[k] )-1 ); + } + info->num_quals = _preset_ptr->num_quals; + info->compIdx = _preset_ptr->compIdx; + return PAPI_OK; } else { return PAPI_ENOEVNT; diff --git a/src/papi_internal.h b/src/papi_internal.h index 915491995..8fd1db434 100644 --- a/src/papi_internal.h +++ b/src/papi_internal.h @@ -98,6 +98,7 @@ extern char **_papi_errlist; #define DONT_NEED_CONTEXT 0 #define PAPI_EVENTS_IN_DERIVED_EVENT 8 +#define PAPI_MAX_COMP_QUALS 8 /* these vestigial pointers are to structures defined in the components @@ -447,6 +448,7 @@ void _papi_hwi_free_papi_event_string(); void _papi_hwi_set_papi_event_code (unsigned int event_code, int update_flag); unsigned int _papi_hwi_get_papi_event_code (void); int _papi_hwi_get_ntv_idx (unsigned int papi_evt_code); +const char *_papi_hwi_strip_component_prefix(const char *event_name); int _papi_hwi_is_sw_multiplex( EventSetInfo_t * ESI ); hwd_context_t *_papi_hwi_get_context( EventSetInfo_t * ESI, int *is_dirty ); @@ -468,6 +470,7 @@ int _papi_hwi_read( hwd_context_t * context, EventSetInfo_t * ESI, int _papi_hwi_cleanup_eventset( EventSetInfo_t * ESI ); int _papi_hwi_convert_eventset_to_multiplex( _papi_int_multiplex_t * mpx ); int _papi_hwi_init_global( int PE_OR_PEU ); +int _papi_hwi_init_global_presets( void ); int _papi_hwi_init_global_internal( void ); int _papi_hwi_init_os(void); void _papi_hwi_init_errors(void); @@ -522,4 +525,8 @@ int _papi_hwi_enum_dev_type(int enum_modifier, void **handle); int _papi_hwi_get_dev_type_attr(void *handle, PAPI_dev_type_attr_e attr, void *val); int _papi_hwi_get_dev_attr(void *handle, int id, PAPI_dev_attr_e attr, void *val); +int get_first_cmp_preset_idx( void ); +int get_preset_cmp( unsigned int *index ); +hwi_presets_t* get_preset( int event_code ); + #endif /* PAPI_INTERNAL_H */ diff --git a/src/papi_preset.c b/src/papi_preset.c index fd7dd9a20..ec456a850 100644 --- a/src/papi_preset.c +++ b/src/papi_preset.c @@ -9,7 +9,6 @@ * Merge of the libpfm3/libpfm4/pmapi-ppc64_events preset code */ - #include #include #include @@ -25,8 +24,14 @@ // A place to put user defined events extern hwi_presets_t user_defined_events[]; extern int user_defined_events_count; +extern int num_all_presets; +extern int _papi_hwi_start_idx[PAPI_NUM_COMP]; +extern int pe_idx; +extern int comp_idx; +extern int first_comp_preset_idx; static int papi_load_derived_events (char *pmu_str, int pmu_type, int cidx, int preset_flag); +static int papi_load_derived_events_component (char *comp_str, char *arch_str, int cidx); /* This routine copies values from a dense 'findem' array of events @@ -87,6 +92,10 @@ _papi_hwi_setup_all_presets( hwi_search_t * findem, int cidx ) INTDBG( "This preset has %d terms.\n", j ); _papi_hwi_presets[preset_index].count = j; + + // Set the component index to that of the first native event used to define it. + // Make sure we later check that all native events in a preset come from same comp. + _papi_hwi_presets[preset_index].compIdx = _papi_hwi_component_index(findem[pnum].native[0]); _papi_hwi_presets[preset_index].derived_int = findem[pnum].derived; for(k=0;kcmp_info.num_preset_events = 0; - } + int preset_index,cidx; + unsigned int j; + + // TODO: Free _papi_hwi_comp_presets, too. + for(cidx=0;cidxcode[results->count]) != 0 ) { - INTDBG( "EXIT: returned: 0, new event not associated with component 0 (current limitation with derived events)\n"); - return 0; - } - // found = 1; INTDBG("\tFound a native event %s\n", target); - results->name[results->count++] = papi_strdup(target); INTDBG( "EXIT: returned: 1\n"); return 1; @@ -787,6 +796,22 @@ int _papi_load_preset_table(char *pmu_str, int pmu_type, int cidx) { return retval; } +int _papi_load_preset_table_component(char *comp_str, char *arch_str, int cidx) { + SUBDBG("ENTER: arch_str: %s, cidx: %d\n", arch_str, cidx); + + int retval; + + // go load papi preset events for component index 'cidx' + retval = papi_load_derived_events_component(comp_str, arch_str, cidx); + if (retval != PAPI_OK) { + SUBDBG("EXIT: retval: %d\n", retval); + return retval; + } + + SUBDBG("EXIT: retval: %d\n", retval); + return retval; +} + // global variables static char stack[2*PAPI_HUGE_STR_LEN]; // stack static int stacktop = -1; // stack length @@ -966,6 +991,7 @@ papi_load_derived_events (char *pmu_str, int pmu_type, int cidx, int preset_flag int preset = 0; int get_events = 0; /* only process derived events after CPU type they apply to is identified */ int found_events = 0; /* flag to track if event definitions (PRESETS) are found since last CPU declaration */ + int breakAfter = 0; /* flag to break parsing events file if component 'arch' has already been parsed */ #ifdef PAPI_DATADIR char path[PATH_MAX]; #endif @@ -1064,6 +1090,8 @@ papi_load_derived_events (char *pmu_str, int pmu_type, int cidx, int preset_flag if (strcasecmp(t, pmu_name) == 0) { int type; + breakAfter = 1; + SUBDBG( "Process events for PMU %s found at line %d of %s.\n", t, line_no, name); t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); @@ -1078,9 +1106,7 @@ papi_load_derived_events (char *pmu_str, int pmu_type, int cidx, int preset_flag } } continue; - } - - if ((strcasecmp(t, "PRESET") == 0) || (strcasecmp(t, "EVENT") == 0)) { + } else if ((strcasecmp(t, "PRESET") == 0) || (strcasecmp(t, "EVENT") == 0)) { if (get_events == 0) continue; @@ -1106,6 +1132,8 @@ papi_load_derived_events (char *pmu_str, int pmu_type, int cidx, int preset_flag (void) preset; SUBDBG( "Use event code: %#x for %s\n", preset, t); + unsigned int preset_index = ( preset & PAPI_PRESET_AND_MASK ); + _papi_hwi_presets[preset_index].compIdx = cidx; t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); if ((t == NULL) || (strlen(t) == 0)) { @@ -1192,6 +1220,14 @@ papi_load_derived_events (char *pmu_str, int pmu_type, int cidx, int preset_flag break; } + /* If it is a valid event, then update the preset fields here. */ + /* Initially, the event name should be those with a default, mandatory qualifiers. */ + results[res_idx].name[results[res_idx].count] = papi_strdup(t); + results[res_idx].base_name[results[res_idx].count] = papi_strdup(t); + results[res_idx].default_name[results[res_idx].count] = papi_strdup(t); + results[res_idx].default_code[results[res_idx].count] = results[res_idx].code[results[res_idx].count]; + results[res_idx].count++; + i++; } while (results[res_idx].count < PAPI_EVENTS_IN_DERIVED_EVENT); @@ -1275,8 +1311,11 @@ papi_load_derived_events (char *pmu_str, int pmu_type, int cidx, int preset_flag } while (t != NULL); } (*event_count)++; + continue; - } + } else { + if( breakAfter ) break; // Break this while-loop once all presets for the given component's arch have been parsed. + } PAPIERROR("Unrecognized token %s at line %d of %s -- ignoring", t, line_no, name); } @@ -1290,6 +1329,452 @@ papi_load_derived_events (char *pmu_str, int pmu_type, int cidx, int preset_flag } +static int +papi_load_derived_events_component (char *comp_str, char *arch_str, int cidx) { + SUBDBG( "ENTER: arch_str: %s, cidx: %d\n", arch_str, cidx); + + char arch_name[PAPI_MIN_STR_LEN]; + char line[LINE_MAX]; + char name[PATH_MAX] = "builtin papi_events_table"; + char *event_file_path=NULL; + char *event_table_ptr=NULL; + int event_type_bits = 0; + char *tmpn; + char *tok_save_ptr=NULL; + FILE *event_file = NULL; + hwi_presets_t *results=NULL; + int result_size = 0; + int *event_count = NULL; + int invalid_event; + int line_no = 0; /* count of lines read from event definition input */ + int derived = 0; + int res_idx = 0; /* index into results array for where to store next event */ + int preset = 0; + int get_events = 0; /* only process derived events after CPU type they apply to is identified */ + int found_events = 0; /* flag to track if event definitions (PRESETS) are found since last CPU declaration */ + int breakAfter = 0; /* flag to break parsing events file if component 'arch' has already been parsed */ + int status = 0; +#ifdef PAPI_DATADIR + char path[PATH_MAX]; +#endif + + + /* try the environment variable first */ + if ((tmpn = getenv("PAPI_CSV_EVENT_FILE")) && (strlen(tmpn) > 0)) { + event_file_path = tmpn; + } + /* if no valid environment variable, look for built-in table */ + else if (papi_events_table) { + event_table_ptr = papi_events_table; + } + /* if no env var and no built-in, search for default file */ + else { +#ifdef PAPI_DATADIR + sprintf( path, "%s/%s", PAPI_DATADIR, PAPI_EVENT_FILE ); + event_file_path = path; +#else + event_file_path = PAPI_EVENT_FILE; +#endif + } + event_type_bits = PAPI_PRESET_MASK; + results = &_papi_hwi_comp_presets[cidx][0]; + result_size = _papi_hwi_max_presets[cidx]; + event_count = &_papi_hwd[cidx]->cmp_info.num_preset_events; + + // if we have an event file pathname, open it and read event definitions from the file + if (event_file_path != NULL) { + if ((event_file = open_event_table(event_file_path)) == NULL) { + // if file open fails, return an error + SUBDBG("EXIT: Event file open failed.\n"); + return PAPI_ESYS; + } + strncpy(name, event_file_path, sizeof(name)-1); + name[sizeof(name)-1] = '\0'; + } else if (event_table_ptr == NULL) { + // if we do not have a path name or table pointer, return an error + SUBDBG("EXIT: Both event_file_path and event_table_ptr are NULL.\n"); + return PAPI_ESYS; + } + + /* copy the arch identifier, stripping commas if found */ + tmpn = arch_name; + while (*arch_str) { + if (*arch_str != ',') + *tmpn++ = *arch_str; + arch_str++; + } + *tmpn = '\0'; + + /* at this point we have either a valid file pointer or built-in table pointer */ + while (get_event_line(line, event_file, &event_table_ptr)) { + char *t; + int i; + + // increment number of lines we have read + line_no++; + + t = trim_string(strtok_r(line, ",", &tok_save_ptr)); + + /* Skip blank lines */ + if ((t == NULL) || (strlen(t) == 0)) + continue; + + /* Skip comments */ + if (t[0] == '#') { + continue; + } + + if (strcasecmp(t, comp_str) == 0) { + if (get_events != 0 && found_events != 0) { + SUBDBG( "Ending event scanning at line %d of %s.\n", line_no, name); + get_events = 0; + found_events = 0; + } + + t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); + if ((t == NULL) || (strlen(t) == 0)) { + PAPIERROR("Expected name after component-name token at line %d of %s -- ignoring", line_no, name); + continue; + } + + if (strcasecmp(t, arch_name) == 0) { + int type; + + breakAfter = 1; + + SUBDBG( "Process events for ARCH %s found at line %d of %s.\n", t, line_no, name); + + t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); + if ((t == NULL) || (strlen(t) == 0)) { + SUBDBG("No additional qualifier found, matching on string.\n"); + get_events = 1; + } + } + continue; + } else if ((strcasecmp(t, "PRESET") == 0) || (strcasecmp(t, "EVENT") == 0)) { + + if (get_events == 0) + continue; + + found_events = 1; + t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); + + if ((t == NULL) || (strlen(t) == 0)) { + PAPIERROR("Expected name after PRESET token at line %d of %s -- ignoring", line_no, name); + continue; + } + + SUBDBG( "Examining event %s\n", t); + + // see if this event already exists in the results array, if not already known it sets up event in unused entry + if ((res_idx = find_event_index (results, result_size, t)) < 0) { + PAPIERROR("No room left for event %s -- ignoring", t); + continue; + } + + + // add the proper event bits (preset or user defined bits) + preset = res_idx | event_type_bits; + (void) preset; + + SUBDBG( "Use event code: %#x for %s\n", preset, t); + unsigned int preset_index = ( preset & PAPI_PRESET_AND_MASK ); + _papi_hwi_comp_presets[cidx][preset_index].compIdx = cidx; + + t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); + if ((t == NULL) || (strlen(t) == 0)) { + // got an error, make this entry unused + if (results[res_idx].symbol != NULL){ + papi_free (results[res_idx].symbol); + results[res_idx].symbol = NULL; + } + PAPIERROR("Expected derived type after PRESET token at line %d of %s -- ignoring", line_no, name); + continue; + } + + if (_papi_hwi_derived_type(t, &derived) != PAPI_OK) { + // got an error, make this entry unused + if (results[res_idx].symbol != NULL){ + papi_free (results[res_idx].symbol); + results[res_idx].symbol = NULL; + } + PAPIERROR("Invalid derived name %s after PRESET token at line %d of %s -- ignoring", t, line_no, name); + continue; + } + + /****************************************/ + /* Have an event, let's start assigning */ + /****************************************/ + + SUBDBG( "Adding event: %s, code: %#x, derived: %d results[%d]: %p.\n", t, preset, derived, res_idx, &results[res_idx]); + + /* results[res_idx].event_code = preset; */ + results[res_idx].derived_int = derived; + + /* Derived support starts here */ + /* Special handling for postfix and infix */ + if ((derived == DERIVED_POSTFIX) || (derived == DERIVED_INFIX)) { + t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); + if ((t == NULL) || (strlen(t) == 0)) { + // got an error, make this entry unused + if (results[res_idx].symbol != NULL){ + papi_free (results[res_idx].symbol); + results[res_idx].symbol = NULL; + } + PAPIERROR("Expected Operation string after derived type DERIVED_POSTFIX or DERIVED_INFIX at line %d of %s -- ignoring", line_no, name); + continue; + } + + // if it is an algebraic formula, we need to convert it to postfix + if (derived == DERIVED_INFIX) { + SUBDBG( "Converting InFix operations %s\n", t); + t = infix_to_postfix( t ); + results[res_idx].derived_int = DERIVED_POSTFIX; + } + + SUBDBG( "Saving PostFix operations %s\n", t); + results[res_idx].postfix = papi_strdup(t); + } + + /* All derived terms collected here */ + i = 0; + invalid_event = 0; + results[res_idx].count = 0; + int firstTerm = 1; + do { + t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); + if ((t == NULL) || (strlen(t) == 0)) + break; + if (strcasecmp(t, "NOTE") == 0) + break; + if (strcasecmp(t, "LDESC") == 0) + break; + if (strcasecmp(t, "SDESC") == 0) + break; + + SUBDBG( "Adding term (%d) %s to derived event %#x, current native event count: %d.\n", i, t, preset, results[res_idx].count); + + // show that we do not have an event code yet (the component may create one and update this info) + // this also clears any values left over from a previous call + _papi_hwi_set_papi_event_code(-1, -1); + + unsigned int eventCode; + char *tmpEvent; + PAPI_event_info_t eventInfo; + hwi_presets_t *prstPtr = &(_papi_hwi_comp_presets[cidx][preset_index]); + + if( firstTerm ) { + + // Convert native event to code and check that it's valid. + status = _papi_hwi_native_name_to_code(t, &eventCode); + if( status != PAPI_OK ) { + invalid_event = 1; + PAPIERROR("Failed to get code for native event %s, used in derived event %s", t, results[res_idx].symbol); + break; + } + + do { + // Call get_event_info, and use the qualifier string that comes after the + // single instance of ":" and the description that comes after "masks:" + status = _papi_hwi_get_native_event_info( (unsigned int)eventCode, &eventInfo ); + if ( status != PAPI_OK ) { + invalid_event = 1; + PAPIERROR("Failed to get info for native event %s, used in derived event %s", t, results[res_idx].symbol); + break; + } + + const char *wholeNameConst = _papi_hwi_strip_component_prefix(eventInfo.symbol); + char *wholeName = strdup(wholeNameConst); + char *qualDelim = ":"; + char *qualPtr = strstr( wholeName, qualDelim ); + if( NULL != qualPtr ) { + + prstPtr->num_quals++; + + /* Store the qualifier in the preset struct. */ + prstPtr->quals[prstPtr->num_quals-1] = (char*)malloc((1+strlen(qualPtr))*sizeof(char)); + if( NULL != prstPtr->quals[prstPtr->num_quals-1] ) { + status = sprintf(prstPtr->quals[prstPtr->num_quals-1], "%s", qualPtr); + if( strlen(qualPtr) != status ) { + invalid_event = 1; + PAPIERROR("Failed to store qualifier for native event %s,", + " used in derived event %s", + t, results[res_idx].symbol); + break; + } + } + } else { + /* If there is no qualifier detected, then even if 'masks:' exists in the event + * description, we don't want to track a 'qualifier description' because there + * is no associated qualifier. */ + continue; + } + + qualPtr = strstr( eventInfo.long_descr, "masks:" ); + if( NULL != qualPtr ) { + + qualPtr = strstr( qualPtr, ":" ); + if( NULL != qualPtr && NULL != ++qualPtr) { + + /* Store the qualifier's description in the preset struct. */ + prstPtr->descrs[prstPtr->num_quals-1] = (char*)malloc((1+strlen(qualPtr))*sizeof(char)); + if( NULL != prstPtr->descrs[prstPtr->num_quals-1] ) { + status = sprintf(prstPtr->descrs[prstPtr->num_quals-1], "%s", qualPtr); + if( strlen(qualPtr) != status ) { + invalid_event = 1; + PAPIERROR("Failed to store qualifier description for native event %s,", + " used in derived event %s", + t, results[res_idx].symbol); + break; + } + } + } + } + + free(wholeName); + + } while( PAPI_OK == PAPI_enum_event( &eventCode, PAPI_NTV_ENUM_UMASKS) ); + + firstTerm = 0; + } + + /* Construct event with all qualifiers. */ + int k, strLenSum = strlen(t)+1; + for (k = 0; k < prstPtr->num_quals; k++){ + strLenSum += strlen(prstPtr->quals[k]); + } + + tmpEvent = (char*)malloc(strLenSum*sizeof(char)); + if( NULL != tmpEvent ) { + + /* Print the basename to the string. */ + status = sprintf(tmpEvent, "%s", t); + if( status != strlen(t) ) { + invalid_event = 1; + PAPIERROR("Event basename %s was truncated to %s in dervied event %s", + t, tmpEvent, results[res_idx].symbol); + break; + } + + /* Print the qualifiers to the string. */ + status = 0; + for (k = 0; k < prstPtr->num_quals; k++){ + status += sprintf(tmpEvent, "%s%s", t, prstPtr->quals[k]); + } + + if( status != strLenSum - 1 ) { + invalid_event = 1; + PAPIERROR("Event %s with qualifiers was truncated to %s in dervied event %s", + t, tmpEvent, results[res_idx].symbol); + break; + } + } + + // make sure that this term in the derived event is a valid event name + // this call replaces preset and user event names with the equivalent native events in our results table + // it also updates formulas for derived events so that they refer to the correct native event index + if (is_event(tmpEvent, results[res_idx].derived_int, &results[res_idx], i) == 0) { + invalid_event = 1; + PAPIERROR("Missing event %s, used in derived event %s", t, results[res_idx].symbol); + break; + } + + /* If it is a valid event, then update the preset fields here. */ + /* Initially, the event name should be those with a default, mandatory qualifiers. */ + results[res_idx].name[results[res_idx].count] = papi_strdup(tmpEvent); + results[res_idx].base_name[results[res_idx].count] = papi_strdup(t); + results[res_idx].default_name[results[res_idx].count] = papi_strdup(tmpEvent); + results[res_idx].default_code[results[res_idx].count] = results[res_idx].code[results[res_idx].count]; + results[res_idx].count++; + + free(tmpEvent); + + i++; + } while (results[res_idx].count < PAPI_EVENTS_IN_DERIVED_EVENT); + + /* preset code list must be PAPI_NULL terminated */ + if (i < PAPI_EVENTS_IN_DERIVED_EVENT) { + results[res_idx].code[results[res_idx].count] = PAPI_NULL; + } + + if (invalid_event) { + // got an error, make this entry unused + // preset table is statically allocated, user defined is dynamic + unsigned int j; + for (j = 0; j < results[res_idx].count; j++){ + if (results[res_idx].name[j] != NULL){ + papi_free( results[res_idx].name[j] ); + results[res_idx].name[j] = NULL; + } + } + + continue; + } + + /* End of derived support */ + + // if we did not find any terms to base this derived event on, report error + if (i == 0) { + // got an error, make this entry unused + PAPIERROR("Expected PFM event after DERIVED token at line %d of %s -- ignoring", line_no, name); + continue; + } + + if (i == PAPI_EVENTS_IN_DERIVED_EVENT) { + t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); + } + + // if something was provided following the list of events to be used by the operation, process it + if ( t!= NULL && strlen(t) > 0 ) { + do { + // save the field name + char *fptr = papi_strdup(t); + + // get the value to be used with this field + t = trim_note(strtok_r(NULL, ",", &tok_save_ptr)); + if ( t== NULL || strlen(t) == 0 ) { + papi_free(fptr); + break; + } + + // Handle optional short descriptions, long descriptions and notes + if (strcasecmp(fptr, "SDESC") == 0) { + results[res_idx].short_descr = papi_strdup(t); + } + if (strcasecmp(fptr, "LDESC") == 0) { + results[res_idx].long_descr = papi_strdup(t); + } + if (strcasecmp(fptr, "NOTE") == 0) { + results[res_idx].note = papi_strdup(t); + } + + SUBDBG( "Found %s (%s) on line %d\n", fptr, t, line_no); + papi_free (fptr); + + // look for another field name + t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); + if ( t== NULL || strlen(t) == 0 ) { + break; + } + } while (t != NULL); + } + (*event_count)++; + + continue; + } else { + if( breakAfter ) break; // Break this while-loop once all presets for the given component's 'arch' have been parsed. + } + + PAPIERROR("Unrecognized token %s at line %d of %s -- ignoring", t, line_no, name); + } + + if (event_file) { + fclose(event_file); + } + + SUBDBG("EXIT: Done processing derived event file.\n"); + return PAPI_OK; +} /* The following code is proof of principle for reading preset events from an diff --git a/src/papi_preset.h b/src/papi_preset.h index bc4d411a5..cc8d86d93 100644 --- a/src/papi_preset.h +++ b/src/papi_preset.h @@ -29,9 +29,16 @@ typedef struct hwi_presets { unsigned int count; unsigned int event_type; char *postfix; - unsigned int code[PAPI_MAX_INFO_TERMS]; - char *name[PAPI_MAX_INFO_TERMS]; + unsigned int code[PAPI_MAX_INFO_TERMS]; // Active code for each native event. + char *name[PAPI_MAX_INFO_TERMS]; // Active name for each native event. + char *base_name[PAPI_MAX_INFO_TERMS]; // Unqualified native event name. + unsigned int default_code[PAPI_MAX_INFO_TERMS]; // Codes for names with mandatory quals included. + char *default_name[PAPI_MAX_INFO_TERMS]; // Name of native events with mandatory quals included. char *note; + int compIdx; + int num_quals; + char *quals[PAPI_MAX_COMP_QUALS]; + char *descrs[PAPI_MAX_COMP_QUALS]; } hwi_presets_t; @@ -49,7 +56,10 @@ int _papi_hwi_setup_all_presets( hwi_search_t * findem, int cidx); int _papi_hwi_cleanup_all_presets( void ); int _xml_papi_hwi_setup_all_presets( char *arch); int _papi_load_preset_table( char *name, int type, int cidx ); +int _papi_load_preset_table_component( char *comp_str, char *name, int cidx ); extern hwi_presets_t _papi_hwi_presets[PAPI_MAX_PRESET_EVENTS]; +extern hwi_presets_t *_papi_hwi_comp_presets[]; +extern int _papi_hwi_max_presets[]; #endif /* _PAPI_PRESET */ From b4ecf1ef081963692e3d6671ea46ddd99796cd6e Mon Sep 17 00:00:00 2001 From: Daniel Barry Date: Thu, 31 Oct 2024 13:15:07 -0700 Subject: [PATCH 6/8] utils: convert tabs to spaces in papi_avail.c This is an aesthetic change to improve the development process. These changes have been tested on the NVIDIA Grace-Hopper architecture. --- src/utils/papi_avail.c | 814 ++++++++++++++++++++--------------------- 1 file changed, 407 insertions(+), 407 deletions(-) diff --git a/src/utils/papi_avail.c b/src/utils/papi_avail.c index fada75d6e..3f284bbca 100644 --- a/src/utils/papi_avail.c +++ b/src/utils/papi_avail.c @@ -1,29 +1,29 @@ // Define the papi_avail man page contents. /** * file papi_avail.c - * @brief papi_avail utility. + * @brief papi_avail utility. * @page papi_avail - * @section Name - * papi_avail - provides availability and detailed information for PAPI preset and user defined events. + * @section Name + * papi_avail - provides availability and detailed information for PAPI preset and user defined events. * - * @section Synopsis - * papi_avail [-adht] [-e event] + * @section Synopsis + * papi_avail [-adht] [-e event] * - * @section Description - * papi_avail is a PAPI utility program that reports information about the - * current PAPI installation and supported preset and user defined events. + * @section Description + * papi_avail is a PAPI utility program that reports information about the + * current PAPI installation and supported preset and user defined events. * - * @section Options + * @section Options *
    - *
  • -h Display help information about this utility. - *
  • -a Display only the available PAPI events. + *
  • -h Display help information about this utility. + *
  • -a Display only the available PAPI events. *
  • -c Display only the available PAPI events after a check. - *
  • -d Display PAPI event information in a more detailed format. - *
  • -e < event > Display detailed event information for the named event. - * This event can be a preset event, a user defined event, or a native event. - * If the event is a preset or a user defined event the output shows a list of native - * events the event is based on and the formula that is used to compute the events final value.\n - *
+ *
  • -d Display PAPI event information in a more detailed format. + *
  • -e < event > Display detailed event information for the named event. + * This event can be a preset event, a user defined event, or a native event. + * If the event is a preset or a user defined event the output shows a list of native + * events the event is based on and the formula that is used to compute the events final value.\n + * * * Event filtering options *
      @@ -40,139 +40,139 @@ *
    • --msc Display miscellaneous PAPI preset events *
    • --tlb Display Translation Lookaside Buffer PAPI preset events *
    - * @section Bugs - * There are no known bugs in this utility. - * If you find a bug, it should be reported to the PAPI Mailing List at . + * @section Bugs + * There are no known bugs in this utility. + * If you find a bug, it should be reported to the PAPI Mailing List at . *
    - * @see PAPI_derived_event_files + * @see PAPI_derived_event_files * */ // Define the PAPI_derived_event_files man page contents. /** - * @page PAPI_derived_event_files - * @brief Describes derived event definition file syntax. + * @page PAPI_derived_event_files + * @brief Describes derived event definition file syntax. * - * @section main Derived Events - * PAPI provides the ability to define events whose value will be derived from multiple native events. The list of native - * events to be used in a derived event and a formula which describes how to use them is provided in an event definition file. - * The PAPI team provides an event definition file which describes all of the supported PAPI preset events. PAPI also allows - * a user to provide an event definition file that describes a set of user defined events which can extend the events PAPI - * normally supports. + * @section main Derived Events + * PAPI provides the ability to define events whose value will be derived from multiple native events. The list of native + * events to be used in a derived event and a formula which describes how to use them is provided in an event definition file. + * The PAPI team provides an event definition file which describes all of the supported PAPI preset events. PAPI also allows + * a user to provide an event definition file that describes a set of user defined events which can extend the events PAPI + * normally supports. * - * This page documents the syntax of the commands which can appear in an event definition file. + * This page documents the syntax of the commands which can appear in an event definition file. * *
    - * @subsection rules General Rules: - *
      - *
    • Blank lines are ignored.
    • - *
    • Lines that begin with '#' are comments (they are also ignored).
    • - *
    • Names shown inside < > below represent values that must be provided by the user.
    • - *
    • If a user provided value contains white space, it must be protected with quotes.
    • - *
    + * @subsection rules General Rules: + *
      + *
    • Blank lines are ignored.
    • + *
    • Lines that begin with '#' are comments (they are also ignored).
    • + *
    • Names shown inside < > below represent values that must be provided by the user.
    • + *
    • If a user provided value contains white space, it must be protected with quotes.
    • + *
    * *
    - * @subsection commands Commands: - * @par CPU,\ - * Specifies a PMU name which controls if the PRESET and EVENT commands that follow this line should - * be processed. Multiple CPU commands can be entered without PRESET or EVENT commands between them to provide - * a list of PMU names to which the derived events that follow will apply. When a PMU name provided in the list - * matches a PMU name known to the running system, the events which follow will be created. If none of the PMU - * names provided in the list match a PMU name on the running system, the events which follow will be ignored. - * When a new CPU command follows either a PRESET or EVENT command, the PMU list is rebuilt.

    + * @subsection commands Commands: + * @par CPU,\ + * Specifies a PMU name which controls if the PRESET and EVENT commands that follow this line should + * be processed. Multiple CPU commands can be entered without PRESET or EVENT commands between them to provide + * a list of PMU names to which the derived events that follow will apply. When a PMU name provided in the list + * matches a PMU name known to the running system, the events which follow will be created. If none of the PMU + * names provided in the list match a PMU name on the running system, the events which follow will be ignored. + * When a new CPU command follows either a PRESET or EVENT command, the PMU list is rebuilt.

    * - * @par PRESET,\,\,\,LDESC,\"\\",SDESC,\"\\",NOTE,\"\\" - * Declare a PAPI preset derived event.

    + * @par PRESET,\,\,\,LDESC,\"\\",SDESC,\"\\",NOTE,\"\\" + * Declare a PAPI preset derived event.

    * - * @par EVENT,\,\,\,LDESC,\"\\",SDESC,\"\\",NOTE,\"\\" - * Declare a user defined derived event.

    + * @par EVENT,\,\,\,LDESC,\"\\",SDESC,\"\\",NOTE,\"\\" + * Declare a user defined derived event.

    * - * @par Where: - * @par pmuName: - * The PMU which the following events should apply to. A list of PMU names supported by your - * system can be obtained by running papi_component_avail on your system.
    - * @par eventName: - * Specifies the name used to identify this derived event. This name should be unique within the events on your system.
    - * @par derivedType: - * Specifies the kind of derived event being defined (see 'Derived Types' below).
    - * @par eventAttr: - * Specifies a formula and a list of base events that are used to compute the derived events value. The syntax - * of this field depends on the 'derivedType' specified above (see 'Derived Types' below).
    - * @par longDesc: - * Provides the long description of the event.
    - * @par shortDesc: - * Provides the short description of the event.
    - * @par note: - * Provides an event note.
    - * @par baseEvent (used below): - * Identifies an event on which this derived event is based. This may be a native event (possibly with event masks), - * an already known preset event, or an already known user event.
    + * @par Where: + * @par pmuName: + * The PMU which the following events should apply to. A list of PMU names supported by your + * system can be obtained by running papi_component_avail on your system.
    + * @par eventName: + * Specifies the name used to identify this derived event. This name should be unique within the events on your system.
    + * @par derivedType: + * Specifies the kind of derived event being defined (see 'Derived Types' below).
    + * @par eventAttr: + * Specifies a formula and a list of base events that are used to compute the derived events value. The syntax + * of this field depends on the 'derivedType' specified above (see 'Derived Types' below).
    + * @par longDesc: + * Provides the long description of the event.
    + * @par shortDesc: + * Provides the short description of the event.
    + * @par note: + * Provides an event note.
    + * @par baseEvent (used below): + * Identifies an event on which this derived event is based. This may be a native event (possibly with event masks), + * an already known preset event, or an already known user event.
    * *
    - * @subsection notes Notes: - * The PRESET command has traditionally been used in the PAPI provided preset definition file. - * The EVENT command is intended to be used in user defined event definition files. The code treats them - * the same so they are interchangeable and they can both be used in either event definition file.
    + * @subsection notes Notes: + * The PRESET command has traditionally been used in the PAPI provided preset definition file. + * The EVENT command is intended to be used in user defined event definition files. The code treats them + * the same so they are interchangeable and they can both be used in either event definition file.
    * *
    - * @subsection types Derived Types: - * This describes values allowed in the 'derivedType' field of the PRESET and EVENT commands. It also - * shows the syntax of the 'eventAttr' field for each derived type supported by these commands. - * All of the derived events provide a list of one or more events which the derived event is based - * on (baseEvent). Some derived events provide a formula that specifies how to compute the derived - * events value using the baseEvents in the list. The following derived types are supported, the syntax - * of the 'eventAttr' parameter for each derived event type is shown in parentheses.

    + * @subsection types Derived Types: + * This describes values allowed in the 'derivedType' field of the PRESET and EVENT commands. It also + * shows the syntax of the 'eventAttr' field for each derived type supported by these commands. + * All of the derived events provide a list of one or more events which the derived event is based + * on (baseEvent). Some derived events provide a formula that specifies how to compute the derived + * events value using the baseEvents in the list. The following derived types are supported, the syntax + * of the 'eventAttr' parameter for each derived event type is shown in parentheses.

    * - * @par NOT_DERIVED (\): - * This derived type defines an alias for the existing event 'baseEvent'.
    - * @par DERIVED_ADD (\,\): - * This derived type defines a new event that will be the sum of two other - * events. It has a value of 'baseEvent1' plus 'baseEvent2'.
    - * @par DERIVED_PS (PAPI_TOT_CYC,\): - * This derived type defines a new event that will report the number of 'baseEvent1' events which occurred - * per second. It has a value of ((('baseEvent1' * cpu_max_mhz) * 1000000 ) / PAPI_TOT_CYC). The user must - * provide PAPI_TOT_CYC as the first event of two events in the event list for this to work correctly.
    - * @par DERIVED_ADD_PS (PAPI_TOT_CYC,\,\): - * This derived type defines a new event that will add together two event counters and then report the number - * which occurred per second. It has a value of (((('baseEvent1' + baseEvent2) * cpu_max_mhz) * 1000000 ) / PAPI_TOT_CYC). - * The user must provide PAPI_TOT_CYC as the first event of three events in the event list for this to work correctly.
    - * @par DERIVED_CMPD (\,\ - * @par DERIVED_SUB (\,\): - * This derived type defines a new event that will be the difference between two other - * events. It has a value of 'baseEvent1' minus 'baseEvent2'.
    - * @par DERIVED_POSTFIX (\,\,\, ... ,\): - * This derived type defines a new event whose value is computed from several native events using - * a postfix (reverse polish notation) formula. Its value is the result of processing the postfix - * formula. The 'pfFormula' is of the form 'N0|N1|N2|5|*|+|-|' where the '|' acts as a token - * separator and the tokens N0, N1, and N2 are place holders that represent baseEvent0, baseEvent1, - * and baseEvent2 respectively.
    - * @par DERIVED_INFIX (\,\,\, ... ,\): - * This derived type defines a new event whose value is computed from several native events using - * an infix (algebraic notation) formula. Its value is the result of processing the infix - * formula. The 'ifFormula' is of the form 'N0-(N1+(N2*5))' where the tokens N0, N1, and N2 - * are place holders that represent baseEvent0, baseEvent1, and baseEvent2 respectively.
    + * @par NOT_DERIVED (\): + * This derived type defines an alias for the existing event 'baseEvent'.
    + * @par DERIVED_ADD (\,\): + * This derived type defines a new event that will be the sum of two other + * events. It has a value of 'baseEvent1' plus 'baseEvent2'.
    + * @par DERIVED_PS (PAPI_TOT_CYC,\): + * This derived type defines a new event that will report the number of 'baseEvent1' events which occurred + * per second. It has a value of ((('baseEvent1' * cpu_max_mhz) * 1000000 ) / PAPI_TOT_CYC). The user must + * provide PAPI_TOT_CYC as the first event of two events in the event list for this to work correctly.
    + * @par DERIVED_ADD_PS (PAPI_TOT_CYC,\,\): + * This derived type defines a new event that will add together two event counters and then report the number + * which occurred per second. It has a value of (((('baseEvent1' + baseEvent2) * cpu_max_mhz) * 1000000 ) / PAPI_TOT_CYC). + * The user must provide PAPI_TOT_CYC as the first event of three events in the event list for this to work correctly.
    + * @par DERIVED_CMPD (\,\ + * @par DERIVED_SUB (\,\): + * This derived type defines a new event that will be the difference between two other + * events. It has a value of 'baseEvent1' minus 'baseEvent2'.
    + * @par DERIVED_POSTFIX (\,\,\, ... ,\): + * This derived type defines a new event whose value is computed from several native events using + * a postfix (reverse polish notation) formula. Its value is the result of processing the postfix + * formula. The 'pfFormula' is of the form 'N0|N1|N2|5|*|+|-|' where the '|' acts as a token + * separator and the tokens N0, N1, and N2 are place holders that represent baseEvent0, baseEvent1, + * and baseEvent2 respectively.
    + * @par DERIVED_INFIX (\,\,\, ... ,\): + * This derived type defines a new event whose value is computed from several native events using + * an infix (algebraic notation) formula. Its value is the result of processing the infix + * formula. The 'ifFormula' is of the form 'N0-(N1+(N2*5))' where the tokens N0, N1, and N2 + * are place holders that represent baseEvent0, baseEvent1, and baseEvent2 respectively.
    * *
    - * @subsection example Example: - * In the following example, the events PAPI_SP_OPS, USER_SP_OPS, and ALIAS_SP_OPS will all measure the same events and return - * the same value. They just demonstrate different ways to use the PRESET and EVENT event definition commands.

    + * @subsection example Example: + * In the following example, the events PAPI_SP_OPS, USER_SP_OPS, and ALIAS_SP_OPS will all measure the same events and return + * the same value. They just demonstrate different ways to use the PRESET and EVENT event definition commands.

    * - *
      - *
    • # The following lines define pmu names that all share the following events
    • - *
    • CPU nhm
    • - *
    • CPU nhm-ex
    • - *
    • \# Events which should be defined for either of the above pmu types
    • - *
    • PRESET,PAPI_TOT_CYC,NOT_DERIVED,UNHALTED_CORE_CYCLES
    • - *
    • PRESET,PAPI_REF_CYC,NOT_DERIVED,UNHALTED_REFERENCE_CYCLES
    • - *
    • PRESET,PAPI_SP_OPS,DERIVED_POSTFIX,N0|N1|3|*|+|,FP_COMP_OPS_EXE:SSE_SINGLE_PRECISION,FP_COMP_OPS_EXE:SSE_FP_PACKED,NOTE,"Using a postfix formula"
    • - *
    • EVENT,USER_SP_OPS,DERIVED_INFIX,N0+(N1*3),FP_COMP_OPS_EXE:SSE_SINGLE_PRECISION,FP_COMP_OPS_EXE:SSE_FP_PACKED,NOTE,"Using the same formula in infix format"
    • - *
    • EVENT,ALIAS_SP_OPS,NOT_DERIVED,PAPI_SP_OPS,LDESC,"Alias for preset event PAPI_SP_OPS"
    • - *
    • # End of event definitions for above pmu names and start of a section for a new pmu name.
    • - *
    • CPU snb
    • - *
    + *
      + *
    • # The following lines define pmu names that all share the following events
    • + *
    • CPU nhm
    • + *
    • CPU nhm-ex
    • + *
    • \# Events which should be defined for either of the above pmu types
    • + *
    • PRESET,PAPI_TOT_CYC,NOT_DERIVED,UNHALTED_CORE_CYCLES
    • + *
    • PRESET,PAPI_REF_CYC,NOT_DERIVED,UNHALTED_REFERENCE_CYCLES
    • + *
    • PRESET,PAPI_SP_OPS,DERIVED_POSTFIX,N0|N1|3|*|+|,FP_COMP_OPS_EXE:SSE_SINGLE_PRECISION,FP_COMP_OPS_EXE:SSE_FP_PACKED,NOTE,"Using a postfix formula"
    • + *
    • EVENT,USER_SP_OPS,DERIVED_INFIX,N0+(N1*3),FP_COMP_OPS_EXE:SSE_SINGLE_PRECISION,FP_COMP_OPS_EXE:SSE_FP_PACKED,NOTE,"Using the same formula in infix format"
    • + *
    • EVENT,ALIAS_SP_OPS,NOT_DERIVED,PAPI_SP_OPS,LDESC,"Alias for preset event PAPI_SP_OPS"
    • + *
    • # End of event definitions for above pmu names and start of a section for a new pmu name.
    • + *
    • CPU snb
    • + *
    * */ @@ -187,14 +187,14 @@ static char * is_derived( PAPI_event_info_t * info ) { - if ( strlen( info->derived ) == 0 ) - return ( "No" ); - else if ( strcmp( info->derived, "NOT_DERIVED" ) == 0 ) - return ( "No" ); - else if ( strcmp( info->derived, "DERIVED_CMPD" ) == 0 ) - return ( "No" ); - else - return ( "Yes" ); + if ( strlen( info->derived ) == 0 ) + return ( "No" ); + else if ( strcmp( info->derived, "NOT_DERIVED" ) == 0 ) + return ( "No" ); + else if ( strcmp( info->derived, "DERIVED_CMPD" ) == 0 ) + return ( "No" ); + else + return ( "Yes" ); } static void @@ -202,62 +202,62 @@ print_help( char **argv ) { printf( "This is the PAPI avail program.\n" ); printf( "It provides availability and details about PAPI Presets and User-defined Events.\n" ); - printf( "PAPI Preset Event filters can be combined in a logical OR.\n" ); - printf( "Usage: %s [options]\n", argv[0] ); - printf( "Options:\n\n" ); - printf( "General command options:\n" ); - printf( "\t-h, --help Print this help message\n" ); - printf( "\t-a, --avail Display only available PAPI preset and user defined events\n" ); - printf( "\t-c, --check Display only available PAPI preset and user defined events after an availability check\n" ); - printf( "\t-d, --detail Display detailed information about events\n" ); - printf( "\t-e EVENTNAME Display detail information about specified event\n" ); - printf( "\nEvent filtering options:\n" ); - printf( "\t--br Display branch related PAPI preset events\n" ); - printf( "\t--cache Display cache related PAPI preset events\n" ); - printf( "\t--cnd Display conditional PAPI preset events\n" ); - printf( "\t--fp Display Floating Point related PAPI preset events\n" ); - printf( "\t--ins Display instruction related PAPI preset events\n" ); - printf( "\t--idl Display Stalled or Idle PAPI preset events\n" ); - printf( "\t--l1 Display level 1 cache related PAPI preset events\n" ); - printf( "\t--l2 Display level 2 cache related PAPI preset events\n" ); - printf( "\t--l3 Display level 3 cache related PAPI preset events\n" ); - printf( "\t--mem Display memory related PAPI preset events\n" ); - printf( "\t--msc Display miscellaneous PAPI preset events\n" ); - printf( "\t--tlb Display Translation Lookaside Buffer PAPI preset events\n" ); - printf( "\n" ); + printf( "PAPI Preset Event filters can be combined in a logical OR.\n" ); + printf( "Usage: %s [options]\n", argv[0] ); + printf( "Options:\n\n" ); + printf( "General command options:\n" ); + printf( "\t-h, --help Print this help message\n" ); + printf( "\t-a, --avail Display only available PAPI preset and user defined events\n" ); + printf( "\t-c, --check Display only available PAPI preset and user defined events after an availability check\n" ); + printf( "\t-d, --detail Display detailed information about events\n" ); + printf( "\t-e EVENTNAME Display detail information about specified event\n" ); + printf( "\nEvent filtering options:\n" ); + printf( "\t--br Display branch related PAPI preset events\n" ); + printf( "\t--cache Display cache related PAPI preset events\n" ); + printf( "\t--cnd Display conditional PAPI preset events\n" ); + printf( "\t--fp Display Floating Point related PAPI preset events\n" ); + printf( "\t--ins Display instruction related PAPI preset events\n" ); + printf( "\t--idl Display Stalled or Idle PAPI preset events\n" ); + printf( "\t--l1 Display level 1 cache related PAPI preset events\n" ); + printf( "\t--l2 Display level 2 cache related PAPI preset events\n" ); + printf( "\t--l3 Display level 3 cache related PAPI preset events\n" ); + printf( "\t--mem Display memory related PAPI preset events\n" ); + printf( "\t--msc Display miscellaneous PAPI preset events\n" ); + printf( "\t--tlb Display Translation Lookaside Buffer PAPI preset events\n" ); + printf( "\n" ); } static int parse_unit_masks( PAPI_event_info_t * info ) { - char *pmask; - - if ( ( pmask = strchr( info->symbol, ':' ) ) == NULL ) { - return ( 0 ); - } - memmove( info->symbol, pmask, ( strlen( pmask ) + 1 ) * sizeof ( char ) ); - pmask = strchr( info->long_descr, ':' ); - if ( pmask == NULL ) - info->long_descr[0] = 0; - else - memmove( info->long_descr, pmask + sizeof ( char ), - ( strlen( pmask ) + 1 ) * sizeof ( char ) ); - return 1; + char *pmask; + + if ( ( pmask = strchr( info->symbol, ':' ) ) == NULL ) { + return ( 0 ); + } + memmove( info->symbol, pmask, ( strlen( pmask ) + 1 ) * sizeof ( char ) ); + pmask = strchr( info->long_descr, ':' ); + if ( pmask == NULL ) + info->long_descr[0] = 0; + else + memmove( info->long_descr, pmask + sizeof ( char ), + ( strlen( pmask ) + 1 ) * sizeof ( char ) ); + return 1; } static int checkCounter (int eventcode) { - int EventSet = PAPI_NULL; - if (PAPI_create_eventset(&EventSet) != PAPI_OK) - return 0; - if (PAPI_add_event (EventSet, eventcode) != PAPI_OK) - return 0; - if (PAPI_cleanup_eventset (EventSet) != PAPI_OK) - return 0; - if (PAPI_destroy_eventset (&EventSet) != PAPI_OK) - return 0; - return 1; + int EventSet = PAPI_NULL; + if (PAPI_create_eventset(&EventSet) != PAPI_OK) + return 0; + if (PAPI_add_event (EventSet, eventcode) != PAPI_OK) + return 0; + if (PAPI_cleanup_eventset (EventSet) != PAPI_OK) + return 0; + if (PAPI_destroy_eventset (&EventSet) != PAPI_OK) + return 0; + return 1; } @@ -282,10 +282,10 @@ int is_preset_event_available(char *name) { if ( PAPI_get_event_info( event_code, &info ) == PAPI_OK ) { if ( info.count ) { - if ( (check_counter && checkCounter (event_code)) || !check_counter) { - if (strcmp(info.symbol, name) == 0) - return 1; - } + if ( (check_counter && checkCounter (event_code)) || !check_counter) { + if (strcmp(info.symbol, name) == 0) + return 1; + } } } } while (PAPI_enum_event( &event_code, PAPI_PRESET_ENUM_AVAIL ) == PAPI_OK); @@ -319,49 +319,49 @@ main( int argc, char **argv ) for( args = 1; args < argc; args++ ) { if ( strstr( argv[args], "-e" ) ) { - print_event_info = 1; + print_event_info = 1; if( (args+1 >= argc) || ( argv[args+1] == NULL ) || ( strlen( argv[args+1] ) == 0 ) ) { - print_help( argv ); - exit( 1 ); - } - name = argv[args + 1]; + print_help( argv ); + exit( 1 ); + } + name = argv[args + 1]; } else if ( ( !strstr( argv[args], "--") && strstr( argv[args], "-c" ) ) || strstr(argv[args], "--check") ) { - print_avail_only = PAPI_PRESET_ENUM_AVAIL; + print_avail_only = PAPI_PRESET_ENUM_AVAIL; check_counter = 1; } else if ( strstr( argv[args], "-a" )) - print_avail_only = PAPI_PRESET_ENUM_AVAIL; + print_avail_only = PAPI_PRESET_ENUM_AVAIL; else if ( strstr( argv[args], "-d" ) ) - print_tabular = 0; + print_tabular = 0; else if ( strstr( argv[args], "-h" ) ) { - print_help( argv ); - exit( 1 ); + print_help( argv ); + exit( 1 ); } else if ( strstr( argv[args], "--br" ) ) - filter |= PAPI_PRESET_BIT_BR; + filter |= PAPI_PRESET_BIT_BR; else if ( strstr( argv[args], "--cache" ) ) - filter |= PAPI_PRESET_BIT_CACH; + filter |= PAPI_PRESET_BIT_CACH; else if ( strstr( argv[args], "--cnd" ) ) - filter |= PAPI_PRESET_BIT_CND; + filter |= PAPI_PRESET_BIT_CND; else if ( strstr( argv[args], "--fp" ) ) - filter |= PAPI_PRESET_BIT_FP; + filter |= PAPI_PRESET_BIT_FP; else if ( strstr( argv[args], "--ins" ) ) - filter |= PAPI_PRESET_BIT_INS; + filter |= PAPI_PRESET_BIT_INS; else if ( strstr( argv[args], "--idl" ) ) - filter |= PAPI_PRESET_BIT_IDL; + filter |= PAPI_PRESET_BIT_IDL; else if ( strstr( argv[args], "--l1" ) ) - filter |= PAPI_PRESET_BIT_L1; + filter |= PAPI_PRESET_BIT_L1; else if ( strstr( argv[args], "--l2" ) ) - filter |= PAPI_PRESET_BIT_L2; + filter |= PAPI_PRESET_BIT_L2; else if ( strstr( argv[args], "--l3" ) ) - filter |= PAPI_PRESET_BIT_L3; + filter |= PAPI_PRESET_BIT_L3; else if ( strstr( argv[args], "--mem" ) ) - filter |= PAPI_PRESET_BIT_MEM; + filter |= PAPI_PRESET_BIT_MEM; else if ( strstr( argv[args], "--msc" ) ) - filter |= PAPI_PRESET_BIT_MSC; + filter |= PAPI_PRESET_BIT_MSC; else if ( strstr( argv[args], "--tlb" ) ) - filter |= PAPI_PRESET_BIT_TLB; + filter |= PAPI_PRESET_BIT_TLB; } if ( filter == 0 ) { @@ -372,149 +372,149 @@ main( int argc, char **argv ) retval = PAPI_library_init( PAPI_VER_CURRENT ); if ( retval != PAPI_VER_CURRENT ) { - fprintf(stderr,"Error! PAPI library mismatch!\n"); - return 1; + fprintf(stderr,"Error! PAPI library mismatch!\n"); + return 1; } - retval = PAPI_set_debug( PAPI_VERB_ECONT ); - if ( retval != PAPI_OK ) { - fprintf(stderr,"Error with PAPI_set debug!\n"); - return 1; - } + retval = PAPI_set_debug( PAPI_VERB_ECONT ); + if ( retval != PAPI_OK ) { + fprintf(stderr,"Error with PAPI_set debug!\n"); + return 1; + } retval=papi_print_header("Available PAPI preset and user defined events plus hardware information.\n", - &hwinfo ); - if ( retval != PAPI_OK ) { - fprintf(stderr,"Error with PAPI_get_hardware_info!\n"); - return 1; - } + &hwinfo ); + if ( retval != PAPI_OK ) { + fprintf(stderr,"Error with PAPI_get_hardware_info!\n"); + return 1; + } /* Code for info on just one event */ if ( print_event_info ) { - if ( PAPI_event_name_to_code( name, &event_code ) == PAPI_OK ) { - if ( PAPI_get_event_info( event_code, &info ) == PAPI_OK ) { - - if ( event_code & PAPI_PRESET_MASK ) { - printf( "%-30s%s\n%-30s%#-10x\n%-30s%d\n", - "Event name:", info.symbol, "Event Code:", - info.event_code, "Number of Native Events:", - info.count ); - printf( "%-29s|%s|\n%-29s|%s|\n%-29s|%s|\n", - "Short Description:", info.short_descr, - "Long Description:", info.long_descr, - "Developer's Notes:", info.note ); - printf( "%-29s|%s|\n%-29s|%s|\n", "Derived Type:", - info.derived, "Postfix Processing String:", - info.postfix ); - - for( j = 0; j < ( int ) info.count; j++ ) { - printf( " Native Code[%d]: %#x |%s|\n", j, - info.code[j], info.name[j] ); - PAPI_get_event_info( (int) info.code[j], &n_info ); - printf(" Number of Register Values: %d\n", n_info.count ); - for( k = 0; k < ( int ) n_info.count; k++ ) { - printf( " Register[%2d]: %#08x |%s|\n", k, - n_info.code[k], n_info.name[k] ); - } - printf( " Native Event Description: |%s|\n\n", - n_info.long_descr ); - } - - if (!is_preset_event_available(name)) { - printf("\nPRESET event %s is NOT available on this architecture!\n\n", name); - } - - } else { /* must be a native event code */ - printf( "%-30s%s\n%-30s%#-10x\n%-30s%d\n", - "Event name:", info.symbol, "Event Code:", - info.event_code, "Number of Register Values:", - info.count ); - printf( "%-29s|%s|\n", "Description:", info.long_descr ); - for ( k = 0; k < ( int ) info.count; k++ ) { - printf( " Register[%2d]: %#08x |%s|\n", k, - info.code[k], info.name[k] ); - } - - /* if unit masks exist but none are specified, process all */ - if ( !strchr( name, ':' ) ) { - if ( 1 ) { - if ( PAPI_enum_event( &event_code, PAPI_NTV_ENUM_UMASKS ) == PAPI_OK ) { - printf( "\nUnit Masks:\n" ); - do { - retval = PAPI_get_event_info(event_code, &info ); - if ( retval == PAPI_OK ) { - if ( parse_unit_masks( &info ) ) { - printf( "%-29s|%s|%s|\n", - " Mask Info:", info.symbol, - info.long_descr ); - for ( k = 0; k < ( int ) info.count;k++ ) { - printf( " Register[%2d]: %#08x |%s|\n", - k, info.code[k], info.name[k] ); - } - } - } - } while ( PAPI_enum_event( &event_code, - PAPI_NTV_ENUM_UMASKS ) == PAPI_OK ); - } - } - } - } - } - } else { - printf( "Sorry, an event by the name '%s' could not be found.\n" + if ( PAPI_event_name_to_code( name, &event_code ) == PAPI_OK ) { + if ( PAPI_get_event_info( event_code, &info ) == PAPI_OK ) { + + if ( event_code & PAPI_PRESET_MASK ) { + printf( "%-30s%s\n%-30s%#-10x\n%-30s%d\n", + "Event name:", info.symbol, "Event Code:", + info.event_code, "Number of Native Events:", + info.count ); + printf( "%-29s|%s|\n%-29s|%s|\n%-29s|%s|\n", + "Short Description:", info.short_descr, + "Long Description:", info.long_descr, + "Developer's Notes:", info.note ); + printf( "%-29s|%s|\n%-29s|%s|\n", "Derived Type:", + info.derived, "Postfix Processing String:", + info.postfix ); + + for( j = 0; j < ( int ) info.count; j++ ) { + printf( " Native Code[%d]: %#x |%s|\n", j, + info.code[j], info.name[j] ); + PAPI_get_event_info( (int) info.code[j], &n_info ); + printf(" Number of Register Values: %d\n", n_info.count ); + for( k = 0; k < ( int ) n_info.count; k++ ) { + printf( " Register[%2d]: %#08x |%s|\n", k, + n_info.code[k], n_info.name[k] ); + } + printf( " Native Event Description: |%s|\n\n", + n_info.long_descr ); + } + + if (!is_preset_event_available(name)) { + printf("\nPRESET event %s is NOT available on this architecture!\n\n", name); + } + + } else { /* must be a native event code */ + printf( "%-30s%s\n%-30s%#-10x\n%-30s%d\n", + "Event name:", info.symbol, "Event Code:", + info.event_code, "Number of Register Values:", + info.count ); + printf( "%-29s|%s|\n", "Description:", info.long_descr ); + for ( k = 0; k < ( int ) info.count; k++ ) { + printf( " Register[%2d]: %#08x |%s|\n", k, + info.code[k], info.name[k] ); + } + + /* if unit masks exist but none are specified, process all */ + if ( !strchr( name, ':' ) ) { + if ( 1 ) { + if ( PAPI_enum_event( &event_code, PAPI_NTV_ENUM_UMASKS ) == PAPI_OK ) { + printf( "\nUnit Masks:\n" ); + do { + retval = PAPI_get_event_info(event_code, &info ); + if ( retval == PAPI_OK ) { + if ( parse_unit_masks( &info ) ) { + printf( "%-29s|%s|%s|\n", + " Mask Info:", info.symbol, + info.long_descr ); + for ( k = 0; k < ( int ) info.count;k++ ) { + printf( " Register[%2d]: %#08x |%s|\n", + k, info.code[k], info.name[k] ); + } + } + } + } while ( PAPI_enum_event( &event_code, + PAPI_NTV_ENUM_UMASKS ) == PAPI_OK ); + } + } + } + } + } + } else { + printf( "Sorry, an event by the name '%s' could not be found.\n" " Is it typed correctly?\n\n", name ); - } + } } else { - /* Print *ALL* Events */ + /* Print *ALL* Events */ for (i=0 ; i<2 ; i++) { - // set the event code to fetch preset events the first time through loop and user events the second time through the loop - if (i== 0) { - event_code = 0 | PAPI_PRESET_MASK; - } else { - event_code = 0 | PAPI_UE_MASK; - } - - /* For consistency, always ASK FOR the first event, if there is not one then nothing to process */ - if (PAPI_enum_event( &event_code, PAPI_ENUM_FIRST ) != PAPI_OK) { - continue; - } - - // print heading to show which kind of events follow - if (i== 0) { - printf( "================================================================================\n" ); - printf( " PAPI Preset Events\n" ); - printf( "================================================================================\n" ); - } else { - printf( "\n"); // put a blank line after the presets before strarting the user events - printf( "================================================================================\n" ); - printf( " User Defined Events\n" ); - printf( "================================================================================\n" ); - } - - if ( print_tabular ) { - printf( " Name Code " ); - if ( !print_avail_only ) { - printf( "Avail " ); - } - printf( "Deriv Description (Note)\n" ); - } else { - printf( "%-13s%-11s%-8s%-16s\n |Long Description|\n" + // set the event code to fetch preset events the first time through loop and user events the second time through the loop + if (i== 0) { + event_code = 0 | PAPI_PRESET_MASK; + } else { + event_code = 0 | PAPI_UE_MASK; + } + + /* For consistency, always ASK FOR the first event, if there is not one then nothing to process */ + if (PAPI_enum_event( &event_code, PAPI_ENUM_FIRST ) != PAPI_OK) { + continue; + } + + // print heading to show which kind of events follow + if (i== 0) { + printf( "================================================================================\n" ); + printf( " PAPI Preset Events\n" ); + printf( "================================================================================\n" ); + } else { + printf( "\n"); // put a blank line after the presets before strarting the user events + printf( "================================================================================\n" ); + printf( " User Defined Events\n" ); + printf( "================================================================================\n" ); + } + + if ( print_tabular ) { + printf( " Name Code " ); + if ( !print_avail_only ) { + printf( "Avail " ); + } + printf( "Deriv Description (Note)\n" ); + } else { + printf( "%-13s%-11s%-8s%-16s\n |Long Description|\n" " |Developer's Notes|\n |Derived|\n |PostFix|\n" " Native Code[n]: |name|\n", - "Symbol", "Event Code", "Count", "|Short Description|" ); - } - do { - if ( PAPI_get_event_info( event_code, &info ) == PAPI_OK ) { - if ( print_tabular ) { - // if this is a user defined event or its a preset and matches the preset event filters, display its information - if ( (i==1) || (filter & info.event_type)) { - if ( print_avail_only ) { - if ( info.count ) { + "Symbol", "Event Code", "Count", "|Short Description|" ); + } + do { + if ( PAPI_get_event_info( event_code, &info ) == PAPI_OK ) { + if ( print_tabular ) { + // if this is a user defined event or its a preset and matches the preset event filters, display its information + if ( (i==1) || (filter & info.event_type)) { + if ( print_avail_only ) { + if ( info.count ) { if ( (check_counter && checkCounter (event_code)) || !check_counter) { printf( "%-13s%#x %-5s%s", @@ -522,83 +522,83 @@ main( int argc, char **argv ) info.event_code, is_derived( &info ), info.long_descr ); } - } - if ( info.note[0] ) { - printf( " (%s)", info.note ); - } - printf( "\n" ); - } else { - printf( "%-13s%#x %-6s%-4s %s", - info.symbol, - info.event_code, - ( info.count ? "Yes" : "No" ), - is_derived( &info ), info.long_descr ); - if ( info.note[0] ) { - printf( " (%s)", info.note ); - } - printf( "\n" ); - } - tot_count++; - if ( info.count ) { - if ((check_counter && checkCounter (event_code)) || !check_counter ) - avail_count++; - } - if ( !strcmp( is_derived( &info ), "Yes" ) ) { - deriv_count++; - } - } - } else { - if ( ( print_avail_only && info.count ) || - ( print_avail_only == 0 ) ) - { - if ((check_counter && checkCounter (event_code)) || !check_counter) - { - printf( "%s\t%#x\t%d\t|%s|\n |%s|\n" - " |%s|\n |%s|\n |%s|\n", - info.symbol, info.event_code, info.count, - info.short_descr, info.long_descr, info.note, - info.derived, info.postfix ); - for ( j = 0; j < ( int ) info.count; j++ ) { - printf( " Native Code[%d]: %#x |%s|\n", j, - info.code[j], info.name[j] ); - } + } + if ( info.note[0] ) { + printf( " (%s)", info.note ); + } + printf( "\n" ); + } else { + printf( "%-13s%#x %-6s%-4s %s", + info.symbol, + info.event_code, + ( info.count ? "Yes" : "No" ), + is_derived( &info ), info.long_descr ); + if ( info.note[0] ) { + printf( " (%s)", info.note ); + } + printf( "\n" ); + } + tot_count++; + if ( info.count ) { + if ((check_counter && checkCounter (event_code)) || !check_counter ) + avail_count++; } - } - tot_count++; - if ( info.count ) { - if ((check_counter && checkCounter (event_code)) || !check_counter ) - avail_count++; - } - if ( !strcmp( is_derived( &info ), "Yes" ) ) { - deriv_count++; - } - } - } - } while (PAPI_enum_event( &event_code, print_avail_only ) == PAPI_OK); + if ( !strcmp( is_derived( &info ), "Yes" ) ) { + deriv_count++; + } + } + } else { + if ( ( print_avail_only && info.count ) || + ( print_avail_only == 0 ) ) + { + if ((check_counter && checkCounter (event_code)) || !check_counter) + { + printf( "%s\t%#x\t%d\t|%s|\n |%s|\n" + " |%s|\n |%s|\n |%s|\n", + info.symbol, info.event_code, info.count, + info.short_descr, info.long_descr, info.note, + info.derived, info.postfix ); + for ( j = 0; j < ( int ) info.count; j++ ) { + printf( " Native Code[%d]: %#x |%s|\n", j, + info.code[j], info.name[j] ); + } + } + } + tot_count++; + if ( info.count ) { + if ((check_counter && checkCounter (event_code)) || !check_counter ) + avail_count++; + } + if ( !strcmp( is_derived( &info ), "Yes" ) ) { + deriv_count++; + } + } + } + } while (PAPI_enum_event( &event_code, print_avail_only ) == PAPI_OK); } } - printf( "--------------------------------------------------------------------------------\n" ); - - if ( !print_event_info ) { - if ( print_avail_only ) { - printf( "Of %d available events, %d ", avail_count, deriv_count ); - } else { - printf( "Of %d possible events, %d are available, of which %d ", - tot_count, avail_count, deriv_count ); - } - if ( deriv_count == 1 ) { - printf( "is derived.\n\n" ); - } else { - printf( "are derived.\n\n" ); - } - - if (avail_count==0) { - printf("No events detected! Check papi_component_avail to find out why.\n"); - printf("\n"); - } - } - - return 0; + printf( "--------------------------------------------------------------------------------\n" ); + + if ( !print_event_info ) { + if ( print_avail_only ) { + printf( "Of %d available events, %d ", avail_count, deriv_count ); + } else { + printf( "Of %d possible events, %d are available, of which %d ", + tot_count, avail_count, deriv_count ); + } + if ( deriv_count == 1 ) { + printf( "is derived.\n\n" ); + } else { + printf( "are derived.\n\n" ); + } + + if (avail_count==0) { + printf("No events detected! Check papi_component_avail to find out why.\n"); + printf("\n"); + } + } + + return 0; } From a0ae3502fb6297af88412a51ad6500c26509f70e Mon Sep 17 00:00:00 2001 From: Daniel Barry Date: Thu, 7 Nov 2024 08:55:25 -0800 Subject: [PATCH 7/8] utils: new modifiers for strictly CPU presets Replace modifiers with only those that enumerate the CPU preset events. These changes have been tested on the NVIDIA Grace-Hopper architecture. --- src/utils/papi_avail.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/utils/papi_avail.c b/src/utils/papi_avail.c index 3f284bbca..4b04ad21c 100644 --- a/src/utils/papi_avail.c +++ b/src/utils/papi_avail.c @@ -303,7 +303,7 @@ main( int argc, char **argv ) unsigned int filter = 0; int print_event_info = 0; char *name = NULL; - int print_avail_only = PAPI_ENUM_EVENTS; + int print_avail_only = PAPI_PRESET_ENUM_CPU; int print_tabular = 1; PAPI_event_info_t info; const PAPI_hw_info_t *hwinfo = NULL; @@ -332,7 +332,7 @@ main( int argc, char **argv ) check_counter = 1; } else if ( strstr( argv[args], "-a" )) - print_avail_only = PAPI_PRESET_ENUM_AVAIL; + print_avail_only = PAPI_PRESET_ENUM_CPU_AVAIL; else if ( strstr( argv[args], "-d" ) ) print_tabular = 0; else if ( strstr( argv[args], "-h" ) ) { @@ -498,7 +498,7 @@ main( int argc, char **argv ) if ( print_tabular ) { printf( " Name Code " ); - if ( !print_avail_only ) { + if ( print_avail_only == PAPI_PRESET_ENUM_CPU ) { printf( "Avail " ); } printf( "Deriv Description (Note)\n" ); @@ -513,7 +513,7 @@ main( int argc, char **argv ) if ( print_tabular ) { // if this is a user defined event or its a preset and matches the preset event filters, display its information if ( (i==1) || (filter & info.event_type)) { - if ( print_avail_only ) { + if ( print_avail_only == PAPI_PRESET_ENUM_CPU_AVAIL ) { if ( info.count ) { if ( (check_counter && checkCounter (event_code)) || !check_counter) { @@ -548,8 +548,8 @@ main( int argc, char **argv ) } } } else { - if ( ( print_avail_only && info.count ) || - ( print_avail_only == 0 ) ) + if ( ( print_avail_only == PAPI_PRESET_ENUM_CPU_AVAIL && info.count ) || + ( print_avail_only == PAPI_PRESET_ENUM_CPU ) ) { if ((check_counter && checkCounter (event_code)) || !check_counter) { @@ -581,7 +581,7 @@ main( int argc, char **argv ) printf( "--------------------------------------------------------------------------------\n" ); if ( !print_event_info ) { - if ( print_avail_only ) { + if ( print_avail_only == PAPI_PRESET_ENUM_CPU_AVAIL ) { printf( "Of %d available events, %d ", avail_count, deriv_count ); } else { printf( "Of %d possible events, %d are available, of which %d ", From 6406ed1d35b52656d3b9944b09cda250fe0d08cc Mon Sep 17 00:00:00 2001 From: Daniel Barry Date: Thu, 7 Nov 2024 14:17:14 -0800 Subject: [PATCH 8/8] utils: papi_avail extension for component presets Enumerate presets for components as well as the CPU. These changes have been tested on the NVIDIA Grace-Hopper architecture. --- src/utils/papi_avail.c | 162 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 156 insertions(+), 6 deletions(-) diff --git a/src/utils/papi_avail.c b/src/utils/papi_avail.c index 4b04ad21c..85d9f2a57 100644 --- a/src/utils/papi_avail.c +++ b/src/utils/papi_avail.c @@ -277,19 +277,31 @@ int is_preset_event_available(char *name) { exit(1); } + /* Since some component presets require qualifiers, such as ":device=0", but + * the base preset names do not contain qualifiers, then the qualifier must + * first be stripped in order to find a match. */ + char *localname = strdup(name); + char *basename = strtok(localname, ":"); + if( NULL == basename ) { + basename = name; + } + /* Iterate over all the available preset events and compare them by names. */ do { if ( PAPI_get_event_info( event_code, &info ) == PAPI_OK ) { if ( info.count ) { if ( (check_counter && checkCounter (event_code)) || !check_counter) { - if (strcmp(info.symbol, name) == 0) + if (strcmp(info.symbol, basename) == 0) return 1; } } } } while (PAPI_enum_event( &event_code, PAPI_PRESET_ENUM_AVAIL ) == PAPI_OK); + /* Free the temporary, dynamically allocated buffer. */ + free(localname); + return 0; } @@ -503,7 +515,7 @@ main( int argc, char **argv ) } printf( "Deriv Description (Note)\n" ); } else { - printf( "%-13s%-11s%-8s%-16s\n |Long Description|\n" + printf( "%-17s%-11s%-8s%-16s\n |Long Description|\n" " |Developer's Notes|\n |Derived|\n |PostFix|\n" " Native Code[n]: |name|\n", "Symbol", "Event Code", "Count", "|Short Description|" ); @@ -517,7 +529,7 @@ main( int argc, char **argv ) if ( info.count ) { if ( (check_counter && checkCounter (event_code)) || !check_counter) { - printf( "%-13s%#x %-5s%s", + printf( "%-17s%#x %-5s%s", info.symbol, info.event_code, is_derived( &info ), info.long_descr ); @@ -528,7 +540,7 @@ main( int argc, char **argv ) } printf( "\n" ); } else { - printf( "%-13s%#x %-6s%-4s %s", + printf( "%-17s%#x %-6s%-4s %s", info.symbol, info.event_code, ( info.count ? "Yes" : "No" ), @@ -575,13 +587,151 @@ main( int argc, char **argv ) } } } while (PAPI_enum_event( &event_code, print_avail_only ) == PAPI_OK); + + /* Repeat the logic for component presets. For consistency, always ASK FOR the first event, + * if there is not one then nothing to process */ + if (PAPI_enum_event( &event_code, PAPI_ENUM_FIRST_COMP ) != PAPI_OK) { + continue; + } + + /* Print heading for component presets. */ + if (i== 0) { + + if( print_avail_only == PAPI_PRESET_ENUM_CPU ) { + print_avail_only = PAPI_ENUM_EVENTS; + } else if( print_avail_only == PAPI_PRESET_ENUM_CPU_AVAIL ) { + print_avail_only = PAPI_PRESET_ENUM_AVAIL; + } + + printf( "================================================================================\n" ); + printf( " PAPI Component Presets\n" ); + printf( "================================================================================\n" ); + + if ( print_tabular ) { + printf( " Name Code " ); + if ( print_avail_only == PAPI_ENUM_EVENTS ) { + printf( "Avail " ); + } + printf( "Deriv Description (Note)\n" ); + } else { + printf( "%-17s%-11s%-8s%-16s\n |Long Description|\n" + " |Developer's Notes|\n |Derived|\n |PostFix|\n" + " Native Code[n]: |name|\n", + "Symbol", "Event Code", "Count", "|Short Description|" ); + } + + int first_flag = 1; + do { + if ( PAPI_get_event_info( event_code, &info ) == PAPI_OK ) { + if ( print_tabular ) { + // if this is a user defined event or its a preset and matches the preset event filters, display its information + if ( filter & info.event_type ) { + if ( print_avail_only == PAPI_PRESET_ENUM_AVAIL ) { + if ( info.count ) { + if ( (check_counter && checkCounter (event_code)) || !check_counter) { + printf( "%-17s%#x %-5s%s\n", + info.symbol, + info.event_code, + is_derived( &info ), info.long_descr ); + + /* Add event to tally. */ + avail_count++; + if ( !strcmp( is_derived( &info ), "Yes" ) ) { + deriv_count++; + } + + /* List the qualifiers. */ + int k; + for( k = 0; k < info.num_quals; ++k ) { + printf(" %s\n %s", info.quals[k], info.descrs[k]); + } + } + } + if ( info.note[0] ) { + printf( " (%s)", info.note ); + } + printf( "\n" ); + } else { + + int cid, numcmp = PAPI_num_components(); + for ( cid = 0; cid < numcmp; cid++ ) { + const PAPI_component_info_t *component; + component=PAPI_get_component_info(cid); + + /* Skip disabled components */ + if (component->disabled && component->disabled != PAPI_EDELAY_INIT) continue; + + if ( info.count && info.compIdx == cid ) { + if( !first_flag ) { + printf( "--------------------------------------------------------------------------------\n" ); + } + first_flag = 0; + printf( "%-17s%#x %-6s%-4s %s", + info.symbol, + info.event_code, + ( info.count ? "Yes" : "No" ), + is_derived( &info ), info.long_descr ); + if ( info.note[0] ) { + printf( " (%s)", info.note ); + } + printf("\n"); + + /* List the qualifiers. */ + int k; + for( k = 0; k < info.num_quals; ++k ) { + printf(" %s\n %s\n", info.quals[k], info.descrs[k]); + } + + tot_count++; + if ( info.count ) { + if ((check_counter && checkCounter (event_code)) || !check_counter ) + avail_count++; + } + if ( !strcmp( is_derived( &info ), "Yes" ) ) { + deriv_count++; + } + } + } // end of loop for number of components + } + } + } else { + if ( ( print_avail_only == PAPI_PRESET_ENUM_AVAIL && info.count ) || + ( print_avail_only == PAPI_ENUM_EVENTS ) ) + { + if ((check_counter && checkCounter (event_code)) || !check_counter) { + printf( "%s\t%#x\t%d\t|%s|\n |%s|\n" + " |%s|\n |%s|\n |%s|\n", + info.symbol, info.event_code, info.count, + info.short_descr, info.long_descr, info.note, + info.derived, info.postfix ); + for ( j = 0; j < ( int ) info.count; j++ ) { + printf( " Native Code[%d]: %#x |%s|\n", j, + info.code[j], info.name[j] ); + } + } + } + tot_count++; + if ( info.count ) { + if ((check_counter && checkCounter (event_code)) || !check_counter ) + avail_count++; + } + if ( !strcmp( is_derived( &info ), "Yes" ) ) { + deriv_count++; + } + } + } + } while (PAPI_enum_event( &event_code, PAPI_ENUM_EVENTS ) == PAPI_OK); + } + + + } } - printf( "--------------------------------------------------------------------------------\n" ); + printf( "================================================================================\n" ); if ( !print_event_info ) { - if ( print_avail_only == PAPI_PRESET_ENUM_CPU_AVAIL ) { + if ( print_avail_only == PAPI_PRESET_ENUM_CPU_AVAIL || print_avail_only == PAPI_PRESET_ENUM_AVAIL ) { printf( "Of %d available events, %d ", avail_count, deriv_count ); } else { printf( "Of %d possible events, %d are available, of which %d ",