Blame src/components/bgpm/NWunit/linux-NWunit.c

Packit 577717
/****************************/
Packit 577717
/* THIS IS OPEN SOURCE CODE */
Packit 577717
/****************************/
Packit 577717
Packit 577717
/** 
Packit 577717
 * @file    linux-NWunit.c
Packit 577717
 * @author  Heike Jagode
Packit 577717
 *          jagode@eecs.utk.edu
Packit 577717
 * Mods:	< your name here >
Packit 577717
 *			< your email address >
Packit 577717
 * BGPM / NWunit component 
Packit 577717
 * 
Packit 577717
 * Tested version of bgpm (early access)
Packit 577717
 *
Packit 577717
 * @brief
Packit 577717
 *  This file has the source code for a component that enables PAPI-C to 
Packit 577717
 *  access hardware monitoring counters for BG/Q through the bgpm library.
Packit 577717
 */
Packit 577717
Packit 577717
#include "linux-NWunit.h"
Packit 577717
Packit 577717
/* Declare our vector in advance */
Packit 577717
papi_vector_t _NWunit_vector;
Packit 577717
Packit 577717
/*****************************************************************************
Packit 577717
 *******************  BEGIN PAPI's COMPONENT REQUIRED FUNCTIONS  *************
Packit 577717
 *****************************************************************************/
Packit 577717
Packit 577717
/*
Packit 577717
 * This is called whenever a thread is initialized
Packit 577717
 */
Packit 577717
int
Packit 577717
NWUNIT_init_thread( hwd_context_t * ctx )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "NWUNIT_init_thread\n" );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	( void ) ctx;
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/* Initialize hardware counters, setup the function vector table
Packit 577717
 * and get hardware information, this routine is called when the 
Packit 577717
 * PAPI process is initialized (IE PAPI_library_init)
Packit 577717
 */
Packit 577717
int
Packit 577717
NWUNIT_init_component( int cidx )
Packit 577717
{  
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "NWUNIT_init_component\n" );
Packit 577717
#endif
Packit 577717
Packit 577717
	_NWunit_vector.cmp_info.CmpIdx = cidx;
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "NWUNIT_init_component cidx = %d\n", cidx );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Control of counters (Reading/Writing/Starting/Stopping/Setup)
Packit 577717
 * functions
Packit 577717
 */
Packit 577717
int
Packit 577717
NWUNIT_init_control_state( hwd_control_state_t * ptr )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "NWUNIT_init_control_state\n" );
Packit 577717
#endif
Packit 577717
	int retval;
Packit 577717
Packit 577717
	NWUNIT_control_state_t * this_state = ( NWUNIT_control_state_t * ) ptr;
Packit 577717
	
Packit 577717
	this_state->EventGroup = Bgpm_CreateEventSet();
Packit 577717
	retval = _check_BGPM_error( this_state->EventGroup, "Bgpm_CreateEventSet" );
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 *
Packit 577717
 */
Packit 577717
int
Packit 577717
NWUNIT_start( hwd_context_t * ctx, hwd_control_state_t * ptr )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "NWUNIT_start\n" );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	( void ) ctx;
Packit 577717
	int retval;
Packit 577717
	NWUNIT_control_state_t * this_state = ( NWUNIT_control_state_t * ) ptr;
Packit 577717
Packit 577717
	retval = Bgpm_Attach( this_state->EventGroup, UPC_NW_ALL_LINKS, 0); 
Packit 577717
	retval = _check_BGPM_error( retval, "Bgpm_Attach" );
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
	retval = Bgpm_ResetStart( this_state->EventGroup );
Packit 577717
	retval = _check_BGPM_error( retval, "Bgpm_ResetStart" );
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 *
Packit 577717
 */
Packit 577717
int
Packit 577717
NWUNIT_stop( hwd_context_t * ctx, hwd_control_state_t * ptr )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "NWUNIT_stop\n" );
Packit 577717
#endif
Packit 577717
	( void ) ctx;
Packit 577717
	int retval;
Packit 577717
	NWUNIT_control_state_t * this_state = ( NWUNIT_control_state_t * ) ptr;
Packit 577717
	
Packit 577717
	retval = Bgpm_Stop( this_state->EventGroup );
Packit 577717
	retval = _check_BGPM_error( retval, "Bgpm_Stop" );
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 *
Packit 577717
 */
Packit 577717
int
Packit 577717
NWUNIT_read( hwd_context_t * ctx, hwd_control_state_t * ptr,
Packit 577717
		   long_long ** events, int flags )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "NWUNIT_read\n" );
Packit 577717
#endif
Packit 577717
	( void ) ctx;
Packit 577717
	( void ) flags;
Packit 577717
	int i, numEvts;
Packit 577717
	NWUNIT_control_state_t * this_state = ( NWUNIT_control_state_t * ) ptr;
Packit 577717
	
Packit 577717
	numEvts = Bgpm_NumEvents( this_state->EventGroup );
Packit 577717
	if ( numEvts == 0 ) {
Packit 577717
#ifdef DEBUG_BGPM
Packit 577717
		printf ("Error: ret value is %d for BGPM API function Bgpm_NumEvents.\n", numEvts );
Packit 577717
#endif
Packit 577717
		//return ( EXIT_FAILURE );
Packit 577717
	}
Packit 577717
		
Packit 577717
	for ( i = 0; i < numEvts; i++ )
Packit 577717
		this_state->counts[i] = _common_getEventValue( i, this_state->EventGroup );
Packit 577717
Packit 577717
	*events = this_state->counts;
Packit 577717
	
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 *
Packit 577717
 */
Packit 577717
int
Packit 577717
NWUNIT_shutdown_thread( hwd_context_t * ctx )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "NWUNIT_shutdown_thread\n" );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	( void ) ctx;
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/* This function sets various options in the component
Packit 577717
 * The valid codes being passed in are PAPI_SET_DEFDOM,
Packit 577717
 * PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL * and PAPI_SET_INHERIT
Packit 577717
 */
Packit 577717
int
Packit 577717
NWUNIT_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "NWUNIT_ctl\n" );
Packit 577717
#endif
Packit 577717
	
Packit 577717
	( void ) ctx;
Packit 577717
	( void ) code;
Packit 577717
	( void ) option;
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
//int NWUNIT_ntv_code_to_bits ( unsigned int EventCode, hwd_register_t * bits );
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 *
Packit 577717
 */
Packit 577717
int
Packit 577717
NWUNIT_update_control_state( hwd_control_state_t * ptr,
Packit 577717
						   NativeInfo_t * native, int count,
Packit 577717
						   hwd_context_t * ctx )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "NWUNIT_update_control_state: count = %d\n", count );
Packit 577717
#endif
Packit 577717
	( void ) ctx;
Packit 577717
	int retval, index, i;
Packit 577717
	NWUNIT_control_state_t * this_state = ( NWUNIT_control_state_t * ) ptr;
Packit 577717
	
Packit 577717
	// Delete and re-create BGPM eventset
Packit 577717
	retval = _common_deleteRecreate( &this_state->EventGroup );
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
	// otherwise, add the events to the eventset
Packit 577717
	for ( i = 0; i < count; i++ ) {
Packit 577717
		index = ( native[i].ni_event ) + OFFSET;
Packit 577717
		
Packit 577717
		native[i].ni_position = i;
Packit 577717
		
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
		printf("NWUNIT_update_control_state: ADD event: i = %d, index = %d\n", i, index );
Packit 577717
#endif
Packit 577717
		
Packit 577717
		/* Add events to the BGPM eventGroup */
Packit 577717
		retval = Bgpm_AddEvent( this_state->EventGroup, index );
Packit 577717
		retval = _check_BGPM_error( retval, "Bgpm_AddEvent" );
Packit 577717
		if ( retval < 0 ) return retval; 
Packit 577717
	}
Packit 577717
	
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * This function has to set the bits needed to count different domains
Packit 577717
 * In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER
Packit 577717
 * By default return PAPI_EINVAL if none of those are specified
Packit 577717
 * and PAPI_OK with success
Packit 577717
 * PAPI_DOM_USER is only user context is counted
Packit 577717
 * PAPI_DOM_KERNEL is only the Kernel/OS context is counted
Packit 577717
 * PAPI_DOM_OTHER  is Exception/transient mode (like user TLB misses)
Packit 577717
 * PAPI_DOM_ALL   is all of the domains
Packit 577717
 */
Packit 577717
int
Packit 577717
NWUNIT_set_domain( hwd_control_state_t * cntrl, int domain )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "NWUNIT_set_domain\n" );
Packit 577717
#endif
Packit 577717
	int found = 0;
Packit 577717
	( void ) cntrl;
Packit 577717
Packit 577717
	if ( PAPI_DOM_USER & domain )
Packit 577717
		found = 1;
Packit 577717
Packit 577717
	if ( PAPI_DOM_KERNEL & domain )
Packit 577717
		found = 1;
Packit 577717
Packit 577717
	if ( PAPI_DOM_OTHER & domain )
Packit 577717
		found = 1;
Packit 577717
Packit 577717
	if ( !found )
Packit 577717
		return ( PAPI_EINVAL );
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 *
Packit 577717
 */
Packit 577717
int
Packit 577717
NWUNIT_reset( hwd_context_t * ctx, hwd_control_state_t * ptr )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "NWUNIT_reset\n" );
Packit 577717
#endif
Packit 577717
	( void ) ctx;
Packit 577717
	int retval;
Packit 577717
	NWUNIT_control_state_t * this_state = ( NWUNIT_control_state_t * ) ptr;
Packit 577717
Packit 577717
	/* we can't simply call Bgpm_Reset() since PAPI doesn't have the 
Packit 577717
	 restriction that an EventSet has to be stopped before resetting is
Packit 577717
	 possible. However, BGPM does have this restriction. 
Packit 577717
	 Hence we need to stop, reset and start */
Packit 577717
	retval = Bgpm_Stop( this_state->EventGroup );
Packit 577717
	retval = _check_BGPM_error( retval, "Bgpm_Stop" );
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
	retval = Bgpm_ResetStart( this_state->EventGroup );
Packit 577717
	retval = _check_BGPM_error( retval, "Bgpm_ResetStart" );
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Cleanup Eventset
Packit 577717
 *
Packit 577717
 * Destroy and re-create the BGPM / NWunit EventSet
Packit 577717
 */
Packit 577717
int
Packit 577717
NWUNIT_cleanup_eventset( hwd_control_state_t * ctrl )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "NWUNIT_cleanup_eventset\n" );
Packit 577717
#endif
Packit 577717
	int retval;
Packit 577717
Packit 577717
	NWUNIT_control_state_t * this_state = ( NWUNIT_control_state_t * ) ctrl;
Packit 577717
	
Packit 577717
	// create a new empty bgpm eventset
Packit 577717
	// reason: bgpm doesn't permit to remove events from an eventset; 
Packit 577717
	// hence we delete the old eventset and create a new one
Packit 577717
	retval = _common_deleteRecreate( &this_state->EventGroup ); // HJ try to use delete() only
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Native Event functions
Packit 577717
 */
Packit 577717
int
Packit 577717
NWUNIT_ntv_enum_events( unsigned int *EventCode, int modifier )
Packit 577717
{
Packit 577717
	//printf( "NWUNIT_ntv_enum_events\n" );
Packit 577717
Packit 577717
	switch ( modifier ) {
Packit 577717
	case PAPI_ENUM_FIRST:
Packit 577717
		*EventCode = 0;
Packit 577717
Packit 577717
		return ( PAPI_OK );
Packit 577717
		break;
Packit 577717
Packit 577717
	case PAPI_ENUM_EVENTS:
Packit 577717
	{
Packit 577717
		int index = ( *EventCode ) + OFFSET;
Packit 577717
Packit 577717
		if ( index < NWUNIT_MAX_EVENTS ) {
Packit 577717
			*EventCode = *EventCode + 1;
Packit 577717
			return ( PAPI_OK );
Packit 577717
		} else
Packit 577717
			return ( PAPI_ENOEVNT );
Packit 577717
Packit 577717
		break;
Packit 577717
	}
Packit 577717
	default:
Packit 577717
		return ( PAPI_EINVAL );
Packit 577717
	}
Packit 577717
	return ( PAPI_EINVAL );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 *
Packit 577717
 */
Packit 577717
int
Packit 577717
NWUNIT_ntv_name_to_code( const char *name, unsigned int *event_code )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "NWUNIT_ntv_name_to_code\n" );
Packit 577717
#endif
Packit 577717
	int ret;
Packit 577717
	
Packit 577717
	/* Return event id matching a given event label string */
Packit 577717
	ret = Bgpm_GetEventIdFromLabel ( name );
Packit 577717
	
Packit 577717
	if ( ret <= 0 ) {
Packit 577717
#ifdef DEBUG_BGPM
Packit 577717
		printf ("Error: ret value is %d for BGPM API function '%s'.\n",
Packit 577717
				ret, "Bgpm_GetEventIdFromLabel" );
Packit 577717
#endif
Packit 577717
		return PAPI_ENOEVNT;
Packit 577717
	}
Packit 577717
	else if ( ret < OFFSET || ret > NWUNIT_MAX_EVENTS ) // not a NWUnit event
Packit 577717
		return PAPI_ENOEVNT;
Packit 577717
	else
Packit 577717
		*event_code = ( ret - OFFSET ) ;
Packit 577717
	
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 *
Packit 577717
 */
Packit 577717
int
Packit 577717
NWUNIT_ntv_code_to_name( unsigned int EventCode, char *name, int len )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	//printf( "NWUNIT_ntv_code_to_name\n" );
Packit 577717
#endif
Packit 577717
	int index;
Packit 577717
	
Packit 577717
	index = ( EventCode ) + OFFSET;
Packit 577717
Packit 577717
	if ( index >= MAX_COUNTERS )
Packit 577717
		return PAPI_ENOEVNT;
Packit 577717
Packit 577717
	strncpy( name, Bgpm_GetEventIdLabel( index ), len );
Packit 577717
	
Packit 577717
	if ( name == NULL ) {
Packit 577717
#ifdef DEBUG_BGPM
Packit 577717
		printf ("Error: ret value is NULL for BGPM API function Bgpm_GetEventIdLabel.\n" );
Packit 577717
#endif
Packit 577717
		return PAPI_ENOEVNT;
Packit 577717
	}
Packit 577717
	
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 *
Packit 577717
 */
Packit 577717
int
Packit 577717
NWUNIT_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	//printf( "NWUNIT_ntv_code_to_descr\n" );
Packit 577717
#endif
Packit 577717
	int retval, index;
Packit 577717
	
Packit 577717
	index = ( EventCode ) + OFFSET;
Packit 577717
	
Packit 577717
	retval = Bgpm_GetLongDesc( index, name, &len );
Packit 577717
	retval = _check_BGPM_error( retval, "Bgpm_GetLongDesc" );						 
Packit 577717
	if ( retval < 0 ) return retval;
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 *
Packit 577717
 */
Packit 577717
int
Packit 577717
NWUNIT_ntv_code_to_bits( unsigned int EventCode, hwd_register_t * bits )
Packit 577717
{
Packit 577717
#ifdef DEBUG_BGQ
Packit 577717
	printf( "NWUNIT_ntv_code_to_bits\n" );
Packit 577717
#endif
Packit 577717
	( void ) EventCode;
Packit 577717
	( void ) bits;
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 *
Packit 577717
 */
Packit 577717
papi_vector_t _NWunit_vector = {
Packit 577717
	.cmp_info = {
Packit 577717
				 /* default component information (unspecified values are initialized to 0) */
Packit 577717
				 .name = "bgpm/NWUnit",
Packit 577717
				 .short_name = "NWUnit",
Packit 577717
				 .description = "Blue Gene/Q NWUnit component",
Packit 577717
				 .num_cntrs = NWUNIT_MAX_COUNTERS,
Packit 577717
				 .num_native_events = NWUNIT_MAX_EVENTS-OFFSET+1,
Packit 577717
				 .num_mpx_cntrs = NWUNIT_MAX_COUNTERS,
Packit 577717
				 .default_domain = PAPI_DOM_USER,
Packit 577717
				 .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL,
Packit 577717
				 .default_granularity = PAPI_GRN_THR,
Packit 577717
				 .available_granularities = PAPI_GRN_THR,
Packit 577717
		
Packit 577717
				 .hardware_intr_sig = PAPI_INT_SIGNAL,
Packit 577717
				 .hardware_intr = 1,
Packit 577717
		
Packit 577717
				 .kernel_multiplex = 0,
Packit 577717
Packit 577717
				 /* component specific cmp_info initializations */
Packit 577717
				 .fast_real_timer = 0,
Packit 577717
				 .fast_virtual_timer = 0,
Packit 577717
				 .attach = 0,
Packit 577717
				 .attach_must_ptrace = 0,
Packit 577717
				 
Packit 577717
				 }
Packit 577717
	,
Packit 577717
Packit 577717
	/* sizes of framework-opaque component-private structures */
Packit 577717
	.size = {
Packit 577717
			 .context = sizeof ( NWUNIT_context_t ),
Packit 577717
			 .control_state = sizeof ( NWUNIT_control_state_t ),
Packit 577717
			 .reg_value = sizeof ( NWUNIT_register_t ),
Packit 577717
			 .reg_alloc = sizeof ( NWUNIT_reg_alloc_t ),
Packit 577717
			 }
Packit 577717
	,
Packit 577717
	/* function pointers in this component */
Packit 577717
	.init_thread = NWUNIT_init_thread,
Packit 577717
	.init_component = NWUNIT_init_component,
Packit 577717
	.init_control_state = NWUNIT_init_control_state,
Packit 577717
	.start = NWUNIT_start,
Packit 577717
	.stop = NWUNIT_stop,
Packit 577717
	.read = NWUNIT_read,
Packit 577717
	.shutdown_thread = NWUNIT_shutdown_thread,
Packit 577717
	.cleanup_eventset = NWUNIT_cleanup_eventset,
Packit 577717
	.ctl = NWUNIT_ctl,
Packit 577717
Packit 577717
	.update_control_state = NWUNIT_update_control_state,
Packit 577717
	.set_domain = NWUNIT_set_domain,
Packit 577717
	.reset = NWUNIT_reset,
Packit 577717
Packit 577717
	.ntv_name_to_code = NWUNIT_ntv_name_to_code,
Packit 577717
	.ntv_enum_events = NWUNIT_ntv_enum_events,
Packit 577717
	.ntv_code_to_name = NWUNIT_ntv_code_to_name,
Packit 577717
	.ntv_code_to_descr = NWUNIT_ntv_code_to_descr,
Packit 577717
	.ntv_code_to_bits = NWUNIT_ntv_code_to_bits
Packit 577717
};