void init_multiplex( void ) { int retval; const PAPI_hw_info_t *hw_info; const PAPI_component_info_t *cmpinfo; /* Initialize the library */ /* for now, assume multiplexing on CPU compnent only */ cmpinfo = PAPI_get_component_info( 0 ); if ( cmpinfo == NULL ) test_fail( __FILE__, __LINE__, "PAPI_get_component_info", 2 ); hw_info = PAPI_get_hardware_info( ); if ( hw_info == NULL ) test_fail( __FILE__, __LINE__, "PAPI_get_hardware_info", 2 ); if ( ( strstr( cmpinfo->name, "perfctr.c" ) ) && (hw_info !=NULL) && strcmp( hw_info->model_string, "POWER6" ) == 0 ) { retval = PAPI_set_domain( PAPI_DOM_ALL ); if ( retval != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_set_domain", retval ); } retval = PAPI_multiplex_init( ); if ( retval != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI multiplex init fail\n", retval ); }
int main( int argc, char **argv ) { int nthreads = 8, ret, i; PAPI_event_info_t info; pthread_t *threads; const PAPI_hw_info_t *hw_info; tests_quiet( argc, argv ); /* Set TESTS_QUIET variable */ if ( !TESTS_QUIET ) { if ( argc > 1 ) { int tmp = atoi( argv[1] ); if ( tmp >= 1 ) nthreads = tmp; } } ret = PAPI_library_init( PAPI_VER_CURRENT ); if ( ret != PAPI_VER_CURRENT ) { test_fail( __FILE__, __LINE__, "PAPI_library_init", ret ); } hw_info = PAPI_get_hardware_info( ); if ( hw_info == NULL ) test_fail( __FILE__, __LINE__, "PAPI_get_hardware_info", 2 ); if ( strcmp( hw_info->model_string, "POWER6" ) == 0 ) { ret = PAPI_set_domain( PAPI_DOM_ALL ); if ( ret != PAPI_OK ) { test_fail( __FILE__, __LINE__, "PAPI_set_domain", ret ); } } ret = PAPI_thread_init( ( unsigned long ( * )( void ) ) pthread_self ); if ( ret != PAPI_OK ) { test_fail( __FILE__, __LINE__, "PAPI_thread_init", ret ); } ret = PAPI_multiplex_init( ); if ( ret != PAPI_OK ) { test_fail( __FILE__, __LINE__, "PAPI_multiplex_init", ret ); } /* Fill up the event set with as many non-derived events as we can */ i = PAPI_PRESET_MASK; do { if ( PAPI_get_event_info( i, &info ) == PAPI_OK ) { if ( info.count == 1 ) { events[numevents++] = ( int ) info.event_code; printf( "Added %s\n", info.symbol ); } else { printf( "Skipping derived event %s\n", info.symbol ); } } } while ( ( PAPI_enum_event( &i, PAPI_PRESET_ENUM_AVAIL ) == PAPI_OK ) && ( numevents < PAPI_MPX_DEF_DEG ) ); printf( "Found %d events\n", numevents ); do_stuff( ); printf( "Creating %d threads:\n", nthreads ); threads = ( pthread_t * ) malloc( ( size_t ) nthreads * sizeof ( pthread_t ) ); if ( threads == NULL ) { test_fail( __FILE__, __LINE__, "malloc", PAPI_ENOMEM ); } /* Create the threads */ for ( i = 0; i < nthreads; i++ ) { ret = pthread_create( &threads[i], NULL, thread, NULL ); if ( ret != 0 ) { test_fail( __FILE__, __LINE__, "pthread_create", PAPI_ESYS ); } } /* Wait for thread completion */ for ( i = 0; i < nthreads; i++ ) { ret = pthread_join( threads[i], NULL ); if ( ret != 0 ) { test_fail( __FILE__, __LINE__, "pthread_join", PAPI_ESYS ); } } printf( "Done." ); test_pass( __FILE__, NULL, 0 ); pthread_exit( NULL ); exit( 0 ); }
/* ** GPTLcreate_and_start_events: Create and start the PAPI eventset. ** Threaded routine to create the "event set" (PAPI terminology) and start ** the counters. This is only done once, and is called from get_thread_num ** for the first time for the thread. ** ** Input args: ** t: thread number ** ** Return value: 0 (success) or GPTLerror (failure) */ int GPTLcreate_and_start_events (const int t) /* thread number */ { int ret; /* return code */ int n; /* loop index over events */ char eventname[PAPI_MAX_STR_LEN]; /* returned from PAPI_event_code_to_name */ static const char *thisfunc = "GPTLcreate_and_start_events"; /* ** Set the domain to count all contexts. Only needs to be set once for all threads */ if ((ret = PAPI_set_domain (PAPI_DOM_ALL)) != PAPI_OK) return GPTLerror ("%s: thread %d failure setting PAPI domain: %s\n", thisfunc, t, PAPI_strerror (ret)); /* Create the event set */ if ((ret = PAPI_create_eventset (&EventSet[t])) != PAPI_OK) return GPTLerror ("%s: thread %d failure creating eventset: %s\n", thisfunc, t, PAPI_strerror (ret)); if (verbose) printf ("%s: successfully created eventset for thread %d\n", thisfunc, t); /* Add requested events to the event set */ for (n = 0; n < npapievents; n++) { if ((ret = PAPI_add_event (EventSet[t], papieventlist[n])) != PAPI_OK) { if (verbose) { fprintf (stderr, "%s\n", PAPI_strerror (ret)); ret = PAPI_event_code_to_name (papieventlist[n], eventname); fprintf (stderr, "%s: failure adding event:%s\n", thisfunc, eventname); } if (enable_multiplexing) { if (verbose) printf ("Trying multiplexing...\n"); is_multiplexed = true; break; } else return GPTLerror ("enable_multiplexing is false: giving up\n"); } } if (is_multiplexed) { /* Cleanup the eventset for multiplexing */ if ((ret = PAPI_cleanup_eventset (EventSet[t])) != PAPI_OK) return GPTLerror ("%s: %s\n", thisfunc, PAPI_strerror (ret)); if ((ret = PAPI_destroy_eventset (&EventSet[t])) != PAPI_OK) return GPTLerror ("%s: %s\n", thisfunc, PAPI_strerror (ret)); if ((ret = PAPI_create_eventset (&EventSet[t])) != PAPI_OK) return GPTLerror ("%s: failure creating eventset: %s\n", thisfunc, PAPI_strerror (ret)); /* ** Assign EventSet to component 0 (cpu). This step is MANDATORY in recent PAPI releases ** in order to enable event multiplexing */ if ((ret = PAPI_assign_eventset_component (EventSet[t], 0)) != PAPI_OK) return GPTLerror ("%s: thread %d failure in PAPI_assign_eventset_component: %s\n", thisfunc, t, PAPI_strerror (ret)); if ((ret = PAPI_multiplex_init ()) != PAPI_OK) return GPTLerror ("%s: failure from PAPI_multiplex_init%s\n", thisfunc, PAPI_strerror (ret)); if ((ret = PAPI_set_multiplex (EventSet[t])) != PAPI_OK) return GPTLerror ("%s: failure from PAPI_set_multiplex: %s\n", thisfunc, PAPI_strerror (ret)); for (n = 0; n < npapievents; n++) { if ((ret = PAPI_add_event (EventSet[t], papieventlist[n])) != PAPI_OK) { ret = PAPI_event_code_to_name (papieventlist[n], eventname); return GPTLerror ("%s: failure adding event:%s Error was: %s\n", thisfunc, eventname, PAPI_strerror (ret)); } } } /* Start the event set. It will only be read from now on--never stopped */ if ((ret = PAPI_start (EventSet[t])) != PAPI_OK) return GPTLerror ("%s: failed to start event set: %s\n", thisfunc, PAPI_strerror (ret)); return 0; }
static int papi_internal_init(pmdaInterface *dp) { int ec; int sts; PAPI_event_info_t info; char entry[PAPI_HUGE_STR_LEN+12]; // the length papi uses for the symbol name unsigned int i = 0; pmID pmid; sts = sprintf(papi_version, "%d.%d.%d", PAPI_VERSION_MAJOR(PAPI_VERSION), PAPI_VERSION_MINOR(PAPI_VERSION), PAPI_VERSION_REVISION(PAPI_VERSION)); if (sts < 0) { __pmNotifyErr(LOG_ERR, "%s failed to create papi version metric.\n",pmProgname); return PM_ERR_GENERIC; } if ((sts = __pmNewPMNS(&papi_tree)) < 0) { __pmNotifyErr(LOG_ERR, "%s failed to create dynamic papi pmns: %s\n", pmProgname, pmErrStr(sts)); papi_tree = NULL; return PM_ERR_GENERIC; } number_of_counters = PAPI_num_counters(); if (number_of_counters < 0) { __pmNotifyErr(LOG_ERR, "hardware does not support performance counters\n"); return PM_ERR_APPVERSION; } else if (number_of_counters == 0) { __pmNotifyErr(LOG_WARNING, "no performance counters\n"); } sts = PAPI_library_init(PAPI_VER_CURRENT); if (sts != PAPI_VER_CURRENT) { __pmNotifyErr(LOG_ERR, "PAPI_library_init error (%d)\n", sts); return PM_ERR_GENERIC; } ec = PAPI_PRESET_MASK; PAPI_enum_event(&ec, PAPI_ENUM_FIRST); do { if (PAPI_get_event_info(ec, &info) == PAPI_OK) { if (info.count && PAPI_PRESET_ENUM_AVAIL) { expand_papi_info(i); memcpy(&papi_info[i].info, &info, sizeof(PAPI_event_info_t)); memcpy(&papi_info[i].papi_string_code, info.symbol + 5, strlen(info.symbol)-5); snprintf(entry, sizeof(entry),"papi.system.%s", papi_info[i].papi_string_code); pmid = pmid_build(dp->domain, CLUSTER_PAPI, i); papi_info[i].pmid = pmid; __pmAddPMNSNode(papi_tree, pmid, entry); memset(&entry[0], 0, sizeof(entry)); papi_info[i].position = -1; papi_info[i].metric_enabled = 0; expand_values(i); i++; } } } while(PAPI_enum_event(&ec, 0) == PAPI_OK); #if defined(HAVE_PAPI_DISABLED_COMP) char *tokenized_string; int number_of_components; int component_id; int native; number_of_components = PAPI_num_components(); native = 0 | PAPI_NATIVE_MASK; for (component_id = 0; component_id < number_of_components; component_id++) { const PAPI_component_info_t *component; component = PAPI_get_component_info(component_id); if (component->disabled || (strcmp("perf_event", component->name) && strcmp("perf_event_uncore", component->name))) continue; sts = PAPI_enum_cmp_event (&native, PAPI_ENUM_FIRST, component_id); if (sts == PAPI_OK) do { if (PAPI_get_event_info(native, &info) == PAPI_OK) { char local_native_metric_name[PAPI_HUGE_STR_LEN] = ""; int was_tokenized = 0; expand_papi_info(i); memcpy(&papi_info[i].info, &info, sizeof(PAPI_event_info_t)); tokenized_string = strtok(info.symbol, "::: -"); while (tokenized_string != NULL) { size_t remaining = sizeof(local_native_metric_name) - strlen(local_native_metric_name) - 1; if (remaining < 1) break; strncat(local_native_metric_name, tokenized_string, remaining); was_tokenized = 1; tokenized_string=strtok(NULL, "::: -"); if (tokenized_string) { remaining = sizeof(local_native_metric_name) - strlen(local_native_metric_name) - 1; if (remaining < 1) break; strncat(local_native_metric_name, ".", remaining); } } if (!was_tokenized) { strncpy(papi_info[i].papi_string_code, info.symbol, sizeof(papi_info[i].papi_string_code) - 1); } else { strncpy(papi_info[i].papi_string_code, local_native_metric_name, sizeof(papi_info[i].papi_string_code) - 1); } snprintf(entry, sizeof(entry),"papi.system.%s", papi_info[i].papi_string_code); pmid = pmid_build(dp->domain, CLUSTER_PAPI, i); papi_info[i].pmid = pmid; __pmAddPMNSNode(papi_tree, pmid, entry); memset(&entry[0], 0, sizeof(entry)); papi_info[i].position = -1; papi_info[i].metric_enabled = 0; expand_values(i); i++; } } while (PAPI_enum_cmp_event(&native, PAPI_ENUM_EVENTS, component_id) == PAPI_OK); } #endif pmdaTreeRebuildHash(papi_tree, number_of_events); /* Set one-time settings for all future EventSets. */ if ((sts = PAPI_set_domain(PAPI_DOM_ALL)) != PAPI_OK) { handle_papi_error(sts, 0); return PM_ERR_GENERIC; } if ((sts = PAPI_multiplex_init()) != PAPI_OK) { handle_papi_error(sts, 0); return PM_ERR_GENERIC; } sts = refresh_metrics(0); if (sts != PAPI_OK) return PM_ERR_GENERIC; return 0; }