Skip to content

Commit 8553e73

Browse files
Add functionality for user specified PAPI events
This allows user to specify their own PAPI events (up to MAXNPAPICNTRS, defaulting to 4). This is done with the DR_HOOK_PAPI_COUNTERS flag. If the flag is not specified, and PAPI is enabled, then the following defaults will be chosen: PAPI_TOT_CYC PAPI_FP_OPS PAPI_L1_DCA PAPI_L2_DCM If an invalid event is chosen, then DrHook will simply crash will an appropriate error message.
1 parent 8e0a9e2 commit 8553e73

File tree

4 files changed

+108
-45
lines changed

4 files changed

+108
-45
lines changed

src/fiat/drhook/drhook.c

+52-7
Original file line numberDiff line numberDiff line change
@@ -2609,7 +2609,7 @@ process_options()
26092609
opt_cpuprof = 0; /* Note: Switches cpuprof OFF */
26102610
opt_calls = 1;
26112611
opt_cycles = 1;
2612-
opt_papi = 1;
2612+
opt_papi = 1;
26132613
OPTPRINT(fp,"%s%s",comma,"COUNTERS"); comma = ",";
26142614
}
26152615
else if (strequ(p,"CPUPROF")) {
@@ -2687,6 +2687,45 @@ process_options()
26872687
OPTPRINT(fp,"%s %s [%s@%s:%d] DR_HOOK_CALLTRACE=%d\n",pfx,TIMESTR(tid),FFL,opt_calltrace);
26882688
}
26892689

2690+
#if defined(DR_HOOK_HAVE_PAPI)
2691+
if (opt_papi) {
2692+
newline = 0;
2693+
env = getenv("DR_HOOK_PAPI_COUNTERS");
2694+
if (env) {
2695+
const char delim[] = ", \t/";
2696+
char *comma = " DR_HOOK_PAPI_COUNTERS=\"";
2697+
char *s = strdup_drhook(env);
2698+
char *p = s;
2699+
while (*p) {
2700+
if (islower(*p)) *p = toupper(*p);
2701+
p++;
2702+
}
2703+
p = strtok(s,delim);
2704+
for (int i = 0; p && i < drhook_papi_max_num_counters(); p = strtok(NULL,delim), i++) {
2705+
drhook_papi_add_counter_name(strdup_drhook(p));
2706+
OPTPRINT(fp,"%s%s",comma,p); comma = ",";
2707+
}
2708+
2709+
free_drhook(s);
2710+
if (*comma == ',') {
2711+
OPTPRINT(fp,"\"\n");
2712+
newline = 0;
2713+
}
2714+
if (newline) OPTPRINT(fp,"\n");
2715+
} else {
2716+
const char* default_events[4] = {
2717+
"PAPI_TOT_CYC",
2718+
"PAPI_FP_OPS",
2719+
"PAPI_L1_DCA",
2720+
"PAPI_L2_DCM"
2721+
};
2722+
for (int i = 0; i < 4; i++) {
2723+
drhook_papi_add_counter_name(strdup_drhook(default_events[i]));
2724+
}
2725+
}
2726+
}
2727+
#endif
2728+
26902729
if (opt_wallprof || opt_cpuprof || opt_memprof || opt_timeline) {
26912730
atexit(do_prof);
26922731
}
@@ -4585,15 +4624,21 @@ c_drhook_print_(const int *ftnunitno,
45854624
if (opt_papi){
45864625
p=prof;
45874626
int first_counter_is_cyc=0;
4588-
if (strcmp(drhook_papi_counter_name(0,0),"PAPI_TOT_CYC")==0)
4627+
char event_name[drhook_papi_max_name_len()];
4628+
drhook_papi_counter_name(0,event_name);
4629+
if (strcmp(event_name,"PAPI_TOT_CYC")==0)
45894630
first_counter_is_cyc=1;
45904631
{
45914632
len =
45924633
fprintf(fpcsv,"Routine,MPI Rank,ThreadId,SelfRank,%% Self Time,Cumul,Excl Time,Incl. Time,#Calls");
4593-
for (int c=0;c<drhook_papi_num_counters();c++)
4594-
fprintf(fpcsv,",%s(excl)",drhook_papi_counter_name(c,1));
4595-
for (int c=0;c<drhook_papi_num_counters();c++)
4596-
fprintf(fpcsv,",%s(incl)",drhook_papi_counter_name(c,1));
4634+
for (int c=0;c<drhook_papi_num_counters();c++){
4635+
drhook_papi_counter_name(c,event_name);
4636+
fprintf(fpcsv,",%s(excl)",event_name);
4637+
}
4638+
for (int c=0;c<drhook_papi_num_counters();c++) {
4639+
drhook_papi_counter_name(c,event_name);
4640+
fprintf(fpcsv,",%s(incl)",event_name);
4641+
}
45974642
if (first_counter_is_cyc==1)
45984643
fprintf(fpcsv,",Mcyc/sec(excl),Mcyc/sec(incl)");
45994644
fprintf(fpcsv,"\n");
@@ -4603,7 +4648,7 @@ c_drhook_print_(const int *ftnunitno,
46034648
for (j=0; j<nprof; ) {
46044649
int cluster_size = clusize[p->cluster];
46054650
if (opt_cputime)
4606-
cumul += p->self;
4651+
cumul += p->self;
46074652
else
46084653
if (p->is_max || cluster_size == 1) cumul += p->self;
46094654

src/fiat/drhook/drhook_papi.c

+48-33
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,9 @@ enum {
1919
int drhook_papi_state=drhook_papi_notstarted;
2020
int drhook_papi_rank=0; /* C style! */
2121

22-
/* hardwired for now */
23-
const char* hookCounters[NPAPICNTRS][2]= {
24-
{"PAPI_TOT_CYC","Cycles"},
25-
{"PAPI_FP_OPS","FP Operations"},
26-
{"PAPI_L1_DCA","L1 Access"},
27-
{"PAPI_L2_DCM","L2 Miss"}
28-
};
22+
static int papi_counter_event_codes[MAXNPAPICNTRS];
23+
static char* papi_counter_names[MAXNPAPICNTRS];
24+
static int papi_counters_count;
2925

3026
/* function to use for thread id
3127
- it should be better than omp_get_thread_num!
@@ -34,8 +30,16 @@ unsigned long safe_thread_num(){
3430
return oml_my_thread()-1;
3531
}
3632

37-
const char* drhook_papi_counter_name(int c,int t){
38-
return hookCounters[c][t];
33+
int drhook_papi_max_num_counters() {
34+
return MAXNPAPICNTRS;
35+
}
36+
37+
int drhook_papi_max_name_len() {
38+
return PAPI_MAX_STR_LEN;
39+
}
40+
41+
void drhook_papi_counter_name(int c, char* event_name){
42+
PAPI_event_code_to_name(papi_counter_event_codes[c], event_name);
3943
}
4044

4145
void drhook_papi_cpy(long_long* a,long_long* b){
@@ -56,8 +60,12 @@ void drhook_papi_print(char* s, long_long* a, int header){
5660
char fmt[STD_MSG_LEN];
5761
sprintf(fmt,"%%%lds",strlen(s));
5862
sprintf(msg,fmt," ");
59-
for (int i=0;i<drhook_papi_num_counters();i++)
60-
sprintf(&msg[strlen(msg)]," %16s",hookCounters[ i ][1]);
63+
for (int i=0;i<drhook_papi_num_counters();i++) {
64+
char event_name[PAPI_MAX_STR_LEN];
65+
66+
PAPI_event_code_to_name(papi_counter_event_codes[i], event_name);
67+
sprintf(&msg[strlen(msg)]," %16s",event_name);
68+
}
6169
printf("%s\n",msg);
6270
}
6371

@@ -94,7 +102,12 @@ void drhook_papi_add(long_long* a,long_long* b, long_long* c){
94102

95103
// number of counters available to read
96104
int drhook_papi_num_counters(){
97-
return NPAPICNTRS;
105+
return papi_counters_count;
106+
}
107+
108+
void drhook_papi_add_counter_name(const char* counter_name) {
109+
papi_counter_names[papi_counters_count] = counter_name;
110+
papi_counters_count++;
98111
}
99112

100113
long_long drhook_papi_read(int counterId){
@@ -205,12 +218,14 @@ int drhook_papi_init(int rank){
205218

206219
drhook_papi_event_set=malloc(nthreads*sizeof(int));
207220

208-
int prof_papi_numcntrs;
209-
bool failed=false;
210-
211-
drhook_run_omp_parallel_papi_startup(drhook_papi_event_set,nthreads);
212-
213-
/* if (failed){ drhook_papi_state=drhook_papi_failed ; return 0;} */
221+
int rcout;
222+
drhook_run_omp_parallel_papi_startup(drhook_papi_event_set,nthreads, &rcout);
223+
if (rcout)
224+
return 0;
225+
226+
for (int i=0; i < drhook_papi_max_num_counters(); i++)
227+
free(papi_counter_names[i]);
228+
214229
drhook_papi_state=drhook_papi_running;
215230
if (drhook_papi_rank==0 && !silent) printf("DRHOOK:PAPI: Initialisation sucess\n");
216231
return 1;
@@ -231,42 +246,42 @@ int dr_hook_papi_start_threads(int* events){
231246

232247
if (!silent) printf("DRHOOK:PAPI: Event set %d created for thread %d\n",events[thread],thread);
233248

234-
int prof_papi_numcntrs=NPAPICNTRS;
235249
if (!silent && drhook_papi_rank==0 && thread==0)
236250
printf("DRHOOK:PAPI: Attempting to add events to event set:\n");
237251

238-
for (int counter=0; counter < prof_papi_numcntrs; counter ++){
252+
for (int counter=0; counter < drhook_papi_num_counters(); counter ++){
239253
int eventCode;
240254

241255
if (!silent && drhook_papi_rank==0 && thread==0) {
242-
snprintf(pmsg,STD_MSG_LEN,"DRHOOK:PAPI: %s (%s)",hookCounters[counter][0],hookCounters[counter][1]);
256+
snprintf(pmsg,STD_MSG_LEN,"DRHOOK:PAPI: %s", papi_counter_names[counter]);
243257
printf("%s\n",pmsg);
244258
}
245259

246-
papiErr=PAPI_event_name_to_code(hookCounters[counter][0],&eventCode);
260+
papiErr=PAPI_event_name_to_code(papi_counter_names[counter], &eventCode);
247261
if (papiErr != PAPI_OK){
248-
snprintf(pmsg,STD_MSG_LEN,"DRHOOK:PAPI: Error, event name to code failed (%s)",PAPI_strerror(papiErr));
262+
snprintf(pmsg,STD_MSG_LEN,"DRHOOK:PAPI: Error, event name to code failed for %s (%s)", papi_counter_names[counter], PAPI_strerror(papiErr));
249263
printf("%s\n",pmsg);
250264
PAPI_perror("initPapi");
251265
return 0;
252266
}
253267

268+
papi_counter_event_codes[counter] = eventCode;
254269
papiErr=PAPI_add_event(events[thread],eventCode);
255270
if (papiErr!=PAPI_OK){
256271
snprintf(pmsg,STD_MSG_LEN,"DRHOOK:PAPI: Error, add_event failed: %d (%s)",papiErr,PAPI_strerror(papiErr));
257272
printf("%s\n",pmsg);
258273
if (papiErr == PAPI_EINVAL)
259-
printf("Invalid argument");
274+
printf("Invalid argument\n");
260275
else if (papiErr == PAPI_ENOMEM)
261-
printf("Out of memory");
276+
printf("Out of memory\n");
262277
else if (papiErr == PAPI_ENOEVST)
263-
printf("EventSet does not exist");
278+
printf("EventSet does not exist\n");
264279
else if (papiErr == PAPI_EISRUN)
265-
printf("EventSet is running");
280+
printf("EventSet is running\n");
266281
else if (papiErr == PAPI_ECNFLCT)
267-
printf("Conflict");
282+
printf("Conflict\n");
268283
else if (papiErr == PAPI_ENOEVNT)
269-
printf("Preset not available");
284+
printf("Preset not available\n");
270285
return 0;
271286
}
272287
else {
@@ -279,8 +294,8 @@ int dr_hook_papi_start_threads(int* events){
279294
}
280295
}
281296

282-
int number = prof_papi_numcntrs;
283-
int* checkEvents=malloc(prof_papi_numcntrs*sizeof(int));
297+
int number = drhook_papi_num_counters();
298+
int* checkEvents=malloc(drhook_papi_num_counters()*sizeof(int));
284299
papiErr = PAPI_list_events(events[thread], checkEvents, &number);
285300
if (papiErr != PAPI_OK){
286301
snprintf(pmsg,STD_MSG_LEN,"DRHOOK:PAPI: Error querying events - %d=%s",papiErr,PAPI_strerror(papiErr));
@@ -294,8 +309,8 @@ int dr_hook_papi_start_threads(int* events){
294309
}
295310
#endif
296311

297-
if (number != prof_papi_numcntrs){
298-
snprintf(pmsg,STD_MSG_LEN,"DRHOOK:PAPI: Error checking events - expected=%d got=%d",prof_papi_numcntrs,number);
312+
if (number != drhook_papi_num_counters()){
313+
snprintf(pmsg,STD_MSG_LEN,"DRHOOK:PAPI: Error checking events - expected=%d got=%d",drhook_papi_num_counters(),number);
299314
printf("%s\n",pmsg);
300315
}
301316

src/fiat/drhook/drhook_papi.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@
44

55
#include <papi.h>
66

7-
#define NPAPICNTRS 4
7+
#define MAXNPAPICNTRS 4
88

99
int drhook_papi_init(int rank);
1010
int drhook_papi_num_counters();
11-
const char* drhook_papi_counter_name(int c,int t);
11+
int drhook_papi_max_num_counters();
12+
void drhook_papi_counter_name(int c, char* event_name);
13+
void drhook_papi_add_counter_name(const char* counter_name);
1214
long_long drhook_papi_read(int counterId);
1315
int drhook_papi_readAll(long_long * counterArray);
1416

1517
/* implemented in forrtran */
16-
int drhook_run_omp_parallel_papi_startup(int * drhook_papi_event_set,int nthreads);
18+
int drhook_run_omp_parallel_papi_startup(int * drhook_papi_event_set,int nthreads, int* rcout);
1719

1820
/* a = b - c
1921
if b or c == NULL means use current readings

src/fiat/drhook/internal/drhook_run_omp_parallel.F90

+3-2
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,16 @@ end subroutine drhook_run_omp_parallel_get_cycles
7676

7777
#if defined(DR_HOOK_HAVE_PAPI)
7878

79-
subroutine drhook_run_omp_parallel_papi_startup(events,n) bind(c)
79+
subroutine drhook_run_omp_parallel_papi_startup(events,n, rcOut) bind(c)
8080
use, intrinsic :: iso_c_binding, only : c_char, c_int, c_double
8181
use drhook_papi_interface
8282
use OML_MOD
8383
implicit none
8484
INTEGER(KIND=C_INT), INTENT(INOUT) :: Events(n)
8585
INTEGER(KIND=C_INT), VALUE, INTENT(IN) :: n
8686
INTEGER(KIND=C_INT) :: thread
87-
INTEGER(KIND=C_INT) :: rc,rcOut
87+
INTEGER(KIND=C_INT) :: rc
88+
INTEGER(KIND=C_INT), INTENT(OUT) :: rcOut
8889
INTEGER :: myThread
8990
INTEGER :: nThreads
9091

0 commit comments

Comments
 (0)