/** @class PAPI_stop_counters * @brief Stop counting hardware events and reset values to zero. * * @par C Interface: * \#include <papi.h> @n * int PAPI_stop_counters( long long *values, int array_len ); * * @param *values * an array where to put the counter values * @param array_len * the number of items in the *values array * * @post * After this function is called, the values are reset to zero. * * @retval PAPI_EINVAL * One or more of the arguments is invalid. * @retval PAPI_ENOTRUN * The EventSet is not started yet. * @retval PAPI_ENOEVST * The EventSet has not been added yet. * * The PAPI_stop_counters() function stops the counters and copies the counts * into the *values array. * The counters must have been started by a previous call to PAPI_start_counters(). * * \code int Events[2] = { PAPI_TOT_CYC, PAPI_TOT_INS }; long long values[2]; if ( PAPI_start_counters( Events, 2 ) != PAPI_OK ) handle_error(1); your_slow_code(); if ( PAPI_stop_counters( values, 2 ) != PAPI_OK ) handle_error(1); * \endcode * * @see PAPI_read_counters() PAPI_start_counters() PAPI_set_opt() */ int PAPI_stop_counters( long long *values, int array_len ) { int retval; HighLevelInfo *state = NULL; if ( ( retval = _internal_check_state( &state ) ) != PAPI_OK ) return ( retval ); if ( state->running == 0 ) return ( PAPI_ENOTRUN ); if ( state->running == HL_START ) { if ( array_len < state->num_evts || values == NULL) { return ( PAPI_EINVAL ); } else { retval = PAPI_stop( state->EventSet, values ); } } if ( state->running > HL_START ) { long long tmp_values[3]; retval = PAPI_stop( state->EventSet, tmp_values ); } if ( retval == PAPI_OK ) { _internal_cleanup_hl_info( state ); PAPI_cleanup_eventset( state->EventSet ); } APIDBG( "PAPI_stop_counters returns %d\n", retval ); return retval; }
int PAPI_stop_counters(long long * values, int array_len) { int retval; HighLevelInfo *state = NULL; if ((retval = _internal_check_state(&state)) != PAPI_OK) return (retval); if (state->running == 0) return (PAPI_ENOTRUN); if (state->running == HL_FLOPS || state->running == HL_FLIPS || state->running == HL_IPC) { long long tmp_values[2]; retval = PAPI_stop(state->EventSet, tmp_values); } else if(state->running != HL_START_COUNTERS || array_len < state->num_evts) return (PAPI_EINVAL); else retval = PAPI_stop(state->EventSet, values); if (retval==PAPI_OK) { _internal_cleanup_hl_info(state); PAPI_cleanup_eventset(state->EventSet); } APIDBG("PAPI_stop_counters returns %d\n", retval); return retval; }
int PAPI_start_counters(int *events, int array_len) { int i, retval; HighLevelInfo *state = NULL; if ((retval = _internal_check_state(&state)) != PAPI_OK) return (retval); if(state->running != 0) return(PAPI_EINVAL); /* load events to the new EventSet */ for (i = 0; i < array_len; i++) { retval = PAPI_add_event(state->EventSet, events[i]); if (retval == PAPI_EISRUN) return (retval); if (retval) { /* remove any prior events that may have been added * and cleanup the high level information */ _internal_cleanup_hl_info(state); PAPI_cleanup_eventset(state->EventSet); return (retval); } } /* start the EventSet */ if ((retval = _internal_start_hl_counters(state)) == PAPI_OK) { state->running = HL_START_COUNTERS; state->num_evts = array_len; } return (retval); }
int PAPI_ipc(float *rtime, float *ptime, long long * ins, float *ipc) { HighLevelInfo *state = NULL; int retval; if ((retval = _internal_check_state(&state)) != PAPI_OK) return (retval); return(_hl_rate_calls(rtime,ptime,ins,ipc,PAPI_TOT_INS,state)); }
/* * How many hardware counters does this platform support? */ int PAPI_num_counters(void) { int retval; HighLevelInfo *tmp = NULL; /* Make sure the Library is initialized, etc... */ if ((retval = _internal_check_state(&tmp)) != PAPI_OK) return (retval); return (PAPI_get_opt(PAPI_MAX_HWCTRS, NULL)); }
int PAPI_flops(float *rtime, float *ptime, long long * flpops, float *mflops) { HighLevelInfo *state = NULL; int retval; if ((retval = _internal_check_state(&state)) != PAPI_OK) return (retval); if ((retval = _hl_rate_calls(rtime, ptime, flpops, mflops, PAPI_FP_OPS, state)) != PAPI_OK) return (retval); return (PAPI_OK); }
/** @class PAPI_ipc * @brief Get instructions per cycle, real and processor time. * * @par C Interface: * \#include <papi.h> @n * int PAPI_ipc( float *rtime, float *ptime, long long *ins, float *ipc ); * * @param *rtime * total realtime since the first PAPI_flops() call * @param *ptime * total process time since the first PAPI_flops() call * @param *ins * total instructions since the first call * @param *ipc * instructions per cycle achieved since the previous call * * @retval PAPI_EINVAL * The counters were already started by something other than: PAPI_ipc() * @retval PAPI_ENOEVNT * The total instructions or total cycles event does not exist. * @retval PAPI_ENOMEM * Insufficient memory to complete the operation. * * The first call to PAPI_ipc() will initialize the PAPI High Level interface, * set up the counters to monitor PAPI_TOT_INS and PAPI_TOT_CYC events * and start the counters. * Subsequent calls will read the counters and return total real time, * total process time, total instructions since the start of the measurement * and the instructions per cycle rate since latest call to PAPI_ipc(). * A call to PAPI_stop_counters() will stop the counters from running and then * calls such as PAPI_start_counters() can safely be used. * * @see PAPI_flops() PAPI_stop_counters() PAPI_set_opt() PAPI_flips() */ int PAPI_ipc( float *rtime, float *ptime, long long *ins, float *ipc ) { if ( rtime == NULL || ptime == NULL || ins == NULL || ipc == NULL ) return PAPI_EINVAL; HighLevelInfo *state = NULL; int retval; if ( ( retval = _internal_check_state( &state ) ) != PAPI_OK ) return ( retval ); return _hl_rate_calls( rtime, ptime, ins, ipc, ( unsigned int ) PAPI_TOT_INS, state ); }
/** @class PAPI_flops * @brief Simplified call to get Mflops/s (floating point instruction rate), real and processor time. * * @par C Interface: * \#include <papi.h> @n * int PAPI_flops( float *rtime, float *ptime, long long *flpops, float *mflops ); * * @param *rtime * total realtime since the first PAPI_flops() call * @param *ptime * total process time since the first PAPI_flops() call * @param *flpins * total floating point instructions since the first call * @param *rtime * total realtime since the first PAPI_flops() call * @param *ptime * total process time since the first PAPI_flops() call * @param *flpops * total floating point instructions since the first call * * @retval PAPI_EINVAL * The counters were already started by something other than: PAPI_flips() or PAPI_flops(). * @retval PAPI_ENOEVNT * The floating point operations, floating point instructions or total cycles * event does not exist. * @retval PAPI_ENOMEM * Insufficient memory to complete the operation. * * The first call to PAPI_flops() will initialize the PAPI High Level interface, * set up the counters to monitor PAPI_FP_OPS and PAPI_TOT_CYC events * and start the counters. * Subsequent calls will read the counters and return total real time, * total process time, total floating point instructions since the start of the * measurement and the Mflop/s rate since latest call to PAPI_flops(). * A call to PAPI_stop_counters() will stop the counters from running and then * calls such as PAPI_start_counters() can safely be used. * * @internal * The next three calls all use _hl_rate_calls() to return an instruction rate value. * PAPI_flops returns information related to floating point instructions using * the PAPI_FP_INS event. This is intended to measure instruction rate through the * floating point pipe with no massaging. * PAPI_flops return information related to theoretical floating point operations * rather than simple instructions. It uses the PAPI_FP_OPS event which attempts to * 'correctly' account for, e.g., FMA undercounts and FP Store overcounts, etc. * * @see PAPI_stop_counters() PAPI_ipc() PAPI_set_opt() */ int PAPI_flops( float *rtime, float *ptime, long long *flpops, float *mflops ) { if ( rtime == NULL || ptime == NULL || flpops == NULL || mflops == NULL ) return PAPI_EINVAL; HighLevelInfo *state = NULL; int retval; if ( ( retval = _internal_check_state( &state ) ) != PAPI_OK ) return ( retval ); if ( ( retval = _hl_rate_calls( rtime, ptime, flpops, mflops, ( unsigned int ) PAPI_FP_OPS, state ) ) != PAPI_OK ) return ( retval ); return ( PAPI_OK ); }
int _internal_hl_read_cnts(long long * values, int array_len, int flag) { int retval; HighLevelInfo *state = NULL; if ((retval = _internal_check_state(&state)) != PAPI_OK) return (retval); if (state->running != HL_START_COUNTERS || array_len < state->num_evts) return (PAPI_EINVAL); if (flag == PAPI_HL_ACCUM) return (PAPI_accum(state->EventSet, values)); else if (flag == PAPI_HL_READ) { if ((retval = PAPI_read(state->EventSet, values)) != PAPI_OK) return (retval); return (PAPI_reset(state->EventSet)); } /* Invalid flag passed in */ return (PAPI_EINVAL); }
int _hl_rate_calls( float *real_time, float *proc_time, int *events, long long *values, long long *ins, float *rate, int mode ) { long long rt, pt; // current elapsed real and process times in usec int num_events = 2; int retval = 0; HighLevelInfo *state = NULL; if ( ( retval = _internal_check_state( &state ) ) != PAPI_OK ) { return ( retval ); } if ( state->running != HL_STOP && state->running != mode ) { return PAPI_EINVAL; } if ( state->running == HL_STOP ) { switch (mode) { case HL_FLOP: case HL_FLIP: num_events = 1; break; case HL_IPC: break; case HL_EPC: if ( events[2] != 0 ) num_events = 3; break; default: return PAPI_EINVAL; } if (( retval = PAPI_add_events( state->EventSet, events, num_events )) != PAPI_OK ) { _internal_cleanup_hl_info( state ); PAPI_cleanup_eventset( state->EventSet ); return retval; } state->total_ins = 0; state->initial_real_time = state->last_real_time = PAPI_get_real_usec( ); state->initial_proc_time = state->last_proc_time = PAPI_get_virt_usec( ); if ( ( retval = PAPI_start( state->EventSet ) ) != PAPI_OK ) { return retval; } /* Initialize the interface */ state->running = mode; *real_time = 0.0; *proc_time = 0.0; *rate = 0.0; } else { if ( ( retval = PAPI_stop( state->EventSet, values ) ) != PAPI_OK ) { state->running = HL_STOP; return retval; } /* Read elapsed real and process times */ rt = PAPI_get_real_usec(); pt = PAPI_get_virt_usec(); /* Convert to seconds with multiplication because it is much faster */ *real_time = ((float)( rt - state->initial_real_time )) * .000001; *proc_time = ((float)( pt - state->initial_proc_time )) * .000001; state->total_ins += values[0]; switch (mode) { case HL_FLOP: case HL_FLIP: /* Calculate MFLOP and MFLIP rates */ if ( pt > 0 ) { *rate = (float)values[0] / (pt - state->last_proc_time); } else *rate = 0; break; case HL_IPC: case HL_EPC: /* Calculate IPC */ if (values[1]!=0) { *rate = (float) ((float)values[0] / (float) ( values[1])); } break; default: return PAPI_EINVAL; } state->last_real_time = rt; state->last_proc_time = pt; if ( ( retval = PAPI_start( state->EventSet ) ) != PAPI_OK ) { state->running = HL_STOP; return retval; } } *ins = state->total_ins; return PAPI_OK; }