|
Packit |
577717 |
/****************************/
|
|
Packit |
577717 |
/* THIS IS OPEN SOURCE CODE */
|
|
Packit |
577717 |
/****************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* @file papi_hl.c
|
|
Packit |
577717 |
* @author Philip Mucci
|
|
Packit |
577717 |
* mucci@cs.utk.edu
|
|
Packit |
577717 |
* @author Kevin London
|
|
Packit |
577717 |
* london@cs.utk.edu
|
|
Packit |
577717 |
* @author dan terpstra
|
|
Packit |
577717 |
* terpstra@cs.utk.edu
|
|
Packit |
577717 |
* @brief This file contains the 'high level' interface to PAPI.
|
|
Packit |
577717 |
* BASIC is a high level language. ;-) */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "papi.h"
|
|
Packit |
577717 |
#include "papi_internal.h"
|
|
Packit |
577717 |
#include "papi_memory.h"
|
|
Packit |
577717 |
#include <string.h>
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* high level papi functions*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Which high-level interface are we using?
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
#define HL_STOP 0
|
|
Packit |
577717 |
#define HL_START 1
|
|
Packit |
577717 |
#define HL_FLIP 2
|
|
Packit |
577717 |
#define HL_FLOP 3
|
|
Packit |
577717 |
#define HL_IPC 4
|
|
Packit |
577717 |
#define HL_EPC 5
|
|
Packit |
577717 |
#define HL_READ 6
|
|
Packit |
577717 |
#define HL_ACCUM 7
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/** \internal
|
|
Packit |
577717 |
* This is stored per thread
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
typedef struct _HighLevelInfo
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int EventSet; /**< EventSet of the thread */
|
|
Packit |
577717 |
short int num_evts; /**< number of events in the eventset */
|
|
Packit |
577717 |
short int running; /**< STOP, START, or RATE */
|
|
Packit |
577717 |
long long initial_real_time; /**< Start real time */
|
|
Packit |
577717 |
long long initial_proc_time; /**< Start processor time */
|
|
Packit |
577717 |
long long last_real_time; /**< Previous value of real time */
|
|
Packit |
577717 |
long long last_proc_time; /**< Previous value of processor time */
|
|
Packit |
577717 |
long long total_ins; /**< Total instructions */
|
|
Packit |
577717 |
} HighLevelInfo;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int _hl_rate_calls( float *real_time, float *proc_time, int *events,
|
|
Packit |
577717 |
long long *values, long long *ins, float *rate, int mode );
|
|
Packit |
577717 |
void _internal_cleanup_hl_info( HighLevelInfo * state );
|
|
Packit |
577717 |
int _internal_check_state( HighLevelInfo ** state );
|
|
Packit |
577717 |
int _internal_start_hl_counters( HighLevelInfo * state );
|
|
Packit |
577717 |
int _internal_hl_read_cnts( long long *values, int array_len, int flag );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* CHANGE LOG:
|
|
Packit |
577717 |
- ksl 10/17/03
|
|
Packit |
577717 |
Pretty much a complete rewrite of the high level interface. Now
|
|
Packit |
577717 |
the interface is thread safe and you don't have to worry as much
|
|
Packit |
577717 |
about mixing the various high level calls.
|
|
Packit |
577717 |
|
|
Packit |
577717 |
- dkt 11/19/01:
|
|
Packit |
577717 |
After much discussion with users and developers, removed FMA and SLOPE
|
|
Packit |
577717 |
fudge factors. SLOPE was not being used, and we decided the place to
|
|
Packit |
577717 |
apply FMA was at a higher level where there could be a better understanding
|
|
Packit |
577717 |
of platform discrepancies and code implications.
|
|
Packit |
577717 |
ALL PAPI CALLS NOW RETURN EXACTLY WHAT THE HARDWARE REPORTS
|
|
Packit |
577717 |
- dkt 08/14/01:
|
|
Packit |
577717 |
Added reinitialization of values and proc_time to new reinit code.
|
|
Packit |
577717 |
Added SLOPE and FMA constants to correct for systemic errors on a
|
|
Packit |
577717 |
platform-by-platform basis.
|
|
Packit |
577717 |
SLOPE is a factor subtracted from flpins on each call to compensate
|
|
Packit |
577717 |
for platform overhead in the call.
|
|
Packit |
577717 |
FMA is a shifter that doubles floating point counts on platforms that
|
|
Packit |
577717 |
count FMA as one op instead of two.
|
|
Packit |
577717 |
NOTE: We are making the FLAWED assumption that ALL flpins are FMA!
|
|
Packit |
577717 |
This will result in counts that are TOO HIGH on the affected platforms
|
|
Packit |
577717 |
in instances where the code is NOT mostly FMA.
|
|
Packit |
577717 |
- dkt 08/01/01:
|
|
Packit |
577717 |
NOTE: Calling semantics have changed!
|
|
Packit |
577717 |
Now, if flpins < 0 (an invalid value) a PAPI_reset is issued to reset the
|
|
Packit |
577717 |
counter values. The internal start time is also reset. This should be a
|
|
Packit |
577717 |
benign change, exept in the rare case where a user passes an uninitialized
|
|
Packit |
577717 |
(and possibly negative) value for flpins to the routine *AFTER* it has been
|
|
Packit |
577717 |
called the first time. This is unlikely, since the first call clears and
|
|
Packit |
577717 |
returns th is value.
|
|
Packit |
577717 |
- dkt 08/01/01:
|
|
Packit |
577717 |
Internal sequencing changes:
|
|
Packit |
577717 |
-- initial PAPI_get_real_usec() call moved above PAPI_start to avoid unwanted flops.
|
|
Packit |
577717 |
-- PAPI_accum() replaced with PAPI_start() / PAPI_stop pair for same reason.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/** @internal
|
|
Packit |
577717 |
* This function is called to determine the state of the system.
|
|
Packit |
577717 |
* We may as well set the HighLevelInfo so you don't have to look it
|
|
Packit |
577717 |
* up again.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_internal_check_state( HighLevelInfo ** outgoing )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
HighLevelInfo *state = NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Only allow one thread at a time in here */
|
|
Packit |
577717 |
if ( init_level == PAPI_NOT_INITED ) {
|
|
Packit |
577717 |
retval = PAPI_library_init( PAPI_VER_CURRENT );
|
|
Packit |
577717 |
if ( retval != PAPI_VER_CURRENT ) {
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
_papi_hwi_lock( HIGHLEVEL_LOCK );
|
|
Packit |
577717 |
init_level = PAPI_HIGH_LEVEL_INITED;
|
|
Packit |
577717 |
_papi_hwi_unlock( HIGHLEVEL_LOCK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Do we have the thread specific data setup yet?
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
if ( ( retval =
|
|
Packit |
577717 |
PAPI_get_thr_specific( PAPI_HIGH_LEVEL_TLS, ( void ** ) &state ) )
|
|
Packit |
577717 |
!= PAPI_OK || state == NULL ) {
|
|
Packit |
577717 |
state = ( HighLevelInfo * ) papi_malloc( sizeof ( HighLevelInfo ) );
|
|
Packit |
577717 |
if ( state == NULL )
|
|
Packit |
577717 |
return ( PAPI_ENOMEM );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
memset( state, 0, sizeof ( HighLevelInfo ) );
|
|
Packit |
577717 |
state->EventSet = -1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( retval = PAPI_create_eventset( &state->EventSet ) ) != PAPI_OK )
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( retval =
|
|
Packit |
577717 |
PAPI_set_thr_specific( PAPI_HIGH_LEVEL_TLS,
|
|
Packit |
577717 |
state ) ) != PAPI_OK )
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
*outgoing = state;
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/** @internal
|
|
Packit |
577717 |
* Make sure to allocate space for values
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_internal_start_hl_counters( HighLevelInfo * state )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return ( PAPI_start( state->EventSet ) );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
_internal_cleanup_hl_info( HighLevelInfo * state )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
state->num_evts = 0;
|
|
Packit |
577717 |
state->running = HL_STOP;
|
|
Packit |
577717 |
state->initial_real_time = -1;
|
|
Packit |
577717 |
state->initial_proc_time = -1;
|
|
Packit |
577717 |
state->total_ins = 0;
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/** @class PAPI_flips
|
|
Packit |
577717 |
* @brief Simplified call to get Mflips/s (floating point instruction rate), real and processor time.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @par C Interface:
|
|
Packit |
577717 |
* \#include <papi.h> @n
|
|
Packit |
577717 |
* int PAPI_flips( float *rtime, float *ptime, long long *flpins, float *mflips );
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @param *rtime
|
|
Packit |
577717 |
* total realtime since the first call
|
|
Packit |
577717 |
* @param *ptime
|
|
Packit |
577717 |
* total process time since the first call
|
|
Packit |
577717 |
* @param *flpins
|
|
Packit |
577717 |
* total floating point instructions since the first call
|
|
Packit |
577717 |
* @param *mflips
|
|
Packit |
577717 |
* incremental (Mega) floating point instructions per seconds since the last call
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @retval PAPI_EINVAL
|
|
Packit |
577717 |
* The counters were already started by something other than PAPI_flips().
|
|
Packit |
577717 |
* @retval PAPI_ENOEVNT
|
|
Packit |
577717 |
* The floating point instructions event does not exist.
|
|
Packit |
577717 |
* @retval PAPI_ENOMEM
|
|
Packit |
577717 |
* Insufficient memory to complete the operation.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* The first call to PAPI_flips() will initialize the PAPI High Level interface,
|
|
Packit |
577717 |
* set up the counters to monitor the PAPI_FP_INS event and start the counters.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Subsequent calls will read the counters and return total real time,
|
|
Packit |
577717 |
* total process time, total floating point instructions since the start of the
|
|
Packit |
577717 |
* measurement and the Mflip/s rate since latest call to PAPI_flips().
|
|
Packit |
577717 |
* A call to PAPI_stop_counters() will stop the counters from running and then
|
|
Packit |
577717 |
* calls such as PAPI_start_counters() or other rate calls can safely be used.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* PAPI_flips returns information related to floating point instructions using
|
|
Packit |
577717 |
* the PAPI_FP_INS event. This is intended to measure instruction rate through the
|
|
Packit |
577717 |
* floating point pipe with no massaging.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @see PAPI_flops()
|
|
Packit |
577717 |
* @see PAPI_ipc()
|
|
Packit |
577717 |
* @see PAPI_epc()
|
|
Packit |
577717 |
* @see PAPI_stop_counters()
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
PAPI_flips( float *rtime, float *ptime, long long *flpins, float *mflips )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
int events[1] = {PAPI_FP_INS};
|
|
Packit |
577717 |
long long values = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( rtime == NULL || ptime == NULL || flpins == NULL || mflips == NULL )
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = _hl_rate_calls( rtime, ptime, events, &values, flpins, mflips, HL_FLIP );
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/** @class PAPI_flops
|
|
Packit |
577717 |
* @brief Simplified call to get Mflops/s (floating point operation rate), real and processor time.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @par C Interface:
|
|
Packit |
577717 |
* \#include <papi.h> @n
|
|
Packit |
577717 |
* int PAPI_flops( float *rtime, float *ptime, long long *flpops, float *mflops );
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @param *rtime
|
|
Packit |
577717 |
* total realtime since the first call
|
|
Packit |
577717 |
* @param *ptime
|
|
Packit |
577717 |
* total process time since the first call
|
|
Packit |
577717 |
* @param *flpops
|
|
Packit |
577717 |
* total floating point operations since the first call
|
|
Packit |
577717 |
* @param *mflops
|
|
Packit |
577717 |
* incremental (Mega) floating point operations per seconds since the last call
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @retval PAPI_EINVAL
|
|
Packit |
577717 |
* The counters were already started by something other than PAPI_flops().
|
|
Packit |
577717 |
* @retval PAPI_ENOEVNT
|
|
Packit |
577717 |
* The floating point operations event does not exist.
|
|
Packit |
577717 |
* @retval PAPI_ENOMEM
|
|
Packit |
577717 |
* Insufficient memory to complete the operation.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* The first call to PAPI_flops() will initialize the PAPI High Level interface,
|
|
Packit |
577717 |
* set up the counters to monitor the PAPI_FP_OPS event and start the counters.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Subsequent calls will read the counters and return total real time,
|
|
Packit |
577717 |
* total process time, total floating point operations since the start of the
|
|
Packit |
577717 |
* measurement and the Mflop/s rate since latest call to PAPI_flops().
|
|
Packit |
577717 |
* A call to PAPI_stop_counters() will stop the counters from running and then
|
|
Packit |
577717 |
* calls such as PAPI_start_counters() or other rate calls can safely be used.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* PAPI_flops returns information related to theoretical floating point operations
|
|
Packit |
577717 |
* rather than simple instructions. It uses the PAPI_FP_OPS event which attempts to
|
|
Packit |
577717 |
* 'correctly' account for, e.g., FMA undercounts and FP Store overcounts, etc.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @see PAPI_flips()
|
|
Packit |
577717 |
* @see PAPI_ipc()
|
|
Packit |
577717 |
* @see PAPI_epc()
|
|
Packit |
577717 |
* @see PAPI_stop_counters()
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
PAPI_flops( float *rtime, float *ptime, long long *flpops, float *mflops )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
int events[1] = {PAPI_FP_OPS};
|
|
Packit |
577717 |
long long values = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( rtime == NULL || ptime == NULL || flpops == NULL || mflops == NULL )
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = _hl_rate_calls( rtime, ptime, events, &values, flpops, mflops, HL_FLOP );
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/** @class PAPI_ipc
|
|
Packit |
577717 |
* @brief Simplified call to get instructions per cycle, real and processor time.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @par C Interface:
|
|
Packit |
577717 |
* \#include <papi.h> @n
|
|
Packit |
577717 |
* int PAPI_ipc( float *rtime, float *ptime, long long *ins, float *ipc );
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @param *rtime
|
|
Packit |
577717 |
* total realtime since the first call
|
|
Packit |
577717 |
* @param *ptime
|
|
Packit |
577717 |
* total process time since the first call
|
|
Packit |
577717 |
* @param *ins
|
|
Packit |
577717 |
* total instructions since the first call
|
|
Packit |
577717 |
* @param *ipc
|
|
Packit |
577717 |
* incremental instructions per cycle since the last call
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @retval PAPI_EINVAL
|
|
Packit |
577717 |
* The counters were already started by something other than PAPI_ipc().
|
|
Packit |
577717 |
* @retval PAPI_ENOEVNT
|
|
Packit |
577717 |
* The floating point operations event does not exist.
|
|
Packit |
577717 |
* @retval PAPI_ENOMEM
|
|
Packit |
577717 |
* Insufficient memory to complete the operation.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* The first call to PAPI_ipc() will initialize the PAPI High Level interface,
|
|
Packit |
577717 |
* set up the counters to monitor PAPI_TOT_INS and PAPI_TOT_CYC events
|
|
Packit |
577717 |
* and start the counters.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Subsequent calls will read the counters and return total real time,
|
|
Packit |
577717 |
* total process time, total instructions since the start of the
|
|
Packit |
577717 |
* measurement and the IPC rate since the latest call to PAPI_ipc().
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* A call to PAPI_stop_counters() will stop the counters from running and then
|
|
Packit |
577717 |
* calls such as PAPI_start_counters() or other rate calls can safely be used.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* PAPI_ipc should return a ratio greater than 1.0, indicating instruction level
|
|
Packit |
577717 |
* parallelism within the chip. The larger this ratio the more effeciently the program
|
|
Packit |
577717 |
* is running.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @see PAPI_flips()
|
|
Packit |
577717 |
* @see PAPI_flops()
|
|
Packit |
577717 |
* @see PAPI_epc()
|
|
Packit |
577717 |
* @see PAPI_stop_counters()
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
PAPI_ipc( float *rtime, float *ptime, long long *ins, float *ipc )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
long long values[2] = { 0, 0 };
|
|
Packit |
577717 |
int events[2] = {PAPI_TOT_INS, PAPI_TOT_CYC};
|
|
Packit |
577717 |
int retval = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( rtime == NULL || ptime == NULL || ins == NULL || ipc == NULL )
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = _hl_rate_calls( rtime, ptime, events, values, ins, ipc, HL_IPC );
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/** @class PAPI_epc
|
|
Packit |
577717 |
* @brief Simplified call to get arbitrary events per cycle, real and processor time.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @par C Interface:
|
|
Packit |
577717 |
* \#include <papi.h> @n
|
|
Packit |
577717 |
* int PAPI_epc( int event, float *rtime, float *ptime, long long *ref, long long *core, long long *evt, float *epc );
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @param event
|
|
Packit |
577717 |
* event code to be measured (0 defaults to PAPI_TOT_INS)
|
|
Packit |
577717 |
* @param *rtime
|
|
Packit |
577717 |
* total realtime since the first call
|
|
Packit |
577717 |
* @param *ptime
|
|
Packit |
577717 |
* total process time since the first call
|
|
Packit |
577717 |
* @param *ref
|
|
Packit |
577717 |
* incremental reference clock cycles since the last call
|
|
Packit |
577717 |
* @param *core
|
|
Packit |
577717 |
* incremental core clock cycles since the last call
|
|
Packit |
577717 |
* @param *evt
|
|
Packit |
577717 |
* total events since the first call
|
|
Packit |
577717 |
* @param *epc
|
|
Packit |
577717 |
* incremental events per cycle since the last call
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @retval PAPI_EINVAL
|
|
Packit |
577717 |
* The counters were already started by something other than PAPI_epc().
|
|
Packit |
577717 |
* @retval PAPI_ENOEVNT
|
|
Packit |
577717 |
* One of the requested events does not exist.
|
|
Packit |
577717 |
* @retval PAPI_ENOMEM
|
|
Packit |
577717 |
* Insufficient memory to complete the operation.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* The first call to PAPI_epc() will initialize the PAPI High Level interface,
|
|
Packit |
577717 |
* set up the counters to monitor the user specified event, PAPI_TOT_CYC,
|
|
Packit |
577717 |
* and PAPI_REF_CYC (if it exists) and start the counters.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Subsequent calls will read the counters and return total real time,
|
|
Packit |
577717 |
* total process time, total event counts since the start of the
|
|
Packit |
577717 |
* measurement and the core and reference cycle count and EPC rate since the
|
|
Packit |
577717 |
* latest call to PAPI_epc().
|
|
Packit |
577717 |
|
|
Packit |
577717 |
* A call to PAPI_stop_counters() will stop the counters from running and then
|
|
Packit |
577717 |
* calls such as PAPI_start_counters() or other rate calls can safely be used.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* PAPI_epc can provide a more detailed look at algorithm efficiency in light of clock
|
|
Packit |
577717 |
* variability in modern cpus. MFLOPS is no longer an adequate description of peak
|
|
Packit |
577717 |
* performance if clock rates can arbitrarily speed up or slow down. By allowing a
|
|
Packit |
577717 |
* user specified event and reporting reference cycles, core cycles and real time,
|
|
Packit |
577717 |
* PAPI_epc provides the information to compute an accurate effective clock rate, and
|
|
Packit |
577717 |
* an accurate measure of computational throughput.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @see PAPI_flips()
|
|
Packit |
577717 |
* @see PAPI_flops()
|
|
Packit |
577717 |
* @see PAPI_ipc()
|
|
Packit |
577717 |
* @see PAPI_stop_counters()
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
PAPI_epc( int event, float *rtime, float *ptime, long long *ref, long long *core, long long *evt, float *epc )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
long long values[3] = { 0, 0, 0 };
|
|
Packit |
577717 |
int events[3] = {PAPI_TOT_INS, PAPI_TOT_CYC, PAPI_REF_CYC};
|
|
Packit |
577717 |
int retval = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( rtime == NULL || ptime == NULL || ref == NULL ||core == NULL || evt == NULL || epc == NULL )
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// if an event is provided, use it; otherwise use TOT_INS
|
|
Packit |
577717 |
if (event != 0 ) events[0] = event;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( PAPI_query_event( ( int ) PAPI_REF_CYC ) != PAPI_OK )
|
|
Packit |
577717 |
events[2] = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = _hl_rate_calls( rtime, ptime, events, values, evt, epc, HL_EPC );
|
|
Packit |
577717 |
*core = values[1];
|
|
Packit |
577717 |
*ref = values[2];
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_hl_rate_calls( float *real_time, float *proc_time, int *events,
|
|
Packit |
577717 |
long long *values, long long *ins, float *rate, int mode )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
long long rt, pt; // current elapsed real and process times in usec
|
|
Packit |
577717 |
int num_events = 2;
|
|
Packit |
577717 |
int retval = 0;
|
|
Packit |
577717 |
HighLevelInfo *state = NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( retval = _internal_check_state( &state ) ) != PAPI_OK ) {
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( state->running != HL_STOP && state->running != mode ) {
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( state->running == HL_STOP ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
switch (mode) {
|
|
Packit |
577717 |
case HL_FLOP:
|
|
Packit |
577717 |
case HL_FLIP:
|
|
Packit |
577717 |
num_events = 1;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case HL_IPC:
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case HL_EPC:
|
|
Packit |
577717 |
if ( events[2] != 0 ) num_events = 3;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
default:
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (( retval = PAPI_add_events( state->EventSet, events, num_events )) != PAPI_OK ) {
|
|
Packit |
577717 |
_internal_cleanup_hl_info( state );
|
|
Packit |
577717 |
PAPI_cleanup_eventset( state->EventSet );
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
state->total_ins = 0;
|
|
Packit |
577717 |
state->initial_real_time = state->last_real_time = PAPI_get_real_usec( );
|
|
Packit |
577717 |
state->initial_proc_time = state->last_proc_time = PAPI_get_virt_usec( );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( retval = PAPI_start( state->EventSet ) ) != PAPI_OK ) {
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Initialize the interface */
|
|
Packit |
577717 |
state->running = mode;
|
|
Packit |
577717 |
*real_time = 0.0;
|
|
Packit |
577717 |
*proc_time = 0.0;
|
|
Packit |
577717 |
*rate = 0.0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
if ( ( retval = PAPI_stop( state->EventSet, values ) ) != PAPI_OK ) {
|
|
Packit |
577717 |
state->running = HL_STOP;
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Read elapsed real and process times */
|
|
Packit |
577717 |
rt = PAPI_get_real_usec();
|
|
Packit |
577717 |
pt = PAPI_get_virt_usec();
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Convert to seconds with multiplication because it is much faster */
|
|
Packit |
577717 |
*real_time = ((float)( rt - state->initial_real_time )) * .000001;
|
|
Packit |
577717 |
*proc_time = ((float)( pt - state->initial_proc_time )) * .000001;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
state->total_ins += values[0];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
switch (mode) {
|
|
Packit |
577717 |
case HL_FLOP:
|
|
Packit |
577717 |
case HL_FLIP:
|
|
Packit |
577717 |
/* Calculate MFLOP and MFLIP rates */
|
|
Packit |
577717 |
if ( pt > 0 ) {
|
|
Packit |
577717 |
*rate = (float)values[0] / (pt - state->last_proc_time);
|
|
Packit |
577717 |
} else *rate = 0;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case HL_IPC:
|
|
Packit |
577717 |
case HL_EPC:
|
|
Packit |
577717 |
/* Calculate IPC */
|
|
Packit |
577717 |
if (values[1]!=0) {
|
|
Packit |
577717 |
*rate = (float) ((float)values[0] / (float) ( values[1]));
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
default:
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
state->last_real_time = rt;
|
|
Packit |
577717 |
state->last_proc_time = pt;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( retval = PAPI_start( state->EventSet ) ) != PAPI_OK ) {
|
|
Packit |
577717 |
state->running = HL_STOP;
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
*ins = state->total_ins;
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/** @class PAPI_num_counters
|
|
Packit |
577717 |
* @brief Get the number of hardware counters available on the system.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @par C Interface:
|
|
Packit |
577717 |
* \#include <papi.h> @n
|
|
Packit |
577717 |
* int PAPI_num_counters( void );
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @post
|
|
Packit |
577717 |
* Initializes the library to PAPI_HIGH_LEVEL_INITED if necessary.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @retval PAPI_EINVAL
|
|
Packit |
577717 |
* papi.h is different from the version used to compile the PAPI library.
|
|
Packit |
577717 |
* @retval PAPI_ENOMEM
|
|
Packit |
577717 |
* Insufficient memory to complete the operation.
|
|
Packit |
577717 |
* @retval PAPI_ESYS
|
|
Packit |
577717 |
* A system or C library call failed inside PAPI, see the errno variable.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @par Examples:
|
|
Packit |
577717 |
* @code
|
|
Packit |
577717 |
* int num_hwcntrs;
|
|
Packit |
577717 |
* // The installation does not support PAPI
|
|
Packit |
577717 |
* if ((num_hwcntrs = PAPI_num_counters()) < 0 )
|
|
Packit |
577717 |
* handle_error(1);
|
|
Packit |
577717 |
* // The installation supports PAPI, but has no counters
|
|
Packit |
577717 |
* if ((num_hwcntrs = PAPI_num_counters()) == 0 )
|
|
Packit |
577717 |
* fprintf(stderr,"Info:: This machine does not provide hardware counters.\n");
|
|
Packit |
577717 |
* @endcode
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* PAPI_num_counters() returns the optimal length of the values array for the high level functions.
|
|
Packit |
577717 |
* This value corresponds to the number of hardware counters supported by the current CPU component.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @note This function only works for the CPU component. To determine the number of counters on
|
|
Packit |
577717 |
* another component, use the low level PAPI_num_cmp_hwctrs().
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
PAPI_num_counters( void )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
HighLevelInfo *tmp = NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Make sure the Library is initialized, etc... */
|
|
Packit |
577717 |
if ( ( retval = _internal_check_state( &tmp ) ) != PAPI_OK )
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( PAPI_get_opt( PAPI_MAX_HWCTRS, NULL ) );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/** @class PAPI_start_counters
|
|
Packit |
577717 |
* @brief Start counting hardware events.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @par C Interface:
|
|
Packit |
577717 |
* \#include <papi.h> @n
|
|
Packit |
577717 |
* int PAPI_start_counters( int *events, int array_len );
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @param *events
|
|
Packit |
577717 |
* an array of codes for events such as PAPI_INT_INS or a native event code
|
|
Packit |
577717 |
* @param array_len
|
|
Packit |
577717 |
* the number of items in the *events array
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @retval PAPI_EINVAL
|
|
Packit |
577717 |
* One or more of the arguments is invalid.
|
|
Packit |
577717 |
* @retval PAPI_EISRUN
|
|
Packit |
577717 |
* Counters have already been started, you must call PAPI_stop_counters()
|
|
Packit |
577717 |
* before you call this function again.
|
|
Packit |
577717 |
* @retval PAPI_ESYS
|
|
Packit |
577717 |
* A system or C library call failed inside PAPI, see the errno variable.
|
|
Packit |
577717 |
* @retval PAPI_ENOMEM
|
|
Packit |
577717 |
* Insufficient memory to complete the operation.
|
|
Packit |
577717 |
* @retval PAPI_ECNFLCT
|
|
Packit |
577717 |
* The underlying counter hardware cannot count this event and other events
|
|
Packit |
577717 |
* in the EventSet simultaneously.
|
|
Packit |
577717 |
* @retval PAPI_ENOEVNT
|
|
Packit |
577717 |
* The PAPI preset is not available on the underlying hardware.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* PAPI_start_counters() starts counting the events named in the *events array.
|
|
Packit |
577717 |
* This function cannot be called if the counters have already been started.
|
|
Packit |
577717 |
* The user must call PAPI_stop_counters() to stop the events explicitly if
|
|
Packit |
577717 |
* he/she wants to call this function again.
|
|
Packit |
577717 |
* It is the user's responsibility to choose events that can be counted
|
|
Packit |
577717 |
* simultaneously by reading the vendor's documentation.
|
|
Packit |
577717 |
* The length of the *events array should be no longer than the value returned
|
|
Packit |
577717 |
* by PAPI_num_counters().
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @code
|
|
Packit |
577717 |
if( PAPI_start_counters( Events, num_hwcntrs ) != PAPI_OK )
|
|
Packit |
577717 |
handle_error(1);
|
|
Packit |
577717 |
* @endcode
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @see PAPI_stop_counters() PAPI_add_event() PAPI_create_eventset()
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
PAPI_start_counters( int *events, int array_len )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int i, retval;
|
|
Packit |
577717 |
HighLevelInfo *state = NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( events == NULL || array_len <= 0 )
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( retval = _internal_check_state( &state ) ) != PAPI_OK )
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( state->running != 0 )
|
|
Packit |
577717 |
return ( PAPI_EINVAL );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* load events to the new EventSet */
|
|
Packit |
577717 |
for ( i = 0; i < array_len; i++ ) {
|
|
Packit |
577717 |
retval = PAPI_add_event( state->EventSet, events[i] );
|
|
Packit |
577717 |
if ( retval == PAPI_EISRUN )
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( retval ) {
|
|
Packit |
577717 |
/* remove any prior events that may have been added
|
|
Packit |
577717 |
* and cleanup the high level information
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
_internal_cleanup_hl_info( state );
|
|
Packit |
577717 |
PAPI_cleanup_eventset( state->EventSet );
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
/* start the EventSet */
|
|
Packit |
577717 |
if ( ( retval = _internal_start_hl_counters( state ) ) == PAPI_OK ) {
|
|
Packit |
577717 |
state->running = HL_START;
|
|
Packit |
577717 |
state->num_evts = ( short ) array_len;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*========================================================================*/
|
|
Packit |
577717 |
/* int PAPI_read_counters(long long *values, int array_len) */
|
|
Packit |
577717 |
/* */
|
|
Packit |
577717 |
/* Read the running counters into the values array. This call */
|
|
Packit |
577717 |
/* implicitly initializes the internal counters to zero and allows */
|
|
Packit |
577717 |
/* them continue to run upon return. */
|
|
Packit |
577717 |
/*========================================================================*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
_internal_hl_read_cnts( long long *values, int array_len, int flag )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
HighLevelInfo *state = NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( retval = _internal_check_state( &state ) ) != PAPI_OK )
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( state->running != HL_START || array_len < state->num_evts )
|
|
Packit |
577717 |
return ( PAPI_EINVAL );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( flag == HL_ACCUM )
|
|
Packit |
577717 |
return ( PAPI_accum( state->EventSet, values ) );
|
|
Packit |
577717 |
else if ( flag == HL_READ ) {
|
|
Packit |
577717 |
if ( ( retval = PAPI_read( state->EventSet, values ) ) != PAPI_OK )
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
return ( PAPI_reset( state->EventSet ) );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Invalid flag passed in */
|
|
Packit |
577717 |
return ( PAPI_EINVAL );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/** @class PAPI_read_counters
|
|
Packit |
577717 |
* @brief Read and reset counters.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @par C Interface:
|
|
Packit |
577717 |
* \#include <papi.h> @n
|
|
Packit |
577717 |
* int PAPI_read_counters( long long *values, int array_len );
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @param *values
|
|
Packit |
577717 |
* an array to hold the counter values of the counting events
|
|
Packit |
577717 |
* @param arry_len
|
|
Packit |
577717 |
* the number of items in the *events array
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @pre
|
|
Packit |
577717 |
* These calls assume an initialized PAPI library and a properly added event set.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @post
|
|
Packit |
577717 |
* The counters are reset and left running after the call.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @retval PAPI_EINVAL
|
|
Packit |
577717 |
* One or more of the arguments is invalid.
|
|
Packit |
577717 |
* @retval PAPI_ESYS
|
|
Packit |
577717 |
* A system or C library call failed inside PAPI, see the errno variable.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* PAPI_read_counters() copies the event counters into the array *values.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @code
|
|
Packit |
577717 |
do_100events();
|
|
Packit |
577717 |
if ( PAPI_read_counters( values, num_hwcntrs ) != PAPI_OK )
|
|
Packit |
577717 |
handlw_error(1);
|
|
Packit |
577717 |
// values[0] now equals 100
|
|
Packit |
577717 |
do_100events();
|
|
Packit |
577717 |
if ( PAPI_accum_counters( values, num_hwcntrs ) != PAPI_OK )
|
|
Packit |
577717 |
handle_error(1);
|
|
Packit |
577717 |
// values[0] now equals 200
|
|
Packit |
577717 |
values[0] = -100;
|
|
Packit |
577717 |
do_100events();
|
|
Packit |
577717 |
if ( PAPI_accum_counters(values, num_hwcntrs ) != PAPI_OK )
|
|
Packit |
577717 |
handle_error();
|
|
Packit |
577717 |
// values[0] now equals 0
|
|
Packit |
577717 |
* @endcode
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @see PAPI_set_opt() PAPI_start_counters()
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
PAPI_read_counters( long long *values, int array_len )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return ( _internal_hl_read_cnts( values, array_len, HL_READ ) );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/** @class PAPI_accum_counters
|
|
Packit |
577717 |
* @brief Accumulate and reset counters.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @par C Interface:
|
|
Packit |
577717 |
* \#include <papi.h> @n
|
|
Packit |
577717 |
* int PAPI_accum_counters( long long *values, int array_len );
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @param *values
|
|
Packit |
577717 |
* an array to hold the counter values of the counting events
|
|
Packit |
577717 |
* @param arry_len
|
|
Packit |
577717 |
* the number of items in the *events array
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @pre
|
|
Packit |
577717 |
* These calls assume an initialized PAPI library and a properly added event set.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @post
|
|
Packit |
577717 |
* The counters are reset and left running after the call.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @retval PAPI_EINVAL
|
|
Packit |
577717 |
* One or more of the arguments is invalid.
|
|
Packit |
577717 |
* @retval PAPI_ESYS
|
|
Packit |
577717 |
* A system or C library call failed inside PAPI, see the errno variable.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* PAPI_accum_counters() adds the event counters into the array *values.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @code
|
|
Packit |
577717 |
do_100events();
|
|
Packit |
577717 |
if ( PAPI_read_counters( values, num_hwcntrs ) != PAPI_OK )
|
|
Packit |
577717 |
handlw_error(1);
|
|
Packit |
577717 |
// values[0] now equals 100
|
|
Packit |
577717 |
do_100events();
|
|
Packit |
577717 |
if ( PAPI_accum_counters( values, num_hwcntrs ) != PAPI_OK )
|
|
Packit |
577717 |
handle_error(1);
|
|
Packit |
577717 |
// values[0] now equals 200
|
|
Packit |
577717 |
values[0] = -100;
|
|
Packit |
577717 |
do_100events();
|
|
Packit |
577717 |
if ( PAPI_accum_counters(values, num_hwcntrs ) != PAPI_OK )
|
|
Packit |
577717 |
handle_error();
|
|
Packit |
577717 |
// values[0] now equals 0
|
|
Packit |
577717 |
* @endcode
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @see PAPI_set_opt() PAPI_start_counters()
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
PAPI_accum_counters( long long *values, int array_len )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if ( values == NULL || array_len <= 0 )
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( _internal_hl_read_cnts( values, array_len, HL_ACCUM ) );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/** @class PAPI_stop_counters
|
|
Packit |
577717 |
* @brief Stop counting hardware events and reset values to zero.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @par C Interface:
|
|
Packit |
577717 |
* \#include <papi.h> @n
|
|
Packit |
577717 |
* int PAPI_stop_counters( long long *values, int array_len );
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @param *values
|
|
Packit |
577717 |
* an array where to put the counter values
|
|
Packit |
577717 |
* @param array_len
|
|
Packit |
577717 |
* the number of items in the *values array
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @post
|
|
Packit |
577717 |
* After this function is called, the values are reset to zero.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @retval PAPI_EINVAL
|
|
Packit |
577717 |
* One or more of the arguments is invalid.
|
|
Packit |
577717 |
* @retval PAPI_ENOTRUN
|
|
Packit |
577717 |
* The EventSet is not started yet.
|
|
Packit |
577717 |
* @retval PAPI_ENOEVST
|
|
Packit |
577717 |
* The EventSet has not been added yet.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* The PAPI_stop_counters() function stops the counters and copies the counts
|
|
Packit |
577717 |
* into the *values array.
|
|
Packit |
577717 |
* The counters must have been started by a previous call to PAPI_start_counters().
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* \code
|
|
Packit |
577717 |
int Events[2] = { PAPI_TOT_CYC, PAPI_TOT_INS };
|
|
Packit |
577717 |
long long values[2];
|
|
Packit |
577717 |
if ( PAPI_start_counters( Events, 2 ) != PAPI_OK )
|
|
Packit |
577717 |
handle_error(1);
|
|
Packit |
577717 |
your_slow_code();
|
|
Packit |
577717 |
if ( PAPI_stop_counters( values, 2 ) != PAPI_OK )
|
|
Packit |
577717 |
handle_error(1);
|
|
Packit |
577717 |
* \endcode
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @see PAPI_read_counters() PAPI_start_counters() PAPI_set_opt()
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
PAPI_stop_counters( long long *values, int array_len )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
HighLevelInfo *state = NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( retval = _internal_check_state( &state ) ) != PAPI_OK )
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( state->running == 0 )
|
|
Packit |
577717 |
return ( PAPI_ENOTRUN );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( state->running == HL_START ) {
|
|
Packit |
577717 |
if ( array_len < state->num_evts || values == NULL) {
|
|
Packit |
577717 |
return ( PAPI_EINVAL );
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
retval = PAPI_stop( state->EventSet, values );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( state->running > HL_START ) {
|
|
Packit |
577717 |
long long tmp_values[3];
|
|
Packit |
577717 |
retval = PAPI_stop( state->EventSet, tmp_values );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( retval == PAPI_OK ) {
|
|
Packit |
577717 |
_internal_cleanup_hl_info( state );
|
|
Packit |
577717 |
PAPI_cleanup_eventset( state->EventSet );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
APIDBG( "PAPI_stop_counters returns %d\n", retval );
|
|
Packit |
577717 |
return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
_papi_hwi_shutdown_highlevel( )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
HighLevelInfo *state = NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( PAPI_get_thr_specific( PAPI_HIGH_LEVEL_TLS, ( void ** ) &state ) ==
|
|
Packit |
577717 |
PAPI_OK ) {
|
|
Packit |
577717 |
if ( state )
|
|
Packit |
577717 |
papi_free( state );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|