PAPI  5.3.0.0
linux-host_micpower.c
Go to the documentation of this file.
00001 
00012 /* From intel examples, see $(mic_dir)/sysmgt/sdk/Examples/Usage */
00013 #define MAX_DEVICES (32)
00014 #define EVENTS_PER_DEVICE 10
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <unistd.h>
00018 #include <dlfcn.h> 
00019 
00020 #include "MicAccessTypes.h"
00021 #include "MicBasicTypes.h"
00022 #include "MicAccessErrorTypes.h"
00023 #include "MicAccessApi.h"
00024 #include "MicPowerManagerAPI.h"
00025 
00026 #include "papi.h"
00027 #include "papi_internal.h"
00028 #include "papi_vector.h"
00029 #include "papi_memory.h"
00030 
00031 void (*_dl_non_dynamic_init)(void) __attribute__((weak));
00032 
00033 /* This is a guess, refine this later */
00034 #define UPDATEFREQ 500000
00035 
00036 papi_vector_t _host_micpower_vector;
00037 
00038 typedef struct host_micpower_register {
00040     unsigned int selector;
00041 } host_micpower_register_t;
00042 
00043 typedef struct host_micpower_reg_alloc {
00044     host_micpower_register_t ra_bits;
00045 } host_micpower_reg_alloc_t;
00046 
00048 typedef struct host_micpower_native_event_entry {
00049     host_micpower_register_t resources; 
00050     char name[PAPI_MAX_STR_LEN];
00051     char description[PAPI_MAX_STR_LEN];
00052     char units[3];
00053 } host_micpower_native_event_entry_t;
00054 
00056 typedef struct host_micpower_control_state {
00057     int num_events;
00058     int resident[MAX_DEVICES*EVENTS_PER_DEVICE];
00059     long long counts[MAX_DEVICES*EVENTS_PER_DEVICE];
00060     long long lastupdate[MAX_DEVICES];
00061 } host_micpower_control_state_t;
00062 
00064 typedef struct host_micpower_context {
00065     host_micpower_control_state_t state;
00066 } host_micpower_context_t; 
00067 
00068 /* Global state info */
00069 static MicDeviceOnSystem adapters[MAX_DEVICES];
00070 static HANDLE handles[MAX_DEVICES];
00071 static long long lastupdate[MAX_DEVICES];
00072 static HANDLE accessHandle = NULL;
00073 static U32 nAdapters = MAX_DEVICES;
00074 
00075 static void* mic_access     =   NULL;
00076 static void* scif_access    =   NULL;
00077 
00078 #undef MICACCESS_API
00079 #define MICACCESS_API __attribute__((weak))
00080 const char *MicGetErrorString(U32);
00081 U32 MICACCESS_API MicCloseAdapter(HANDLE);
00082 U32 MICACCESS_API MicInitAPI(HANDLE *, ETarget, MicDeviceOnSystem *, U32 *);
00083 U32 MICACCESS_API MicCloseAPI(HANDLE *);
00084 U32 MICACCESS_API MicInitAdapter(HANDLE *, MicDeviceOnSystem *);
00085 U32 MICACCESS_API MicGetPowerUsage(HANDLE, MicPwrUsage *);
00086 
00087 const char *(*MicGetErrorStringPtr)(U32);
00088 U32 (*MicCloseAdapterPtr)(HANDLE);
00089 U32 (*MicInitAPIPtr)(HANDLE *, ETarget, MicDeviceOnSystem *, U32 *);
00090 U32 (*MicCloseAPIPtr)(HANDLE *);
00091 U32 (*MicInitAdapterPtr)(HANDLE *, MicDeviceOnSystem *);
00092 U32 (*MicGetPowerUsagePtr)(HANDLE, MicPwrUsage *);
00093 static host_micpower_native_event_entry_t *native_events_table = NULL;
00094 
00095 struct powers {
00096         int total0;
00097         int total1;
00098         int inst;
00099         int imax;
00100         int pcie;
00101         int c2x3;
00102         int c2x4;
00103         int vccp;
00104         int vddg;
00105         int vddq;
00106 };
00107 
00108 typedef union {
00109         struct powers power;
00110         int array[EVENTS_PER_DEVICE]; 
00111 } power_t;
00112 
00113 static power_t cached_values[MAX_DEVICES];
00114 
00115 static int 
00116 loadFunctionPtrs()
00117 {
00118     /* Attempt to guess if we were statically linked to libc, if so bail */
00119     if ( _dl_non_dynamic_init != NULL ) {
00120         strncpy(_host_micpower_vector.cmp_info.disabled_reason, "The host_micpower component does not support statically linking of libc.", PAPI_MAX_STR_LEN);
00121         return PAPI_ENOSUPP;
00122     }
00123 
00124       /* Need to link in the cuda libraries, if not found disable the component */
00125     scif_access = dlopen("libscif.so", RTLD_NOW | RTLD_GLOBAL);
00126     if (NULL == scif_access)
00127     {
00128         snprintf(_host_micpower_vector.cmp_info.disabled_reason, PAPI_MAX_STR_LEN, "Problem loading the SCIF library: %s\n", dlerror());
00129             _host_micpower_vector.cmp_info.disabled = 1;
00130         return ( PAPI_ENOSUPP );
00131     }
00132 
00133     mic_access = dlopen("libMicAccessSDK.so", RTLD_NOW | RTLD_GLOBAL);
00134     if (NULL == mic_access)
00135     {
00136         snprintf(_host_micpower_vector.cmp_info.disabled_reason, PAPI_MAX_STR_LEN, "Problem loading libMicAccessSDK.so: %s\n", dlerror());
00137             _host_micpower_vector.cmp_info.disabled = 1;
00138         return ( PAPI_ENOSUPP );
00139     }
00140 
00141     MicGetErrorStringPtr = dlsym(mic_access, "MicGetErrorString");
00142     if (dlerror() != NULL)
00143     {
00144             strncpy(_host_micpower_vector.cmp_info.disabled_reason, "MicAccessSDK function MicGetErrorString not found.",PAPI_MAX_STR_LEN);
00145             _host_micpower_vector.cmp_info.disabled = 1;
00146             return ( PAPI_ENOSUPP );
00147     }
00148     MicCloseAdapterPtr = dlsym(mic_access, "MicCloseAdapter");
00149     if (dlerror() != NULL)
00150     {
00151             strncpy(_host_micpower_vector.cmp_info.disabled_reason, "MicAccessSDK function MicCloseAdapter not found.",PAPI_MAX_STR_LEN);
00152             _host_micpower_vector.cmp_info.disabled = 1;
00153             return ( PAPI_ENOSUPP );
00154     }
00155     MicInitAPIPtr = dlsym(mic_access, "MicInitAPI");
00156     if (dlerror() != NULL)
00157     {
00158             strncpy(_host_micpower_vector.cmp_info.disabled_reason, "MicAccessSDK function MicInitAPI not found.",PAPI_MAX_STR_LEN);
00159             _host_micpower_vector.cmp_info.disabled = 1;
00160             return ( PAPI_ENOSUPP );
00161     }
00162     MicCloseAPIPtr = dlsym(mic_access, "MicCloseAPI");
00163     if (dlerror() != NULL)
00164     {
00165             strncpy(_host_micpower_vector.cmp_info.disabled_reason, "MicAccessSDK function MicCloseAPI not found.",PAPI_MAX_STR_LEN);
00166             _host_micpower_vector.cmp_info.disabled = 1;
00167             return ( PAPI_ENOSUPP );
00168     }
00169     MicInitAdapterPtr = dlsym(mic_access, "MicInitAdapter");
00170     if (dlerror() != NULL)
00171     {
00172             strncpy(_host_micpower_vector.cmp_info.disabled_reason, "MicAccessSDK function MicInitAdapter not found.",PAPI_MAX_STR_LEN);
00173             _host_micpower_vector.cmp_info.disabled = 1;
00174             return ( PAPI_ENOSUPP );
00175     }
00176 
00177     MicGetPowerUsagePtr = dlsym(mic_access, "MicGetPowerUsage");
00178     if (dlerror() != NULL)
00179     {
00180             strncpy(_host_micpower_vector.cmp_info.disabled_reason, "MicAccessSDK function MicGetPowerUsage not found.",PAPI_MAX_STR_LEN);
00181             _host_micpower_vector.cmp_info.disabled = 1;
00182             return ( PAPI_ENOSUPP );
00183     }
00184 
00185     return 0;
00186 }
00187 
00188 
00189 /* ###############################################
00190  *          Component Interface code 
00191  * ############################################### */
00192 
00193 
00194 int 
00195 _host_micpower_init_component( int cidx ) 
00196 {
00197     U32 ret = MIC_ACCESS_API_ERROR_UNKNOWN;
00198     U32 adapterNum = 0;
00199     U32 throwaway = 1;
00200 
00201     _host_micpower_vector.cmp_info.CmpIdx = cidx;
00202 
00203     if ( loadFunctionPtrs() ) {
00204         goto disable_me;
00205     }
00206 
00207     memset( lastupdate, 0x0, sizeof(lastupdate));
00208     memset( cached_values, 0x0, sizeof(struct powers)*MAX_DEVICES );
00209     ret = MicInitAPIPtr( &accessHandle, eTARGET_SCIF_DRIVER, adapters, &nAdapters );
00210     if ( MIC_ACCESS_API_SUCCESS != ret ) {
00211         snprintf( _host_micpower_vector.cmp_info.disabled_reason, PAPI_MAX_STR_LEN, "Failed to init: %s", MicGetErrorStringPtr(ret));
00212         MicCloseAPIPtr(&accessHandle);
00213         goto disable_me;
00214     }
00215     /* Sanity check on array size */
00216     if ( nAdapters >= MAX_DEVICES ) {
00217         snprintf(_host_micpower_vector.cmp_info.disabled_reason, PAPI_MAX_STR_LEN, "Too many MIC cards [%d] found, bailing.", nAdapters);
00218         MicCloseAPIPtr(&accessHandle);
00219         goto disable_me;
00220     }
00221 
00222 /* XXX: This code initializes a token for each adapter, in testing this appeared to be required/
00223  *  One has to call MicInitAdapter() before calling into that adapter's entries */
00224     for (adapterNum=0; adapterNum < nAdapters; adapterNum++) {
00225             ret = MicInitAPIPtr( &handles[adapterNum], eTARGET_SCIF_DRIVER, adapters, &throwaway );
00226             throwaway = 1;
00227             if (MIC_ACCESS_API_SUCCESS != ret) {
00228                     fprintf(stderr, "%d:MicInitAPI carps: %s\n", __LINE__, MicGetErrorStringPtr(ret));
00229                     nAdapters = adapterNum;
00230                     for (adapterNum=0; adapterNum < nAdapters; adapterNum++)
00231                             MicCloseAdapterPtr( handles[adapterNum] );
00232                     MicCloseAPIPtr( &accessHandle );
00233                     snprintf(_host_micpower_vector.cmp_info.disabled_reason, PAPI_MAX_STR_LEN,
00234                         "Failed to initialize card %d's interface.", nAdapters);
00235                     goto disable_me;
00236             }
00237             ret = MicInitAdapterPtr(&handles[adapterNum], &adapters[adapterNum]);
00238             if (MIC_ACCESS_API_SUCCESS != ret) {
00239                     fprintf(stderr, "%d:MicInitAdapter carps: %s\n", __LINE__, MicGetErrorStringPtr(ret));
00240                     nAdapters = adapterNum;
00241                     for (adapterNum=0; adapterNum < nAdapters; adapterNum++)
00242                             MicCloseAdapterPtr( handles[adapterNum] );
00243                     MicCloseAPIPtr( &accessHandle );
00244                     snprintf(_host_micpower_vector.cmp_info.disabled_reason, PAPI_MAX_STR_LEN,
00245                         "Failed to initialize card %d's interface.", nAdapters);
00246                     goto disable_me;
00247             }
00248     }
00249 
00250     native_events_table = ( host_micpower_native_event_entry_t*)papi_malloc( nAdapters * EVENTS_PER_DEVICE * sizeof(host_micpower_native_event_entry_t));
00251     if ( NULL == native_events_table ) {
00252         return PAPI_ENOMEM;
00253     }
00254     for (adapterNum=0; adapterNum < nAdapters; adapterNum++) {
00255         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE].name, PAPI_MAX_STR_LEN, "mic%d:tot0", adapterNum);
00256         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE].description, PAPI_MAX_STR_LEN, "Total power utilization, Averaged over Time Window 0 (uWatts)");
00257         native_events_table[adapterNum*EVENTS_PER_DEVICE].resources.selector = adapterNum*EVENTS_PER_DEVICE + 1;
00258         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE].units, PAPI_MIN_STR_LEN, "uW");
00259 
00260         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 1].name, PAPI_MAX_STR_LEN, "mic%d:tot1", adapterNum);
00261         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 1].description, PAPI_MAX_STR_LEN, "Total power utilization, Averaged over Time Window 1 (uWatts)");
00262         native_events_table[adapterNum*EVENTS_PER_DEVICE + 1].resources.selector = adapterNum*EVENTS_PER_DEVICE + 2;
00263         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 1].units, PAPI_MIN_STR_LEN, "uW");
00264 
00265         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 2].name, PAPI_MAX_STR_LEN, "mic%d:pcie", adapterNum);
00266         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 2].description, PAPI_MAX_STR_LEN, "PCI-E connector power (uWatts)");
00267         native_events_table[adapterNum*EVENTS_PER_DEVICE + 2].resources.selector = adapterNum*EVENTS_PER_DEVICE + 3;
00268         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 2].units, PAPI_MIN_STR_LEN, "uW");
00269 
00270         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 3].name, PAPI_MAX_STR_LEN, "mic%d:inst", adapterNum);
00271         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 3].description, PAPI_MAX_STR_LEN, "Instantaneous power (uWatts)");
00272         native_events_table[adapterNum*EVENTS_PER_DEVICE + 3].resources.selector = adapterNum*EVENTS_PER_DEVICE + 4;
00273         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 3].units, PAPI_MIN_STR_LEN, "uW");
00274 
00275         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 4].name, PAPI_MAX_STR_LEN, "mic%d:imax", adapterNum);
00276         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 4].description, PAPI_MAX_STR_LEN, "Max instantaneous power (uWatts)");
00277         native_events_table[adapterNum*EVENTS_PER_DEVICE + 4].resources.selector = adapterNum*EVENTS_PER_DEVICE + 5;
00278         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 4].units, PAPI_MIN_STR_LEN, "uW");
00279 
00280         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 5].name, PAPI_MAX_STR_LEN, "mic%d:c2x3", adapterNum);
00281         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 5].description, PAPI_MAX_STR_LEN, "2x3 connector power (uWatts)");
00282         native_events_table[adapterNum*EVENTS_PER_DEVICE + 5].resources.selector = adapterNum*EVENTS_PER_DEVICE + 6;
00283         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 5].units, PAPI_MIN_STR_LEN, "uW");
00284 
00285         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 6].name, PAPI_MAX_STR_LEN, "mic%d:c2x4", adapterNum);
00286         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 6].description, PAPI_MAX_STR_LEN, "2x4 connector power (uWatts)");
00287         native_events_table[adapterNum*EVENTS_PER_DEVICE + 6].resources.selector = adapterNum*EVENTS_PER_DEVICE + 7;
00288         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 6].units, PAPI_MIN_STR_LEN, "uW");
00289 
00290         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 7].name, PAPI_MAX_STR_LEN, "mic%d:vccp", adapterNum);
00291         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 7].description, PAPI_MAX_STR_LEN, "Core rail (uVolts)");
00292         native_events_table[adapterNum*EVENTS_PER_DEVICE + 7].resources.selector = adapterNum*EVENTS_PER_DEVICE + 8;
00293         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 7].units, PAPI_MIN_STR_LEN, "uV");
00294 
00295         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 8].name, PAPI_MAX_STR_LEN, "mic%d:vddg", adapterNum);
00296         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 8].description, PAPI_MAX_STR_LEN, "Uncore rail (uVolts)");
00297         native_events_table[adapterNum*EVENTS_PER_DEVICE + 8].resources.selector = adapterNum*EVENTS_PER_DEVICE + 9;
00298         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 8].units, PAPI_MIN_STR_LEN, "uV");
00299 
00300         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 9].name, PAPI_MAX_STR_LEN, "mic%d:vddq", adapterNum);
00301         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 9].description, PAPI_MAX_STR_LEN, "Memory subsystem rail (uVolts)");
00302         native_events_table[adapterNum*EVENTS_PER_DEVICE + 9].resources.selector = adapterNum*EVENTS_PER_DEVICE + 10;
00303         snprintf(native_events_table[adapterNum*EVENTS_PER_DEVICE + 9].units, PAPI_MIN_STR_LEN, "uV");
00304     }
00305 
00306     _host_micpower_vector.cmp_info.num_cntrs = EVENTS_PER_DEVICE*nAdapters;
00307     _host_micpower_vector.cmp_info.num_mpx_cntrs = EVENTS_PER_DEVICE*nAdapters;
00308 
00309     _host_micpower_vector.cmp_info.num_native_events = EVENTS_PER_DEVICE*nAdapters;
00310 
00311     return PAPI_OK;
00312 
00313 disable_me:
00314     _host_micpower_vector.cmp_info.num_cntrs = 0;
00315     _host_micpower_vector.cmp_info.num_mpx_cntrs = 0;
00316     _host_micpower_vector.cmp_info.num_native_events = 0;
00317     _host_micpower_vector.cmp_info.disabled = 1;
00318 
00319     nAdapters = 0;
00320     return PAPI_ENOSUPP;
00321 }
00322 
00323 int _host_micpower_init_thread( hwd_context_t *ctx) {
00324     (void)ctx;
00325     return PAPI_OK;
00326 }
00327 
00328 int
00329 _host_micpower_shutdown_component( void ) {
00330     U32 i = 0;
00331     for( i=0; i<nAdapters; i++) {
00332         MicCloseAdapterPtr( handles[i] );
00333     }
00334 
00335     papi_free(native_events_table);
00336     return PAPI_OK;
00337 }
00338     
00339 int
00340 _host_micpower_shutdown_thread( hwd_context_t *ctx ) {
00341     (void) ctx;
00342     return PAPI_OK;
00343 }
00344 
00345 int _host_micpower_init_control_state ( hwd_control_state_t *ctl ) {
00346     host_micpower_control_state_t *state = (host_micpower_control_state_t*) ctl;
00347     memset( state, 0, sizeof(host_micpower_control_state_t));
00348 
00349     return PAPI_OK;
00350 }
00351 
00352 int _host_micpower_update_control_state(hwd_control_state_t *ctl, 
00353                                         NativeInfo_t *info, 
00354                                         int count,
00355                                         hwd_context_t* ctx ) {
00356 
00357     (void) ctx;
00358     int i, index;
00359     
00360     host_micpower_control_state_t *state = (host_micpower_control_state_t*)ctl;
00361 
00362     for (i=0; i<MAX_DEVICES*EVENTS_PER_DEVICE; i++)
00363         state->resident[i] = 0;
00364 
00365     for (i=0; i < count; i++) {
00366         index = info[i].ni_event&PAPI_NATIVE_AND_MASK;
00367         info[i].ni_position=native_events_table[index].resources.selector-1;
00368         state->resident[index] = 1;
00369     }
00370     state->num_events = count;
00371 
00372     return PAPI_OK;
00373 }
00374 
00375 int
00376 _host_micpower_start( hwd_context_t *ctx, hwd_control_state_t *ctl )
00377 {
00378     (void) ctx;
00379     (void) ctl;
00380     return PAPI_OK;
00381 }
00382 
00383 static int 
00384 read_power( struct powers *pwr, int which_one ) 
00385 {
00386     MicPwrUsage power;
00387     U32 ret = MIC_ACCESS_API_ERROR_UNKNOWN;
00388 
00389     if ( which_one < 0 || which_one > (int)nAdapters )
00390         return PAPI_ENOEVNT;
00391     
00392 
00393     ret = MicGetPowerUsagePtr(handles[which_one], &power);
00394     if (MIC_ACCESS_API_SUCCESS != ret) {
00395             fprintf(stderr,"Oops MicGetPowerUsage failed: %s\n", 
00396                             MicGetErrorStringPtr(ret));
00397             return PAPI_ECMP;
00398     }
00399 
00400     pwr->total0 = power.total0.prr;
00401     pwr->total1 = power.total1.prr;
00402     pwr->inst = power.inst.prr;
00403     pwr->imax = power.imax.prr;
00404     pwr->pcie = power.pcie.prr;
00405     pwr->c2x3 = power.c2x3.prr;
00406     pwr->c2x4 = power.c2x4.prr;
00407     pwr->vccp = power.vccp.pwr;
00408     pwr->vddg = power.vddg.pwr;
00409     pwr->vddq = power.vddq.pwr;
00410 
00411     return PAPI_OK;
00412 }
00413 
00414 int
00415 _host_micpower_read( hwd_context_t *ctx, hwd_control_state_t *ctl, 
00416                      long long **events, int flags) 
00417 {
00418     (void)flags;
00419     (void)events;
00420     (void)ctx;
00421     unsigned int i,j;
00422     int needs_update = 0;
00423     host_micpower_control_state_t* control = (host_micpower_control_state_t*)ctl;
00424     long long now = PAPI_get_real_usec();
00425 
00426     for( i=0; i<nAdapters; i++) {
00427             needs_update = 0;
00428             for (j=0; j<EVENTS_PER_DEVICE; j++) {
00429                 if ( control->resident[EVENTS_PER_DEVICE*i+j]) {
00430                         needs_update = 1;
00431                         break;
00432                 }
00433             }
00434 
00435             if ( needs_update ) {
00436                     /* Do the global update */
00437                     if ( now >= lastupdate[i] + UPDATEFREQ) {
00438                             read_power( &cached_values[i].power, i );
00439                             lastupdate[i] = now;
00440                     }
00441                     /* update from cached values */
00442                     if ( control->lastupdate[i] < lastupdate[i]) {
00443                             control->lastupdate[i] = lastupdate[i];
00444                     }
00445                     for (j=0; j<EVENTS_PER_DEVICE; j++) {
00446                         if ( control->resident[EVENTS_PER_DEVICE*i+j] ) {
00447                             control->counts[EVENTS_PER_DEVICE*i+j] = (long long)cached_values[i].array[j];
00448                         }
00449                     }
00450             }
00451     }
00452 
00453     *events = control->counts;
00454     return PAPI_OK;
00455 }
00456 
00457 int
00458 _host_micpower_stop( hwd_context_t *ctx, hwd_control_state_t *ctl )
00459 {
00460     (void)ctx;
00461     int needs_update = 0;
00462     unsigned int i,j;
00463     host_micpower_control_state_t* control = (host_micpower_control_state_t*)ctl;
00464     long long now = PAPI_get_real_usec();
00465 
00466     for( i=0; i<nAdapters; i++) {
00467             needs_update = 0;
00468             for (j=0; j<EVENTS_PER_DEVICE; j++) {
00469                 if ( control->resident[EVENTS_PER_DEVICE*i+j]) {
00470                         needs_update = 1;
00471                         break;
00472                 }
00473             }
00474 
00475             if ( needs_update ) {
00476                     /* Do the global update */
00477                     if ( now >= lastupdate[i] + UPDATEFREQ) {
00478                             read_power( &cached_values[i].power, i );
00479                             lastupdate[i] = now;
00480                     }
00481                     /* update from cached values */
00482                     if ( control->lastupdate[i] < lastupdate[i]) {
00483                             control->lastupdate[i] = lastupdate[i];
00484                     }
00485                     for (j=0; j<EVENTS_PER_DEVICE; j++) {
00486                         if ( control->resident[EVENTS_PER_DEVICE*i+j] ) {
00487                             control->counts[EVENTS_PER_DEVICE*i+j] = (long long)cached_values[i].array[j];
00488                         }
00489                     }
00490             }
00491     }
00492     return PAPI_OK;
00493 
00494 }
00495 
00496 int _host_micpower_ntv_enum_events( unsigned int *EventCode, int modifier )
00497 {
00498     int index;
00499     switch (modifier) {
00500         case PAPI_ENUM_FIRST:
00501             if (0 == _host_micpower_vector.cmp_info.num_cntrs)
00502                 return PAPI_ENOEVNT;
00503             *EventCode = 0;
00504             return PAPI_OK;
00505         case PAPI_ENUM_EVENTS:
00506             index = *EventCode;
00507             if ( index < _host_micpower_vector.cmp_info.num_cntrs - 1) {
00508                 *EventCode = *EventCode + 1;
00509                 return PAPI_OK;
00510             } else {
00511                 return PAPI_ENOEVNT;
00512             }
00513             break;
00514         default:
00515             return PAPI_EINVAL;
00516     }
00517     return PAPI_EINVAL;
00518 }
00519 
00520 int
00521 _host_micpower_ntv_code_to_name( unsigned int EventCode, char *name, int len )
00522 {
00523     unsigned int code = EventCode & PAPI_NATIVE_AND_MASK;
00524     if ( code < _host_micpower_vector.cmp_info.num_cntrs ) {
00525         strncpy( name, native_events_table[code].name, len);
00526         return PAPI_OK;
00527     }
00528 
00529     return PAPI_ENOEVNT;
00530 }
00531 
00532 int
00533 _host_micpower_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
00534 {
00535     unsigned int code = EventCode & PAPI_NATIVE_AND_MASK;
00536     if ( code < _host_micpower_vector.cmp_info.num_cntrs ) {
00537         strncpy( name, native_events_table[code].description, len );
00538         return PAPI_OK;
00539     }
00540 
00541     return PAPI_ENOEVNT;
00542 }
00543 
00544 int
00545 _host_micpower_ntv_code_to_info( unsigned int EventCode, PAPI_event_info_t *info)
00546 {
00547     unsigned int code = EventCode & PAPI_NATIVE_AND_MASK;
00548     if ( code >= _host_micpower_vector.cmp_info.num_cntrs)
00549         return PAPI_ENOEVNT;
00550     strncpy( info->symbol, native_events_table[code].name, sizeof(info->symbol) );
00551     strncpy( info->long_descr, native_events_table[code].description, sizeof(info->long_descr) );
00552     strncpy( info->units, native_events_table[code].units, sizeof(info->units) );
00553     return PAPI_OK;
00554 }
00555 
00556 int
00557 _host_micpower_ctl( hwd_context_t* ctx, int code, _papi_int_option_t *option)
00558 {
00559     (void)ctx;
00560     (void)code;
00561     (void)option;
00562     return PAPI_OK;
00563 }
00564 
00565 int
00566 _host_micpower_set_domain( hwd_control_state_t* ctl, int domain)
00567 {
00568     (void)ctl;
00569     (void)domain;
00570     return PAPI_OK;
00571 }
00572 
00573 papi_vector_t _host_micpower_vector = {
00574     .cmp_info = {
00575         .name = "host_micpower", 
00576         .short_name = "host_micpower", 
00577         .description = "A host-side component to read power usage on MIC guest cards.",
00578         .version = "0.1",
00579         .support_version = "n/a",
00580         .kernel_version = "n/a",
00581         .num_cntrs = 0,
00582         .num_mpx_cntrs = 0,
00583         .default_domain             = PAPI_DOM_ALL,
00584         .available_domains          = PAPI_DOM_ALL,
00585         .default_granularity        = PAPI_GRN_THR,
00586         .available_granularities    = PAPI_GRN_THR,
00587         .hardware_intr_sig          = PAPI_INT_SIGNAL,
00588     }, 
00589 
00590     .size  = {
00591         .context        = sizeof(host_micpower_context_t), 
00592         .control_state  = sizeof(host_micpower_control_state_t),
00593         .reg_value      = sizeof(host_micpower_register_t),
00594         .reg_alloc      = sizeof(host_micpower_reg_alloc_t),
00595     },
00596 
00597     .start                  = _host_micpower_start,
00598     .stop                   = _host_micpower_start,
00599     .read                   = _host_micpower_read, 
00600     .reset                  = NULL,
00601     .write                  = NULL,
00602     .init_component         = _host_micpower_init_component,
00603     .init_thread            = _host_micpower_init_thread,
00604     .init_control_state     = _host_micpower_init_control_state,
00605     .update_control_state   = _host_micpower_update_control_state,
00606     .ctl                    = _host_micpower_ctl, 
00607     .shutdown_thread        = _host_micpower_shutdown_thread,
00608     .shutdown_component     = _host_micpower_shutdown_component,
00609     .set_domain             = _host_micpower_set_domain,
00610 
00611     .ntv_enum_events        = _host_micpower_ntv_enum_events, 
00612     .ntv_code_to_name       = _host_micpower_ntv_code_to_name,
00613     .ntv_code_to_descr      = _host_micpower_ntv_code_to_descr,
00614     .ntv_code_to_info       = _host_micpower_ntv_code_to_info,
00615 
00616 };
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines