|
Packit |
577717 |
/****************************/
|
|
Packit |
577717 |
/* THIS IS OPEN SOURCE CODE */
|
|
Packit |
577717 |
/****************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* @file HelloWorld.c
|
|
Packit |
577717 |
* CVS: $Id$
|
|
Packit |
577717 |
* @author Asim YarKhan (yarkhan@icl.utk.edu) HelloWorld altered to test power capping (October 2017)
|
|
Packit |
577717 |
* @author Heike Jagode (jagode@icl.utk.edu)
|
|
Packit |
577717 |
* Mods: <your name here> <your email address>
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @brief
|
|
Packit |
577717 |
|
|
Packit |
577717 |
* This file is a very simple HelloWorld C example which serves
|
|
Packit |
577717 |
* (together with its Makefile) as a guideline on how to add tests to
|
|
Packit |
577717 |
* components. This file tests the ability to do power control using
|
|
Packit |
577717 |
* NVML.
|
|
Packit |
577717 |
|
|
Packit |
577717 |
* The papi configure and papi Makefile will take care of the
|
|
Packit |
577717 |
* compilation of the component tests (if all tests are added to a
|
|
Packit |
577717 |
* directory named 'tests' in the specific component dir). See
|
|
Packit |
577717 |
* components/README for more details.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* The string "Hello World!" is mangled and then restored.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include <cuda.h>
|
|
Packit |
577717 |
#include <stdio.h>
|
|
Packit |
577717 |
#include "papi.h"
|
|
Packit |
577717 |
#include "papi_test.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#define PAPI
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// Prototypes
|
|
Packit |
577717 |
__global__ void helloWorld( char* );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// Host function
|
|
Packit |
577717 |
int main( int argc, char** argv )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifdef PAPI
|
|
Packit |
577717 |
#define NUM_EVENTS 1
|
|
Packit |
577717 |
int retval, i;
|
|
Packit |
577717 |
int EventSet = PAPI_NULL;
|
|
Packit |
577717 |
long long values[NUM_EVENTS];
|
|
Packit |
577717 |
/* REPLACE THE EVENT NAME 'PAPI_FP_OPS' WITH A CUDA EVENT
|
|
Packit |
577717 |
FOR THE CUDA DEVICE YOU ARE RUNNING ON.
|
|
Packit |
577717 |
RUN papi_native_avail to get a list of CUDA events that are
|
|
Packit |
577717 |
supported on your machine */
|
|
Packit |
577717 |
// e.g. on a P100 nvml:::Tesla_P100-SXM2-16GB:power
|
|
Packit |
577717 |
char *EventName[NUM_EVENTS];
|
|
Packit |
577717 |
int events[NUM_EVENTS];
|
|
Packit |
577717 |
int eventCount = 0;
|
|
Packit |
577717 |
const PAPI_component_info_t *cmpinfo;
|
|
Packit |
577717 |
char event_name[PAPI_MAX_STR_LEN];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* PAPI Initialization */
|
|
Packit |
577717 |
retval = PAPI_library_init( PAPI_VER_CURRENT );
|
|
Packit |
577717 |
if( retval != PAPI_VER_CURRENT ) fprintf( stderr, "PAPI_library_init failed\n" );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
printf( "PAPI_VERSION : %4d %6d %7d\n",
|
|
Packit |
577717 |
PAPI_VERSION_MAJOR( PAPI_VERSION ),
|
|
Packit |
577717 |
PAPI_VERSION_MINOR( PAPI_VERSION ),
|
|
Packit |
577717 |
PAPI_VERSION_REVISION( PAPI_VERSION ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int numcmp = PAPI_num_components();
|
|
Packit |
577717 |
// printf( "Searching for nvml component among %d components\n", numcmp );
|
|
Packit |
577717 |
int cid = 0;
|
|
Packit |
577717 |
for( cid=0; cid
|
|
Packit |
577717 |
cmpinfo = PAPI_get_component_info( cid );
|
|
Packit |
577717 |
// printf( "Component %d (%d): %s: %d events\n", cid, cmpinfo->CmpIdx, cmpinfo->name, cmpinfo->num_native_events );
|
|
Packit |
577717 |
if ( cmpinfo == NULL )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__,"PAPI_get_component_info failed\n",-1 );
|
|
Packit |
577717 |
else if ( strstr( cmpinfo->name, "nvml" ) )
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if ( cid==numcmp )
|
|
Packit |
577717 |
test_skip( __FILE__, __LINE__,"Component nvml is not present\n",-1 );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
printf( "nvml component found: Component Index %d: %s: %d events\n", cmpinfo->CmpIdx, cmpinfo->name, cmpinfo->num_native_events );
|
|
Packit |
577717 |
if ( cmpinfo->disabled )
|
|
Packit |
577717 |
test_skip( __FILE__,__LINE__,"Component nvml is disabled", 0 );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int code = PAPI_NATIVE_MASK;
|
|
Packit |
577717 |
int ii=0;
|
|
Packit |
577717 |
int event_modifier = PAPI_ENUM_FIRST;
|
|
Packit |
577717 |
for ( ii=0; ii<cmpinfo->num_native_events; ii++ ) {
|
|
Packit |
577717 |
retval = PAPI_enum_cmp_event( &code, event_modifier, cid );
|
|
Packit |
577717 |
event_modifier = PAPI_ENUM_EVENTS;
|
|
Packit |
577717 |
if ( retval != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval );
|
|
Packit |
577717 |
retval = PAPI_event_code_to_name( code, event_name );
|
|
Packit |
577717 |
// printf( "Look at event %d %d %s \n", ii, code, event_name );
|
|
Packit |
577717 |
if ( strstr( event_name, "power_management_limit" ) )
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if ( ii==cmpinfo->num_native_events )
|
|
Packit |
577717 |
test_skip( __FILE__,__LINE__,"Component nvml does not have a power_management_limit event", 0 );
|
|
Packit |
577717 |
printf( "nvml power_management_limit event found (%s)\n", event_name );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
EventName[0] = event_name;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* convert PAPI native events to PAPI code */
|
|
Packit |
577717 |
for( i = 0; i < NUM_EVENTS; i++ ) {
|
|
Packit |
577717 |
retval = PAPI_event_name_to_code( ( char * )EventName[i], &events[i] );
|
|
Packit |
577717 |
if( retval != PAPI_OK )
|
|
Packit |
577717 |
test_fail( __FILE__,__LINE__,"PAPI_event_name_to_code failed", retval );
|
|
Packit |
577717 |
eventCount++;
|
|
Packit |
577717 |
// printf( "Event: %s: Code: %#x\n", EventName[i], events[i] );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* if we did not find any valid events, just report test failed. */
|
|
Packit |
577717 |
if ( eventCount == 0 )
|
|
Packit |
577717 |
test_skip( __FILE__,__LINE__,"No valid events found", retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = PAPI_create_eventset( &EventSet );
|
|
Packit |
577717 |
if( retval != PAPI_OK )
|
|
Packit |
577717 |
test_fail( __FILE__,__LINE__,"PAPI_create_eventset failed", retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = PAPI_add_events( EventSet, events, eventCount );
|
|
Packit |
577717 |
if( retval != PAPI_OK )
|
|
Packit |
577717 |
test_fail( __FILE__,__LINE__,"PAPI_add_events failed", retval );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int j;
|
|
Packit |
577717 |
int device_count;
|
|
Packit |
577717 |
int cuda_device;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
cudaGetDeviceCount( &device_count );
|
|
Packit |
577717 |
printf( "Found %d cuda devices\n", device_count );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/////////////////////// AYK
|
|
Packit |
577717 |
for ( cuda_device = 0; cuda_device < device_count; cuda_device++ ) {
|
|
Packit |
577717 |
// for ( cuda_device = 0; cuda_device < 1; cuda_device++ ) {
|
|
Packit |
577717 |
printf( "cuda_device %d is being used\n", cuda_device );
|
|
Packit |
577717 |
cudaSetDevice( cuda_device );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifdef PAPI
|
|
Packit |
577717 |
retval = PAPI_start( EventSet );
|
|
Packit |
577717 |
if( retval != PAPI_OK )
|
|
Packit |
577717 |
test_fail( __FILE__,__LINE__,"PAPI_start failed", retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = PAPI_read( EventSet, values );
|
|
Packit |
577717 |
if( retval != PAPI_OK ) fprintf( stderr, "PAPI_read failed\n" );
|
|
Packit |
577717 |
for( i = 0; i < eventCount; i++ )
|
|
Packit |
577717 |
printf( "%s = %lld (read initial power management limit)\n", EventName[i], values[i]);
|
|
Packit |
577717 |
long long int initial_power_management_limit = values[0];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( cuda_device==0 ) {
|
|
Packit |
577717 |
printf("On device_num %d the power_management_limit is going to be reduced by 30\n", cuda_device);
|
|
Packit |
577717 |
// values[0] = 235000
|
|
Packit |
577717 |
values[0] = initial_power_management_limit - 30;
|
|
Packit |
577717 |
retval = PAPI_write( EventSet, values );
|
|
Packit |
577717 |
if ( retval!=PAPI_OK ) {
|
|
Packit |
577717 |
test_skip( __FILE__,__LINE__,"Attempted write of power_management_limit failed: Possible reasons: Insufficient permissions; Power management unavailable. Outside min/max limits", retval );
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
printf( "Set power_management_limit to %llu milliWatts\n", values[0] );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// desired output
|
|
Packit |
577717 |
char str[] = "Hello World!";
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// mangle contents of output
|
|
Packit |
577717 |
// the null character is left intact for simplicity
|
|
Packit |
577717 |
for(j = 0; j < 12; j++)
|
|
Packit |
577717 |
str[j] -= j;
|
|
Packit |
577717 |
printf( "This mangled string need to be fixed=%s\n", str );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// allocate memory on the device
|
|
Packit |
577717 |
char *d_str;
|
|
Packit |
577717 |
size_t size = sizeof( str );
|
|
Packit |
577717 |
cudaMalloc( ( void** )&d_str, size );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// copy the string to the device
|
|
Packit |
577717 |
cudaMemcpy( d_str, str, size, cudaMemcpyHostToDevice );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// set the grid and block sizes
|
|
Packit |
577717 |
dim3 dimGrid( 2 ); // one block per word
|
|
Packit |
577717 |
dim3 dimBlock( sizeof( str )/2 ); // one thread per character
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// invoke the kernel
|
|
Packit |
577717 |
helloWorld<<< dimGrid, dimBlock >>>( d_str );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// retrieve the results from the device
|
|
Packit |
577717 |
cudaMemcpy( str, d_str, size, cudaMemcpyDeviceToHost );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// free up the allocated memory on the device
|
|
Packit |
577717 |
cudaFree( d_str );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
printf( "Device %d Unmangled string = %s\n", cuda_device, str );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifdef PAPI
|
|
Packit |
577717 |
if ( cuda_device==0 ) {
|
|
Packit |
577717 |
retval = PAPI_read( EventSet, values );
|
|
Packit |
577717 |
if( retval != PAPI_OK ) fprintf( stderr, "PAPI_read failed\n" );
|
|
Packit |
577717 |
for( i = 0; i < eventCount; i++ )
|
|
Packit |
577717 |
printf( "%s = %lld (read power management limit after reducing it... was it reduced?) \n", EventName[i], values[i] );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( values[0] != initial_power_management_limit - 30 ) {
|
|
Packit |
577717 |
printf( "Mismatch: power_management_limit on device %d set to %llu but read as %llu\n", cuda_device, initial_power_management_limit-30, values[0] );
|
|
Packit |
577717 |
test_fail( __FILE__,__LINE__,"Mismatch: power_management_limit on device set to one value but read as a different value", -1 );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// AYK papi_reset
|
|
Packit |
577717 |
long long resetvalues[NUM_EVENTS];
|
|
Packit |
577717 |
resetvalues[0] = initial_power_management_limit;
|
|
Packit |
577717 |
retval = PAPI_write( EventSet, resetvalues );
|
|
Packit |
577717 |
retval = PAPI_stop( EventSet, values );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
test_pass( __FILE__);
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// Device kernel
|
|
Packit |
577717 |
__global__ void
|
|
Packit |
577717 |
helloWorld( char* str )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
// determine where in the thread grid we are
|
|
Packit |
577717 |
int idx = blockIdx.x * blockDim.x + threadIdx.x;
|
|
Packit |
577717 |
// unmangle output
|
|
Packit |
577717 |
str[idx] += idx;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|