Skip to content

Commit

Permalink
Merge pull request #188 from deater/master
Browse files Browse the repository at this point in the history
perf_event: initial heterogeneous CPU support
  • Loading branch information
Treece-Burgess committed Jul 3, 2024
2 parents 7d8f196 + 9741cd6 commit 3974391
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 19 deletions.
76 changes: 64 additions & 12 deletions src/components/perf_event/pe_libpfm4_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -1134,8 +1134,12 @@ _pe_libpfm4_shutdown(papi_vector_t *my_vector,
*
* @param[in] component
* -- pointer to component structure
* @param[in] cidx
* -- component index
* @param[in] event_table
* -- native event table structure
* @param[in] pmu_type
* -- type of PMU to init. Should only be PMU_TYPE_CORE
*
* @retval PAPI_OK We initialized correctly
* @retval PAPI_ECMP There was an error initializing the component
Expand Down Expand Up @@ -1208,6 +1212,9 @@ _pe_libpfm4_init(papi_vector_t *component, int cidx,
}

SUBDBG("Detected pmus:\n");

/* Create the list of available PMUs */

i=0;
while(1) {
memset(&pinfo,0,sizeof(pfm_pmu_info_t));
Expand All @@ -1225,34 +1232,73 @@ _pe_libpfm4_init(papi_vector_t *component, int cidx,
if ((retval==PFM_SUCCESS) && (pinfo.name != NULL) &&
(pmu_is_present_and_right_type(&pinfo,pmu_type))) {

/* skip if it is amd64_fam17h and zen1 is also present. */
if (strcmp(pinfo.name,"amd64_fam17h") == 0 && amd64_fam17h_zen1_present) {
i++;
continue;
}
/* Check for PMUs that should not be included even */
/* though they are valid */

/* for backwards compatability reasons */
/* adm64_fam17h and zen1 are aliases to the same PMU */
/* so we should only include one of them. */

if ( (strcmp(pinfo.name,"amd64_fam17h") == 0) &&
amd64_fam17h_zen1_present) {

i++;
continue;
}

/* if we arrive here the PMU is valid and we want to add it */

SUBDBG("\t%d %s %s %d\n",i,
pinfo.name,pinfo.desc,pinfo.type);

detected_pmus++;
ncnt+=pinfo.nevents;

/* FIXME: why do we use 'j' and not base this on detected_pmus? */

if (j < PAPI_PMU_MAX) {
component->cmp_info.pmu_names[j++] =
strdup(pinfo.name);
}

/* For backwards compatability reasons PAPI has the */
/* idea of the "default" PMU that events can be */
/* assigned to without having to specify the PMU */
/* explicitly. We use libpfm4's PMU_TYPE_CORE */
/* to determine this, but it can cause issues when */
/* an architecture has multiple CORE PMUs */

if (pmu_type & PMU_TYPE_CORE) {

/* Hack to have "default core" PMU */
if ( (pinfo.type==PFM_PMU_TYPE_CORE) &&
strcmp(pinfo.name,"ix86arch")) {
memcpy(&(event_table->default_pmu),
&pinfo,sizeof(pfm_pmu_info_t));
found_default++;
if (!strcmp(pinfo.name,"ix86arch")) {

/* On x86 chips don't make the generic ix86arch PMU */
/* the default. */

} else if (strstr(pinfo.desc,"E-Core")) {

/* For heterogeneous systems with both E-cores and P-cores */
/* we use P-core as default. Currently there isn't a way */
/* to do this with libpfm4 except or this hack. */
/* FIXME: find better way to get this info from libpfm4 */
}
else if (pinfo.type!=PFM_PMU_TYPE_CORE) {
/* skip the "perf" and "perf_raw" PMUs */
}
else {
/* Actually set the PMU as the default one */

memcpy(&(event_table->default_pmu),
&pinfo,sizeof(pfm_pmu_info_t));
found_default++;
}



/* For ARM processors, */
/* For ARM processors override the hw_info model_string */
/* (gathered from /proc/cpuinfo) with the more complete */
/* model info provided by libpfm4. */
/* FIXME: is this the proper place to do this? */
if ( (pinfo.type==PFM_PMU_TYPE_CORE) &&
( _papi_hwi_system_info.hw_info.vendor >= PAPI_VENDOR_ARM_ARM)) {
if (strlen(_papi_hwi_system_info.hw_info.model_string) == 0) {
Expand All @@ -1262,6 +1308,9 @@ _pe_libpfm4_init(papi_vector_t *component, int cidx,
}
}

/* FIXME: this is a remnant from when CORE and UNCORE PMU init */
/* shared the same init code. It should not be possible */
/* to hit this code path anymore. */
if (pmu_type==PMU_TYPE_UNCORE) {
/* To avoid confusion, no "default" CPU for uncore */
found_default=1;
Expand All @@ -1276,10 +1325,13 @@ _pe_libpfm4_init(papi_vector_t *component, int cidx,
return PAPI_ENOSUPP;
}

/* Error if we couldn't pick a default PMU */
if (!found_default) {
return PAPI_ECMP;
}

/* Error if we found more than one default PMU */
/* FIXME: this breaks on heterogeneous CPU systems */
if (found_default>1) {
return PAPI_ECOUNT;
}
Expand Down
38 changes: 31 additions & 7 deletions src/papi_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -2299,34 +2299,58 @@ _papi_hwi_get_preset_event_info( int EventCode, PAPI_event_info_t * info )
// 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);

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,
sizeof(info->symbol)-1);
sizeof(info->symbol)-1);

if ( _papi_hwi_presets[i].short_descr != NULL )
/* set up short description, if available */
if ( _papi_hwi_presets[i].short_descr != NULL ) {
strncpy( info->short_descr, _papi_hwi_presets[i].short_descr,
sizeof ( info->short_descr )-1 );
}

if ( _papi_hwi_presets[i].long_descr != NULL )
/* set up long description, if available */
if ( _papi_hwi_presets[i].long_descr != NULL ) {
strncpy( info->long_descr, _papi_hwi_presets[i].long_descr,
sizeof ( info->long_descr )-1 );
}

info->event_type = _papi_hwi_presets[i].event_type;
info->count = _papi_hwi_presets[i].count;


/* set up if derived event */
_papi_hwi_derived_string( _papi_hwi_presets[i].derived_int,
info->derived, sizeof ( info->derived )-1 );

if ( _papi_hwi_presets[i].postfix != NULL )
if ( _papi_hwi_presets[i].postfix != NULL ) {
strncpy( info->postfix, _papi_hwi_presets[i].postfix,
sizeof ( info->postfix )-1 );
}

for(j=0;j < info->count; j++) {
info->code[j]=_papi_hwi_presets[i].code[j];
strncpy(info->name[j], _papi_hwi_presets[i].name[j],
sizeof(info->name[j])-1);

/* make sure the name exists before trying to copy it */
/* that can happen if an event is in the definition in */
/* papi_events.csv but the event is unsupported on the cpu */
/* 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);
return PAPI_ENOEVNT;
}
else {
info->code[j]=_papi_hwi_presets[i].code[j];
strncpy(info->name[j], _papi_hwi_presets[i].name[j],
sizeof(info->name[j])-1);
}
}

if ( _papi_hwi_presets[i].note != NULL ) {
Expand Down

0 comments on commit 3974391

Please sign in to comment.