Beispiel #1
0
/** @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);
}
Beispiel #7
0
/** @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 );
}
Beispiel #8
0
/** @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);
}
Beispiel #10
0
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;
}