PAPI  5.0.1.0
papi_preset.c File Reference
Include dependency graph for papi_preset.c:

Go to the source code of this file.

Defines

#define PAPI_EVENT_FILE   "papi_events.csv"

Functions

int _papi_hwi_setup_all_presets (hwi_search_t *findem, int cidx)
int _papi_hwi_cleanup_all_presets (void)
static char * trim_string (char *in)
static char * trim_note (char *in)
static int find_preset_code (char *tmp, int *code)
static FILE * open_event_table (char *name)
static int get_event_line (char *line, FILE *table, char **tmp_perfmon_events_table)
int _papi_load_preset_table (char *pmu_str, int pmu_type, int cidx)

Variables

static char * papi_events_table = NULL

Define Documentation

#define PAPI_EVENT_FILE   "papi_events.csv"

Definition at line 144 of file papi_preset.c.


Function Documentation

< No error

Definition at line 107 of file papi_preset.c.

{
        int preset_index,cidx;
    unsigned int j;

    for ( preset_index = 0; preset_index < PAPI_MAX_PRESET_EVENTS;
          preset_index++ ) {
        if ( _papi_hwi_presets[preset_index].postfix != NULL ) {
           free( _papi_hwi_presets[preset_index].postfix );
           _papi_hwi_presets[preset_index].postfix = NULL;
        }
        if ( _papi_hwi_presets[preset_index].note != NULL ) {
           free( _papi_hwi_presets[preset_index].note );
           _papi_hwi_presets[preset_index].note = NULL;
        }
        for(j=0; j<_papi_hwi_presets[preset_index].count;j++) {
           free(_papi_hwi_presets[preset_index].name[j]);
        }
    }
    
    for(cidx=0;cidx<papi_num_components;cidx++) {
       _papi_hwd[cidx]->cmp_info.num_preset_events = 0;
    }

#if defined(ITANIUM2) || defined(ITANIUM3)
    /* NOTE: This memory may need to be freed for BG/P builds as well */
    if ( preset_search_map != NULL ) {
        papi_free( preset_search_map );
        preset_search_map = NULL;
    }
#endif

    return PAPI_OK;
}

Here is the caller graph for this function:

int _papi_hwi_setup_all_presets ( hwi_search_t findem,
int  cidx 
)

<A nonexistent hardware event used as a placeholder

<A nonexistent hardware event used as a placeholder

< No error

< Event does not exist

Definition at line 37 of file papi_preset.c.

{
    int i, pnum, did_something = 0;
    unsigned int preset_index, j, k;

    /* dense array of events is terminated with a 0 preset.
       don't do anything if NULL pointer. This allows just notes to be loaded.
       It's also good defensive programming. 
     */
    if ( findem != NULL ) {
       for ( pnum = 0; ( pnum < PAPI_MAX_PRESET_EVENTS ) &&
              ( findem[pnum].event_code != 0 ); pnum++ ) {
       /* find the index for the event to be initialized */
       preset_index = ( findem[pnum].event_code & PAPI_PRESET_AND_MASK );
       /* count and set the number of native terms in this event, 
              these items are contiguous.

          PAPI_EVENTS_IN_DERIVED_EVENT is arbitrarily defined in the high 
              level to be a reasonable number of terms to use in a derived 
              event linear expression, currently 8.

          This wastes space for components with less than 8 counters, 
              but keeps the framework independent of the components.

          The 'native' field below is an arbitrary opaque identifier 
              that points to information on an actual native event. 
              It is not an event code itself (whatever that might mean).
          By definition, this value can never == PAPI_NULL.
          - dkt */

       INTDBG( "Counting number of terms for preset index %d, "
                   "search map index %d.\n", preset_index, pnum );
       i = 0;
       j = 0;
       while ( i < PAPI_EVENTS_IN_DERIVED_EVENT ) {
          if ( findem[pnum].native[i] != PAPI_NULL ) {
         j++;
          }
          else if ( j ) {
         break;
          }
          i++;
       }

       INTDBG( "This preset has %d terms.\n", j );
       _papi_hwi_presets[preset_index].count = j;
 
           _papi_hwi_presets[preset_index].derived_int = findem[pnum].derived;
       for(k=0;k<j;k++) {
              _papi_hwi_presets[preset_index].code[k] = 
                     findem[pnum].native[k];
       }
       /* preset code list must be PAPI_NULL terminated */
       if (k<PAPI_EVENTS_IN_DERIVED_EVENT) {
              _papi_hwi_presets[preset_index].code[k] = PAPI_NULL;
       }

       _papi_hwi_presets[preset_index].postfix=
                                       strdup(findem[pnum].operation);

       did_something++;
       }
    }

    _papi_hwd[cidx]->cmp_info.num_preset_events += did_something;

    return ( did_something ? PAPI_OK : PAPI_ENOEVNT );
}

Here is the caller graph for this function:

int _papi_load_preset_table ( char *  pmu_str,
int  pmu_type,
int  cidx 
)

< A System/C library call failed

< No error

< No error

< Process counters based on specified postfix string

< No error

<A nonexistent hardware event used as a placeholder

< No error

Definition at line 299 of file papi_preset.c.

{

  (void) cidx;  /* We'll use this later */

    char pmu_name[PAPI_MIN_STR_LEN];
    char line[LINE_MAX];
    char name[PATH_MAX] = "builtin papi_events_table";
    char *tmp_papi_events_table = NULL;
    char *tmpn;
    FILE *table;
    int ret;
    unsigned int event_idx;
    int invalid_event;
    int line_no = 1, derived = 0, insert = 0, preset = 0;
    int get_presets = 0;   /* only get PRESETS after CPU is identified      */
    int found_presets = 0; /* only terminate search after PRESETS are found */
                       /* this allows support for synonyms for CPU names*/

    SUBDBG("ENTER\n");

    /* copy the pmu identifier, stripping commas if found */
    tmpn = pmu_name;
    while ( *pmu_str ) {
       if ( *pmu_str != ',' ) *tmpn++ = *pmu_str;
       pmu_str++;
    }
    *tmpn = '\0';

    /* try the environment variable first */
    if ( ( tmpn = getenv( "PAPI_CSV_EVENT_FILE" ) ) && 
         ( strlen( tmpn ) != 0 ) ) {
       sprintf( name, "%s", tmpn );
       table = fopen( name, "r" );
    }
    /* if no valid environment variable, look for built-in table */
    else if ( papi_events_table ) {
       tmp_papi_events_table = papi_events_table;
       table = NULL;
    }
    /* if no env var and no built-in, search for default file */
    else {
#ifdef PAPI_DATADIR
       sprintf( name, "%s/%s", PAPI_DATADIR, PAPI_EVENT_FILE );
#else
       sprintf( name, "%s", PAPI_EVENT_FILE );
#endif
       table = open_event_table( name );
    }

    /* if no valid file or built-in table, bail */
    if ( table == NULL && tmp_papi_events_table == NULL ) {
       PAPIERROR( "fopen(%s): %s, please set the PAPI_CSV_EVENT_FILE "
                  "env. variable", name, strerror( errno ) );
       return PAPI_ESYS;
    }

    /* at this point either a valid file pointer or built-in table pointer */
    while ( get_event_line( line, table, &tmp_papi_events_table ) ) {
       char *t;
       int i;

       t = trim_string( strtok( line, "," ) );

       /* Skip blank lines */
       if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) continue;

       /* Skip comments */
       if ( t[0] == '#' ) {
      goto nextline;
       } 

       if ( strcasecmp( t, "CPU" ) == 0 ) {

      if ( get_presets != 0 && found_presets != 0 ) {
         SUBDBG( "Ending preset scanning at line %d of %s.\n", 
                     line_no, name );

         get_presets=0; found_presets=0;
                
      }
            
      t = trim_string( strtok( NULL, "," ) );
      if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
         PAPIERROR( "Expected name after CPU token at line %d of %s "
            "-- ignoring", line_no, name );
         goto nextline;
      }

      SUBDBG( "Examining CPU (%s) vs. (%s)\n", t, pmu_name );

      if ( strcasecmp( t, pmu_name ) == 0 ) {
         int type;

         SUBDBG( "Found CPU %s at line %d of %s.\n", t, line_no, name );

         t = trim_string( strtok( NULL, "," ) );
         if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
        SUBDBG("No additional qualifier found, matching on string.\n");

        get_presets = 1;
         } else if ( ( sscanf( t,"%d",&type )==1) && (type==pmu_type) ) {
                SUBDBG( "Found CPU %s type %d at line %d of %s.\n",
            pmu_name, type, line_no, name );
        get_presets = 1;
         } else {
        SUBDBG( "Additional qualifier match failed %d vs %d.\n",
            pmu_type, type );

         }
      }
       } else if ( strcasecmp( t, "PRESET" ) == 0 ) {

          if ( get_presets == 0 ) goto nextline;

      found_presets = 1;
      t = trim_string( strtok( NULL, "," ) );

      if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
                   
             PAPIERROR( "Expected name after PRESET token at line %d of %s "
            "-- ignoring", line_no, name );
         goto nextline;
      }

      SUBDBG( "Examining preset %s\n", t );

      if ( find_preset_code( t, &preset ) != PAPI_OK ) {
         PAPIERROR ( "Invalid preset name %s after PRESET token "
             "at line %d of %s -- ignoring",
             t, line_no, name );
         goto nextline;
      }

      SUBDBG( "Found 0x%08x for %s\n", preset, t );

      t = trim_string( strtok( NULL, "," ) );
      if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
         PAPIERROR( "Expected derived type after PRESET token at "
                        "line %d of %s -- ignoring", line_no, name );
         goto nextline;
      }

      if ( _papi_hwi_derived_type( t, &derived ) != PAPI_OK ) {
         PAPIERROR( "Invalid derived name %s after PRESET token at "
            "line %d of %s -- ignoring",
            t, line_no, name );
         goto nextline;
      }

      /****************************************/
      /* Have a preset, let's start assigning */
      /****************************************/

      SUBDBG( "Found %d for %s\n", derived, t );
      SUBDBG( "Adding 0x%x,%d to preset search table.\n", 
          preset, derived );
      
      insert=preset&PAPI_PRESET_AND_MASK;

      /* _papi_hwi_presets[insert].event_code = preset; */
      _papi_hwi_presets[insert].derived_int = derived;

      /* Derived support starts here */
      /* Special handling for postfix */
      if ( derived == DERIVED_POSTFIX ) {
         t = trim_string( strtok( NULL, "," ) );
         if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
        PAPIERROR( "Expected Operation string after derived type "
               "DERIVED_POSTFIX at line %d of %s -- ignoring",
               line_no, name );
        goto nextline;
         }

         SUBDBG( "Saving PostFix operations %s\n", t );

         _papi_hwi_presets[insert].postfix=strdup(t);
      }
            
      /* All derived terms collected here */
      i = 0;
      invalid_event=0;
      do {
         t = trim_string( strtok( NULL, "," ) );
         if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) break;
         if ( strcasecmp( t, "NOTE" ) == 0 ) break;
         _papi_hwi_presets[insert].name[i]=strdup(t);

         SUBDBG( "Adding term (%d) %s to preset event 0x%x.\n", 
             i, t, preset );

         SUBDBG("Looking up: %s\n",t);

         ret=_papi_hwd[cidx]->ntv_name_to_code(t, &event_idx);

         if (ret==PAPI_OK) {
        _papi_hwi_presets[insert].code[i]=
                  _papi_hwi_native_to_eventcode(cidx,event_idx);
        SUBDBG("Found: %s %x c%d e%d\n",t,
               _papi_hwi_presets[insert].code[i],
               cidx,event_idx);
         }
         else {
        PAPIERROR("papi_preset: Error finding event %s",t);
        invalid_event=1;
         }

      } while ( ++i < PAPI_EVENTS_IN_DERIVED_EVENT );

      /* preset code list must be PAPI_NULL terminated */
      if (i<PAPI_EVENTS_IN_DERIVED_EVENT) {
             _papi_hwi_presets[insert].code[i] = PAPI_NULL;
      }

      if (invalid_event) {
        /* We signify a valid preset if count > 0 */
         _papi_hwi_presets[insert].count=0;
      } else {
         _papi_hwi_presets[insert].count=i;
      }

      /* End of derived support */

      if ( i == 0 ) {
         PAPIERROR( "Expected PFM event after DERIVED token at "
            "line %d of %s -- ignoring", line_no, name );
         goto nextline;
      }
      if ( i == PAPI_EVENTS_IN_DERIVED_EVENT ) {
         t = trim_string( strtok( NULL, "," ) );
      }
            
      /* Handle optional NOTEs */
      if ( t && ( strcasecmp( t, "NOTE" ) == 0 ) ) {
         SUBDBG( "%s found on line %d\n", t, line_no );

         /* read the rest of the line */
         t = trim_note( strtok( NULL, "" ) );
    
         if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
        PAPIERROR( "Expected Note string at line %d of %s\n",
               line_no, name );
         }
         else {
            _papi_hwi_presets[insert].note = strdup( t );
        SUBDBG( "NOTE: --%s-- found on line %d\n", t, line_no );
         }
      }
      _papi_hwd[cidx]->cmp_info.num_preset_events++;

       } else {
      PAPIERROR( "Unrecognized token %s at line %d of %s -- ignoring", 
             t, line_no, name );
      goto nextline;
       }
nextline:
       line_no++;
    }

    if ( table ) {
       fclose( table );
    }

    SUBDBG("Done parsing preset table\n");
    
    return PAPI_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int find_preset_code ( char *  tmp,
int *  code 
) [inline, static]

< No error

< Invalid argument

Definition at line 218 of file papi_preset.c.

{
    int i = 0;

    while ( _papi_hwi_presets[i].symbol != NULL ) {
      if ( strcasecmp( tmp, _papi_hwi_presets[i].symbol ) == 0 ) {
         *code = ( int ) ( i | PAPI_PRESET_MASK );
         return PAPI_OK;
      }
      i++;
    }
    return PAPI_EINVAL;
}

Here is the caller graph for this function:

static int get_event_line ( char *  line,
FILE *  table,
char **  tmp_perfmon_events_table 
) [static]

Definition at line 262 of file papi_preset.c.

{
    int ret;
    int i;

    if ( table ) {
        if ( fgets( line, LINE_MAX, table ) ) {
            ret = 1;
            i = ( int ) strlen( line );
            if ( line[i - 1] == '\n' )
                line[i - 1] = '\0';
        } else
            ret = 0;
    } else {
        for ( i = 0;
              **tmp_perfmon_events_table && **tmp_perfmon_events_table != '\n';
              i++ ) {
            line[i] = **tmp_perfmon_events_table;
            ( *tmp_perfmon_events_table )++;
        }
        if ( **tmp_perfmon_events_table == '\n' ) {
            ( *tmp_perfmon_events_table )++;
        }
        line[i] = '\0';
        ret = **tmp_perfmon_events_table;
    }
    return ret;
}

Here is the caller graph for this function:

static FILE* open_event_table ( char *  name) [static]

Definition at line 235 of file papi_preset.c.

{
    FILE *table;

    SUBDBG( "Opening %s\n", name );
    table = fopen( name, "r" );
    if ( table == NULL ) {
        SUBDBG( "Open %s failed, trying ./%s.\n", 
            name, PAPI_EVENT_FILE );
        sprintf( name, "%s", PAPI_EVENT_FILE );
        table = fopen( name, "r" );
    }
    if ( table == NULL ) {
        SUBDBG( "Open ./%s failed, trying ../%s.\n", 
            name, PAPI_EVENT_FILE );
        sprintf( name, "../%s", PAPI_EVENT_FILE );
        table = fopen( name, "r" );
    }
    if ( table ) {
        SUBDBG( "Open %s succeeded.\n", name );
    }
    return table;
}

Here is the caller graph for this function:

static char* trim_note ( char *  in) [inline, static]

Definition at line 190 of file papi_preset.c.

{
    int len;
    char *note, start, end;

    note = trim_string( in );
    if ( note != NULL ) {
                len = ( int ) strlen( note );
        if ( len > 0 ) {
            if ( ispunct( *note ) ) {
                start = *note;
                end = note[len - 1];
                if ( ( start == end )
                     || ( ( start == '(' ) && ( end == ')' ) )
                     || ( ( start == '<' ) && ( end == '>' ) )
                     || ( ( start == '{' ) && ( end == '}' ) )
                     || ( ( start == '[' ) && ( end == ']' ) ) ) {
                    note[len - 1] = '\0';
                    *note = '\0';
                    note++;
                }
            }
        }
    }
    return note;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* trim_string ( char *  in) [inline, static]

Definition at line 150 of file papi_preset.c.

{
    int len, i = 0;
    char *start = in;

    if ( in == NULL )
        return ( in );
    len = ( int ) strlen( in );
    if ( len == 0 )
        return ( in );

    /* Trim left */
    while ( i < len ) {
        if ( isblank( in[i] ) ) {
            in[i] = '\0';
            start++;
        } else
            break;
        i++;
    }

    /* Trim right */
    i = ( int ) strlen( start ) - 1;
    while ( i >= 0 ) {
        if ( isblank( start[i] ) )
            start[i] = '\0';
        else
            break;
        i--;
    }
    return ( start );
}

Here is the caller graph for this function:


Variable Documentation

char* papi_events_table = NULL [static]

Definition at line 295 of file papi_preset.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines