PAPI 7.1.0.0
Loading...
Searching...
No Matches
pe_libpfm4_events.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

int _pe_libpfm4_setup_presets (char *name, int type, int cidx)
 
int _pe_libpfm4_ntv_enum_events (unsigned int *EventCode, int modifier, int cidx, struct native_event_table_t *event_table)
 
int _pe_libpfm4_ntv_name_to_code (const char *ntv_name, unsigned int *EventCode, int cidx, struct native_event_table_t *event_table)
 
int _pe_libpfm4_ntv_code_to_name (unsigned int EventCode, char *name, int len, struct native_event_table_t *event_table)
 
int _pe_libpfm4_ntv_code_to_descr (unsigned int EventCode, char *name, int len, struct native_event_table_t *event_table)
 
int _pe_libpfm4_shutdown (papi_vector_t *my_vector, struct native_event_table_t *event_table)
 
int _pe_libpfm4_ntv_code_to_info (unsigned int EventCode, PAPI_event_info_t *info, struct native_event_table_t *event_table)
 
int _pe_libpfm4_init (papi_vector_t *my_vector, int cidx, struct native_event_table_t *event_table, int pmu_type)
 
int _peu_libpfm4_init (papi_vector_t *my_vector, int cidx, struct native_event_table_t *event_table, int pmu_type)
 

Function Documentation

◆ _pe_libpfm4_init()

int _pe_libpfm4_init ( papi_vector_t my_vector,
int  cidx,
struct native_event_table_t event_table,
int  pmu_type 
)

Definition at line 1146 of file pe_libpfm4_events.c.

1148 {
1149
1150 int detected_pmus=0, found_default=0;
1151 int i;
1152 int j=0;
1153 unsigned int ncnt;
1154
1155 pfm_err_t retval = PFM_SUCCESS;
1156 pfm_pmu_info_t pinfo;
1157 unsigned int strSize;
1158
1159 /* allocate the native event structure */
1160 event_table->num_native_events=0;
1161 event_table->pmu_type=pmu_type;
1162
1163 event_table->native_events=calloc(NATIVE_EVENT_CHUNK,
1164 sizeof(struct native_event_t));
1165 if (event_table->native_events==NULL) {
1166 return PAPI_ENOMEM;
1167 }
1168
1170
1171 /* Count number of present PMUs */
1172 detected_pmus=0;
1173 ncnt=0;
1174
1175 /* init default pmu */
1176 /* need to init pinfo or pfmlib might complain */
1177 memset(&(event_table->default_pmu), 0, sizeof(pfm_pmu_info_t));
1178 event_table->default_pmu.size = sizeof(pfm_pmu_info_t);
1179 retval=pfm_get_pmu_info(0, &(event_table->default_pmu));
1180
1181 SUBDBG("Prescan for aliases.\n");
1182 /* We have to see if we have aliases in there as separate PMUs, */
1183 /* we don't want both PMUs with all the events duplicated. */
1184 /* For aliases, either is valid alone, but if both are present */
1185 /* specify a preference in the code. */
1186 /* Alias: amd64_fam17h_zen1 over amd64_fam17h. */
1187 /* Alias flags are static ints global to this file. */
1188 i=0;
1189 while(1) {
1190 memset(&pinfo,0,sizeof(pfm_pmu_info_t));
1191 pinfo.size = sizeof(pfm_pmu_info_t);
1192 retval=pfm_get_pmu_info(i, &pinfo);
1193
1194 /* We're done if we hit an invalid PMU entry */
1195 /* We can't check against PFM_PMU_MAX as that might not */
1196 /* match if libpfm4 is dynamically linked */
1197
1198 if (retval==PFM_ERR_INVAL) {
1199 break;
1200 }
1201
1202 if ( (retval==PFM_SUCCESS) && (pinfo.name != NULL) &&
1203 (pmu_is_present_and_right_type(&pinfo,pmu_type)) &&
1204 (strcmp(pinfo.name,"amd64_fam17h_zen1") == 0) ) {
1206 }
1207 i++;
1208 }
1209
1210 SUBDBG("Detected pmus:\n");
1211 i=0;
1212 while(1) {
1213 memset(&pinfo,0,sizeof(pfm_pmu_info_t));
1214 pinfo.size = sizeof(pfm_pmu_info_t);
1215 retval=pfm_get_pmu_info(i, &pinfo);
1216
1217 /* We're done if we hit an invalid PMU entry */
1218 /* We can't check against PFM_PMU_MAX as that might not */
1219 /* match if libpfm4 is dynamically linked */
1220
1221 if (retval==PFM_ERR_INVAL) {
1222 break;
1223 }
1224
1225 if ((retval==PFM_SUCCESS) && (pinfo.name != NULL) &&
1226 (pmu_is_present_and_right_type(&pinfo,pmu_type))) {
1227
1228 /* skip if it is amd64_fam17h and zen1 is also present. */
1229 if (strcmp(pinfo.name,"amd64_fam17h") == 0 && amd64_fam17h_zen1_present) {
1230 i++;
1231 continue;
1232 }
1233
1234 SUBDBG("\t%d %s %s %d\n",i,
1235 pinfo.name,pinfo.desc,pinfo.type);
1236
1237 detected_pmus++;
1238 ncnt+=pinfo.nevents;
1239
1240 if (j < PAPI_PMU_MAX) {
1241 component->cmp_info.pmu_names[j++] =
1242 strdup(pinfo.name);
1243 }
1244
1245 if (pmu_type & PMU_TYPE_CORE) {
1246
1247 /* Hack to have "default core" PMU */
1248 if ( (pinfo.type==PFM_PMU_TYPE_CORE) &&
1249 strcmp(pinfo.name,"ix86arch")) {
1250 memcpy(&(event_table->default_pmu),
1251 &pinfo,sizeof(pfm_pmu_info_t));
1252 found_default++;
1253 }
1254
1255 /* For ARM processors, */
1256 if ( (pinfo.type==PFM_PMU_TYPE_CORE) &&
1258 if (strlen(_papi_hwi_system_info.hw_info.model_string) == 0) {
1259 strSize = sizeof(_papi_hwi_system_info.hw_info.model_string);
1260 strncpy( _papi_hwi_system_info.hw_info.model_string, pinfo.desc, strSize - 1);
1261 }
1262 }
1263 }
1264
1265 if (pmu_type==PMU_TYPE_UNCORE) {
1266 /* To avoid confusion, no "default" CPU for uncore */
1267 found_default=1;
1268 }
1269 }
1270 i++;
1271 }
1272 SUBDBG("%d native events detected on %d pmus\n",ncnt,detected_pmus);
1273
1274 if (detected_pmus==0) {
1275 SUBDBG("Could not find any PMUs\n");
1276 return PAPI_ENOSUPP;
1277 }
1278
1279 if (!found_default) {
1280 return PAPI_ECMP;
1281 }
1282
1283 if (found_default>1) {
1284 return PAPI_ECOUNT;
1285 }
1286
1287 component->cmp_info.num_native_events = ncnt;
1288
1289 component->cmp_info.num_cntrs = event_table->default_pmu.num_cntrs+
1290 event_table->default_pmu.num_fixed_cntrs;
1291
1292 SUBDBG( "num_counters: %d\n", component->cmp_info.num_cntrs );
1293
1294 /* Setup presets, only if Component 0 and default core PMU */
1295 if ((cidx==0) && (found_default)) {
1296 retval = _papi_load_preset_table( (char *)event_table->default_pmu.name,
1297 event_table->default_pmu.pmu, cidx );
1298 if ( retval!=PAPI_OK ) {
1299 return PAPI_ENOEVNT;
1300 }
1301 }
1302
1303 return PAPI_OK;
1304}
int i
#define PAPI_OK
Definition: f90papi.h:73
#define PAPI_ENOEVNT
Definition: f90papi.h:139
#define PAPI_VENDOR_ARM_ARM
Definition: f90papi.h:102
#define PAPI_ECOUNT
Definition: f90papi.h:195
#define PAPI_ENOSUPP
Definition: f90papi.h:244
#define PAPI_PMU_MAX
Definition: f90papi.h:101
#define PAPI_ECMP
Definition: f90papi.h:214
#define PAPI_ENOMEM
Definition: f90papi.h:16
#define SUBDBG(format, args...)
Definition: papi_debug.h:64
#define PMU_TYPE_CORE
#define PMU_TYPE_UNCORE
int _papi_load_preset_table(char *pmu_str, int pmu_type, int cidx)
Definition: papi_preset.c:771
static int cidx
#define NATIVE_EVENT_CHUNK
static int amd64_fam17h_zen1_present
static int pmu_is_present_and_right_type(pfm_pmu_info_t *pinfo, int type)
papi_mdi_t _papi_hwi_system_info
Definition: papi_internal.c:56
int pfm_err_t
Definition: pfmlib.h:151
int vendor
Definition: papi.h:781
char model_string[PAPI_MAX_STR_LEN]
Definition: papi.h:784
pfm_pmu_info_t default_pmu
struct native_event_t * native_events
PAPI_hw_info_t hw_info
int retval
Definition: zero_fork.c:53
Here is the call graph for this function:

◆ _pe_libpfm4_ntv_code_to_descr()

int _pe_libpfm4_ntv_code_to_descr ( unsigned int  EventCode,
char *  name,
int  len,
struct native_event_table_t event_table 
)

Definition at line 725 of file pe_libpfm4_events.c.

728{
729 SUBDBG("ENTER: EventCode: %#x, ntv_descr: %p, len: %d: event_table: %p\n", EventCode, ntv_descr, len, event_table);
730
731 int eidx;
732 int papi_event_code;
733 char *mdesc;
734 char *edesc;
735
736 // get the attribute index for this papi event
737 papi_event_code = _papi_hwi_get_papi_event_code();
738
739 // a papi event code less than 0 is invalid, return error
740 if (papi_event_code <= 0) {
741 SUBDBG("EXIT: PAPI_ENOEVNT\n");
742 return PAPI_ENOEVNT;
743 }
744
745 // find our native event table for this papi event code (search list backwards because it improves chances of finding it quickly)
746 for (eidx=event_table->num_native_events-1 ; eidx>=0 ; eidx--) {
747 SUBDBG("native_event[%d]: papi_event_code: %#x, libpfm4_idx: %#x\n", eidx, event_table->native_events[eidx].papi_event_code, event_table->native_events[eidx].libpfm4_idx);
748 if ((papi_event_code == event_table->native_events[eidx].papi_event_code) && (EventCode == ((unsigned)event_table->native_events[eidx].libpfm4_idx))) {
749 break;
750 }
751 }
752
753 // if we did not find a match, return an error
754 if (eidx < 0) {
755 // If we did not find a match in our native event table, then the code passed in has not been
756 // allocated yet It should not be possible to get to this code. The user has to call the papi
757 // code_to_name api with a papi event code for a native event. But the only way to get one of
758 // those is to call either name_to_code or enum_cmp_events first. When one of these calls is
759 // done we allocate the event so it should always be there.
760
761 SUBDBG("EXIT: PAPI_ENOEVNT\n");
762 return PAPI_ENOEVNT;
763 }
764
765 edesc = event_table->native_events[eidx].event_description;
766
767 // if it will not fit, return error
768 if (strlen (edesc) >= (unsigned)len) {
769 SUBDBG("EXIT: event name %s will not fit in buffer provided\n", edesc);
770 return PAPI_EBUF;
771 }
772 strcpy (ntv_descr, edesc);
773
774 // if this event had masks, also add their descriptions
775 mdesc = event_table->native_events[eidx].mask_description;
776 if ((mdesc != NULL) && (strlen(mdesc) > 0)) {
777 if ((strlen(edesc) + 8 + strlen(mdesc)) >= (unsigned)len) {
778 SUBDBG("EXIT: Not enough room for event and mask descriptions: need: %u, have: %u", (unsigned)(strlen(edesc) + 8 + strlen(mdesc)), (unsigned)len);
779 return PAPI_EBUF;
780 }
781 strcat (ntv_descr, ", masks:");
782 strcat (ntv_descr, mdesc);
783 }
784
785 SUBDBG("EXIT: event description: %s\n", ntv_descr);
786 return PAPI_OK;
787}
#define PAPI_EBUF
Definition: f90papi.h:253
unsigned int _papi_hwi_get_papi_event_code()
Here is the call graph for this function:

◆ _pe_libpfm4_ntv_code_to_info()

int _pe_libpfm4_ntv_code_to_info ( unsigned int  EventCode,
PAPI_event_info_t info,
struct native_event_table_t event_table 
)

Definition at line 791 of file pe_libpfm4_events.c.

794{
795 SUBDBG("ENTER: EventCode: %#x, info: %p, event_table: %p\n", EventCode, info, event_table);
796
797 int ret;
798
799 // get the event name first
800 if ((ret = _pe_libpfm4_ntv_code_to_name(EventCode, info->symbol, sizeof(info->symbol), event_table)) != PAPI_OK) {
801 SUBDBG("EXIT: _pe_libpfm4_ntv_code_to_name returned: %d\n", ret);
802 return PAPI_ENOEVNT;
803 }
804
805 if ((ret = _pe_libpfm4_ntv_code_to_descr(EventCode, info->long_descr, sizeof(info->long_descr), event_table)) != PAPI_OK) {
806 SUBDBG("EXIT: _pe_libpfm4_ntv_code_to_descr returned: %d\n", ret);
807 return PAPI_ENOEVNT;
808 }
809
810 SUBDBG("EXIT: EventCode: %#x, name: %s, desc: %s\n", EventCode, info->symbol, info->long_descr);
811 return PAPI_OK;
812}
Take an event code and convert it to a description.
Take an event code and convert it to a name.
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:960
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:963
Here is the caller graph for this function:

◆ _pe_libpfm4_ntv_code_to_name()

int _pe_libpfm4_ntv_code_to_name ( unsigned int  EventCode,
char *  name,
int  len,
struct native_event_table_t event_table 
)

Definition at line 632 of file pe_libpfm4_events.c.

635{
636 SUBDBG("ENTER: EventCode: %#x, ntv_name: %p, len: %d, event_table: %p\n", EventCode, ntv_name, len, event_table);
637
638 int eidx;
639 int papi_event_code;
640
641 // get the attribute index for this papi event
642 papi_event_code = _papi_hwi_get_papi_event_code();
643
644 // a papi event code less than 0 is invalid, return error
645 if (papi_event_code <= 0) {
646 SUBDBG("EXIT: PAPI_ENOEVNT\n");
647 return PAPI_ENOEVNT;
648 }
649
650 // find our native event table for this papi event code (search list backwards because it improves chances of finding it quickly)
651 for (eidx=event_table->num_native_events-1 ; eidx>=0 ; eidx--) {
652 if ((papi_event_code == event_table->native_events[eidx].papi_event_code) && (EventCode == ((unsigned)event_table->native_events[eidx].libpfm4_idx))) {
653 SUBDBG("Found native_event[%d]: papi_event_code: %#x, libpfm4_idx: %#x\n", eidx, event_table->native_events[eidx].papi_event_code, event_table->native_events[eidx].libpfm4_idx);
654 break;
655 }
656 }
657
658 // if we did not find a match, return an error
659 if (eidx < 0) {
660 // If we did not find a match in our native event table, then the code passed in has not been
661 // allocated yet It should not be possible to get to this code. The user has to call the papi
662 // code_to_name api with a papi event code for a native event. But the only way to get one of
663 // those is to call either name_to_code or enum_cmp_events first. When one of these calls is
664 // done we allocate the event so it should always be there.
665
666 SUBDBG("EXIT: PAPI_ENOEVNT\n");
667 return PAPI_ENOEVNT;
668 }
669
670 // if this event is defined by the default pmu, then use only the event name
671 // if it is not defined by the default pmu, then use both the pmu name and event name
672 char *ename;
673 if ((event_table->default_pmu.name) && (strcmp(event_table->default_pmu.name, event_table->native_events[eidx].pmu) == 0)) {
674 ename = event_table->native_events[eidx].base_name;
675 } else {
676 ename = event_table->native_events[eidx].pmu_plus_name;
677 }
678
679 // if it will not fit, return error
680 if (strlen (ename) >= (unsigned)len) {
681 SUBDBG("EXIT: event name %s will not fit in buffer provided\n", ename);
682 return PAPI_EBUF;
683 }
684 strcpy (ntv_name, ename);
685
686 // if this event had masks, also add their names
687 char *mname = event_table->native_events[eidx].mask_string;
688 if ((mname != NULL) && (strlen(mname) > 0)) {
689 if ((strlen(ename) + 8 + strlen(mname)) >= (unsigned)len) {
690 SUBDBG("EXIT: Not enough room for event and mask descriptions: need: %u, have: %u", (unsigned)(strlen(ename) + 8 + strlen(mname)), (unsigned)len);
691 return PAPI_EBUF;
692 }
693 strcat (ntv_name, ":");
694 strcat (ntv_name, mname);
695 }
696
697 SUBDBG("EXIT: event name: %s\n", ntv_name);
698 return PAPI_OK;
699}
Here is the call graph for this function:

◆ _pe_libpfm4_ntv_enum_events()

int _pe_libpfm4_ntv_enum_events ( unsigned int EventCode,
int  modifier,
int  cidx,
struct native_event_table_t event_table 
)

Definition at line 832 of file pe_libpfm4_events.c.

834 {
835
836 SUBDBG("ENTER: PapiEventCode: %p, *PapiEventCode: %#x, modifier: %d, event_table: %p\n", PapiEventCode, *PapiEventCode, modifier, event_table);
837
838 int code,ret, pnum;
839 int max_umasks;
840 char event_string[BUFSIZ];
841 pfm_pmu_info_t pinfo;
842 pfm_event_info_t einfo;
843 struct native_event_t *our_event;
844
845 /* return first event if so specified */
846 if ( modifier == PAPI_ENUM_FIRST ) {
847 attr_idx = 0; // set so if they want attribute information, it will start with the first attribute
848 code=get_first_event_next_pmu(-1, event_table->pmu_type);
849 if (code < 0 ) {
850 SUBDBG("EXIT: Invalid component first event code: %d\n", code);
851 return code;
852 }
853
854 // get the event information from libpfm4 (must zero structure)
855 memset( &einfo, 0, sizeof( pfm_event_info_t ));
856 einfo.size = sizeof(pfm_event_info_t);
857 if ((ret = pfm_get_event_info(code, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
858 SUBDBG("EXIT: pfm_get_event_info returned: %d\n", ret);
859 return PAPI_ENOIMPL;
860 }
861
862 // get the pmu information from libpfm4 (must zero structure)
863 memset( &pinfo, 0, sizeof(pfm_pmu_info_t) );
864 pinfo.size = sizeof(pfm_pmu_info_t);
865 ret=pfm_get_pmu_info(einfo.pmu, &pinfo);
866 if (ret!=PFM_SUCCESS) {
867 SUBDBG("EXIT: pfm_get_pmu_info returned: %d\n", ret);
868 return ret;
869 }
870
871 // build full event name
872 sprintf (event_string, "%s::%s", pinfo.name, einfo.name);
873 SUBDBG("code: %#x, pmu: %s, event: %s, event_string: %s\n", code, pinfo.name, einfo.name, event_string);
874
875 // go allocate this event, need to create tables used by the get event info call that will probably follow
876 if ((our_event = allocate_native_event(event_string, code, cidx, event_table)) == NULL) {
877 // allocate may have created the event table but returned NULL to tell the caller the event string was invalid (attempt to encode it failed).
878 // if the caller wants to use this event to count something, it will report an error
879 // but if the caller is just interested in listing the event, then we need an event table with an event name and libpfm4 index
880 int evt_idx;
881 if ((evt_idx = find_existing_event(event_string, event_table)) < 0) {
882 SUBDBG("EXIT: Allocating event: '%s' failed\n", event_string);
883 return PAPI_ENOEVNT;
884 }
885
886 // give back the new event code
887 *PapiEventCode = event_table->native_events[evt_idx].libpfm4_idx;
888 SUBDBG("EXIT: event code: %#x\n", *PapiEventCode);
889 return PAPI_OK;
890 }
891
892 *PapiEventCode = our_event->libpfm4_idx;
893
894 SUBDBG("EXIT: *PapiEventCode: %#x\n", *PapiEventCode);
895 return PAPI_OK;
896 }
897
898 /* Handle looking for the next event */
899 if ( modifier == PAPI_ENUM_EVENTS ) {
900 attr_idx = 0; // set so if they want attribute information, it will start with the first attribute
901
902 // get the next event code from libpfm4, if there are no more in this pmu find first event in next pmu
903 if ((code = pfm_get_event_next(*PapiEventCode)) < 0) {
904
905 // get this events information from libpfm4, we need the pmu number of the last event we processed (table must be cleared)
906 memset( &einfo, 0, sizeof( pfm_event_info_t ));
907 einfo.size = sizeof(pfm_event_info_t);
908 if ((ret = pfm_get_event_info(*PapiEventCode, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
909 SUBDBG("EXIT: pfm_get_event_info returned: %d\n", ret);
910 return PAPI_ENOIMPL;
911 }
912 SUBDBG("*PapiEventCode: %#x, event: %s\n", *PapiEventCode, einfo.name);
913
914 // get the pmu number of the last event
915 pnum = einfo.pmu;
916
917 SUBDBG("pnum: %d\n", pnum);
918 code=get_first_event_next_pmu(pnum, event_table->pmu_type);
919 if (code < 0) {
920 SUBDBG("EXIT: No more PMUs to list, returning: %d\n", code);
921 return code;
922 }
923 }
924
925
926 // get the event information from libpfm4 (must zero structure)
927 memset( &einfo, 0, sizeof( pfm_event_info_t ));
928 einfo.size = sizeof(pfm_event_info_t);
929 if ((ret = pfm_get_event_info(code, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
930 SUBDBG("EXIT: pfm_get_event_info returned: %d\n", ret);
931 return PAPI_ENOIMPL;
932 }
933
934 // get the pmu information from libpfm4 (must zero structure)
935 memset( &pinfo, 0, sizeof(pfm_pmu_info_t) );
936 pinfo.size = sizeof(pfm_pmu_info_t);
937 ret=pfm_get_pmu_info(einfo.pmu, &pinfo);
938 if (ret!=PFM_SUCCESS) {
939 SUBDBG("EXIT: pfm_get_pmu_info returned: %d\n", ret);
940 return ret;
941 }
942
943 // build full event name
944 sprintf (event_string, "%s::%s", pinfo.name, einfo.name);
945 SUBDBG("code: %#x, pmu: %s, event: %s, event_string: %s\n", code, pinfo.name, einfo.name, event_string);
946
947 // go allocate this event, need to create tables used by the get event info call that will follow
948 if ((our_event = allocate_native_event(event_string, code, cidx, event_table)) == NULL) {
949 // allocate may have created the event table but returned NULL to tell the caller the event string was invalid (attempt to encode it failed).
950 // if the caller wants to use this event to count something, it will report an error
951 // but if the caller is just interested in listing the event, then we need an event table with an event name and libpfm4 index
952 int evt_idx;
953 if ((evt_idx = find_existing_event(event_string, event_table)) < 0) {
954 SUBDBG("EXIT: Allocating event: '%s' failed\n", event_string);
955 return PAPI_ENOEVNT;
956 }
957
958 // give back the new event code
959 *PapiEventCode = event_table->native_events[evt_idx].libpfm4_idx;
960 SUBDBG("EXIT: event code: %#x\n", *PapiEventCode);
961 return PAPI_OK;
962 }
963
964 // give back the new event code
965 *PapiEventCode = our_event->libpfm4_idx;
966
967 SUBDBG("EXIT: *PapiEventCode: %#x\n", *PapiEventCode);
968 return PAPI_OK;
969 }
970
971 /* We don't handle PAPI_NTV_ENUM_UMASK_COMBOS */
972 if ( modifier == PAPI_NTV_ENUM_UMASK_COMBOS ) {
973 SUBDBG("EXIT: do not support umask combos yet\n");
974 return PAPI_ENOIMPL;
975 }
976
977 /* Enumerate PAPI_NTV_ENUM_UMASKS (umasks on an event) */
978 if ( modifier == PAPI_NTV_ENUM_UMASKS ) {
979 // get this events information from libpfm4, we need the number of masks this event knows about (table must be cleared)
980 memset( &einfo, 0, sizeof( pfm_event_info_t ));
981 einfo.size = sizeof(pfm_event_info_t);
982 if ((ret = pfm_get_event_info(*PapiEventCode, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
983 SUBDBG("EXIT: pfm_get_event_info returned: %d\n", ret);
984 return PAPI_ENOIMPL;
985 }
986// SUBDBG("*PapiEventCode: %#x, einfo.name: %s, einfo.code: %#x, einfo.nattrs: %d\n", *PapiEventCode, einfo.name, einfo.code, einfo.nattrs);
987
988 // set max number of masks
989 max_umasks = einfo.nattrs;
990
991 // if we reached last attribute, return error to show we are done with this events masks
992 if (attr_idx == max_umasks) {
993 SUBDBG("EXIT: already processed all umasks: attr_idx: %d\n", attr_idx);
994 return PAPI_ENOEVNT;
995 }
996
997 // find the event table for this event, we need the pmu name and event name without any masks
999 if (ntv_idx < 0) {
1000 SUBDBG("EXIT: _papi_hwi_get_ntv_idx returned: %d\n", ntv_idx);
1001 return ntv_idx;
1002 }
1003 char *ename = event_table->native_events[ntv_idx].pmu_plus_name;
1004 if ((ename == NULL) || (strlen(ename) >= sizeof(event_string))) {
1005 SUBDBG("EXIT: Event name will not fit into buffer\n");
1006 return PAPI_EBUF;
1007 }
1008 strcpy (event_string, ename);
1009 SUBDBG("event_string: %s\n", event_string);
1010
1011 // go get the attribute information for this event
1012 // libpfm4 likes the table cleared
1013 pfm_event_attr_info_t ainfo;
1014 memset (&ainfo, 0, sizeof(pfm_event_attr_info_t));
1015 ainfo.size = sizeof(pfm_event_attr_info_t);
1016 ret = pfm_get_event_attr_info(*PapiEventCode, attr_idx, PFM_OS_PERF_EVENT_EXT, &ainfo);
1017 if (ret != PFM_SUCCESS) {
1018 SUBDBG("EXIT: Attribute info not found, EventCode: %#x, attr_idx: %d, ret: %d\n", *PapiEventCode, attr_idx, _papi_libpfm4_error(ret));
1019 return _papi_libpfm4_error(ret);
1020 }
1021 SUBDBG("*PapiEventCode: %#x, attr_idx: %d, type: %d, name: %s, description: %s\n", *PapiEventCode, attr_idx, ainfo.type, ainfo.name, ainfo.desc);
1022
1023 if (strlen(event_string) + strlen(ainfo.name) + 35 > sizeof(event_string)) {
1024 SUBDBG("EXIT: Event name and mask will not fit into buffer\n");
1025 return PAPI_EBUF;
1026 }
1027
1028 strcat (event_string, ":");
1029 strcat (event_string, ainfo.name);
1030 switch (ainfo.type) {
1031 case PFM_ATTR_UMASK:
1032 break;
1033 case PFM_ATTR_MOD_BOOL:
1034 case PFM_ATTR_MOD_INTEGER:
1035 // a few attributes require a non-zero value to encode correctly (most would accept zero here)
1036 strcat(event_string,"=0");
1037 break;
1038 default:
1039 SUBDBG("EXIT: Unsupported attribute type: %d", ainfo.type);
1040 return PAPI_EATTR;
1041 }
1042
1043 // go allocate this event, need to create tables used by the get event info call that will follow
1044 if ((our_event = allocate_native_event(event_string, *PapiEventCode, cidx, event_table)) == NULL) {
1045 // allocate may have created the event table but returned NULL to tell the caller the event string was invalid.
1046 // if the caller wants to use this event to count something, it must report the error
1047 // but if the caller is just interested in listing the event (like this code), then find the table that was created and return its libpfm4 index
1048 int evt_idx;
1049 if ((evt_idx = find_existing_event(event_string, event_table)) < 0) {
1050 SUBDBG("EXIT: Allocating event: '%s' failed\n", event_string);
1051 return PAPI_ENOEVNT;
1052 }
1053 // bump so next time we will use next attribute
1054 attr_idx++;
1055 // give back the new event code
1056 *PapiEventCode = event_table->native_events[evt_idx].libpfm4_idx;
1057 SUBDBG("EXIT: event code: %#x\n", *PapiEventCode);
1058 return PAPI_OK;
1059 }
1060
1061 // bump so next time we will use next attribute
1062 attr_idx++;
1063
1064 // give back the new event code
1065 *PapiEventCode = our_event->libpfm4_idx;
1066
1067 SUBDBG("EXIT: event code: %#x\n", *PapiEventCode);
1068 return PAPI_OK;
1069 }
1070
1071 /* Enumerate PAPI_NTV_ENUM_GROUPS (groups on an event) */
1072 if ( modifier == PAPI_NTV_ENUM_GROUPS ) {
1073 SUBDBG("EXIT: do not support enumerating groups in this component\n");
1074 return PAPI_ENOIMPL;
1075 }
1076
1077 /* An unknown enumeration method was indicated */
1078
1079 SUBDBG("EXIT: Invalid modifier argument provided\n");
1080 return PAPI_ENOIMPL;
1081}
convert libpfm error codes to PAPI error codes
Allocates a native event.
looks up an event, returns it if it exists
return the first available event that's on an active PMU
#define PAPI_ENUM_EVENTS
Definition: f90papi.h:224
#define PAPI_NTV_ENUM_UMASK_COMBOS
Definition: f90papi.h:108
#define PAPI_ENUM_FIRST
Definition: f90papi.h:85
#define PAPI_NTV_ENUM_UMASKS
Definition: f90papi.h:66
#define PAPI_EATTR
Definition: f90papi.h:97
#define PAPI_ENOIMPL
Definition: f90papi.h:219
@ PAPI_NTV_ENUM_GROUPS
Definition: papi.h:514
int _papi_hwi_get_ntv_idx(unsigned int papi_evt_code)
static int attr_idx
Here is the call graph for this function:

◆ _pe_libpfm4_ntv_name_to_code()

int _pe_libpfm4_ntv_name_to_code ( const char *  ntv_name,
unsigned int EventCode,
int  cidx,
struct native_event_table_t event_table 
)

Definition at line 582 of file pe_libpfm4_events.c.

585{
586 SUBDBG( "ENTER: name: %s, event_code: %p, *event_code: %#x, event_table: %p\n", name, event_code, *event_code, event_table);
587
588 struct native_event_t *our_event;
589 int event_num;
590
591 // if we already know this event name, just return its native code
592 event_num=find_existing_event(name, event_table);
593 if (event_num >= 0) {
594 *event_code=event_table->native_events[event_num].libpfm4_idx;
595 // the following call needs to happen to prevent the internal layer from creating a new papi native event table
597 SUBDBG("EXIT: Found papi_event_code: %#x, libpfm4_idx: %#x\n", event_table->native_events[event_num].papi_event_code, event_table->native_events[event_num].libpfm4_idx);
598 return PAPI_OK;
599 }
600
601 // Try to allocate this event to see if it is known by libpfm4, if allocate fails tell the caller it is not valid
602 our_event=allocate_native_event(name, -1, cidx, event_table);
603 if (our_event==NULL) {
604 SUBDBG("EXIT: Allocating event: '%s' failed\n", name);
605 return PAPI_ENOEVNT;
606 }
607
608 *event_code = our_event->libpfm4_idx;
609 SUBDBG("EXIT: Found code: %#x\n",*event_code);
610 return PAPI_OK;
611}
void _papi_hwi_set_papi_event_code(unsigned int event_code, int update_flag)
const char * name
Definition: rocs.c:225
Here is the call graph for this function:

◆ _pe_libpfm4_setup_presets()

int _pe_libpfm4_setup_presets ( char *  name,
int  type,
int  cidx 
)

◆ _pe_libpfm4_shutdown()

int _pe_libpfm4_shutdown ( papi_vector_t my_vector,
struct native_event_table_t event_table 
)

Definition at line 1095 of file pe_libpfm4_events.c.

1096 {
1097 SUBDBG("ENTER: event_table: %p\n", event_table);
1098
1099 int i;
1100
1101 for (i=0 ; i<PAPI_PMU_MAX ; i++) {
1102 if (my_vector->cmp_info.pmu_names[i] != NULL) {
1103 free (my_vector->cmp_info.pmu_names[i]);
1104 }
1105 }
1106
1107 /* clean out and free the native events structure */
1109
1110 /* free memory allocated with strdup or malloc */
1111 for( i=0; i<event_table->num_native_events; i++) {
1112 free(event_table->native_events[i].base_name);
1113 free(event_table->native_events[i].pmu_plus_name);
1114 free(event_table->native_events[i].pmu);
1115 free(event_table->native_events[i].allocated_name);
1116 free(event_table->native_events[i].mask_string);
1117 free(event_table->native_events[i].event_description);
1118 if (event_table->native_events[i].mask_description != NULL) {
1119 free(event_table->native_events[i].mask_description);
1120 }
1121 }
1122
1123 free(event_table->native_events);
1124
1126
1127 SUBDBG("EXIT: PAPI_OK\n");
1128 return PAPI_OK;
1129}
#define NAMELIB_LOCK
Definition: papi_internal.h:93
char * pmu_names[PAPI_PMU_MAX]
Definition: papi.h:648
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
inline_static int _papi_hwi_lock(int lck)
Definition: threads.h:69
inline_static int _papi_hwi_unlock(int lck)
Definition: threads.h:83
Here is the call graph for this function:

◆ _peu_libpfm4_init()

int _peu_libpfm4_init ( papi_vector_t my_vector,
int  cidx,
struct native_event_table_t event_table,
int  pmu_type 
)

Definition at line 1318 of file pe_libpfm4_events.c.

1320 {
1321
1322 int detected_pmus=0;
1323 int i;
1324 int j=0;
1325 pfm_err_t retval = PFM_SUCCESS;
1326 unsigned int ncnt;
1327 pfm_pmu_info_t pinfo;
1328
1329 (void)cidx;
1330
1331 /* allocate the native event structure */
1332
1333 event_table->num_native_events=0;
1334 event_table->pmu_type=pmu_type;
1335
1336 event_table->native_events=calloc(NATIVE_EVENT_CHUNK,
1337 sizeof(struct native_event_t));
1338 if (event_table->native_events==NULL) {
1339 return PAPI_ENOMEM;
1340 }
1342
1343 /* Count number of present PMUs */
1344 detected_pmus=0;
1345 ncnt=0;
1346
1347 my_vector->cmp_info.num_cntrs=0;
1348
1349 SUBDBG("Detected pmus:\n");
1350 i=0;
1351 while(1) {
1352 memset(&pinfo,0,sizeof(pfm_pmu_info_t));
1353 pinfo.size = sizeof(pfm_pmu_info_t);
1354 retval=pfm_get_pmu_info(i, &pinfo);
1355
1356 /* We're done if we hit an invalid PMU entry */
1357 /* We can't check against PFM_PMU_MAX */
1358 /* as that might not match if libpfm4 is dynamically linked */
1359
1360 if (retval==PFM_ERR_INVAL) {
1361 break;
1362 }
1363
1364 if ((retval==PFM_SUCCESS) && (pinfo.name != NULL) &&
1365 (pmu_is_present_and_right_type(&pinfo,pmu_type))) {
1366
1367 SUBDBG("\t%d %s %s %d\n",i,pinfo.name,pinfo.desc,pinfo.type);
1368
1369 detected_pmus++;
1370 ncnt+=pinfo.nevents;
1371
1372 if ((j < PAPI_PMU_MAX) && (pinfo.name != NULL)) {
1373 my_vector->cmp_info.pmu_names[j++] = strdup(pinfo.name);
1374 }
1375 my_vector->cmp_info.num_cntrs += pinfo.num_cntrs+
1376 pinfo.num_fixed_cntrs;
1377 }
1378 i++;
1379 }
1380 SUBDBG("%d native events detected on %d pmus\n",ncnt,detected_pmus);
1381
1382 my_vector->cmp_info.num_native_events = ncnt;
1383
1384 SUBDBG( "num_counters: %d\n", my_vector->cmp_info.num_cntrs );
1385
1386 return PAPI_OK;
1387}
Here is the call graph for this function: