papi_bipartite.h File Reference

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

static int _bpt_map_avail (hwd_reg_alloc_t *dst, int ctr)
static void _bpt_map_set (hwd_reg_alloc_t *dst, int ctr)
static int _bpt_map_exclusive (hwd_reg_alloc_t *dst)
static int _bpt_map_shared (hwd_reg_alloc_t *dst, hwd_reg_alloc_t *src)
static void _bpt_map_preempt (hwd_reg_alloc_t *dst, hwd_reg_alloc_t *src)
static void _bpt_map_update (hwd_reg_alloc_t *dst, hwd_reg_alloc_t *src)
static int _papi_bipartite_alloc (hwd_reg_alloc_t *event_list, int count, int cidx)

Function Documentation

static int _bpt_map_avail ( hwd_reg_alloc_t dst,
int  ctr 
) [static]

Here is the caller graph for this function:

static int _bpt_map_exclusive ( hwd_reg_alloc_t dst  )  [static]

Here is the caller graph for this function:

static void _bpt_map_preempt ( hwd_reg_alloc_t dst,
hwd_reg_alloc_t src 
) [static]

Here is the caller graph for this function:

static void _bpt_map_set ( hwd_reg_alloc_t dst,
int  ctr 
) [static]

Here is the caller graph for this function:

static int _bpt_map_shared ( hwd_reg_alloc_t dst,
hwd_reg_alloc_t src 
) [static]

Here is the caller graph for this function:

static void _bpt_map_update ( hwd_reg_alloc_t dst,
hwd_reg_alloc_t src 
) [static]

Here is the caller graph for this function:

static int _papi_bipartite_alloc ( hwd_reg_alloc_t event_list,
int  count,
int  cidx 
) [static]

Definition at line 60 of file papi_bipartite.h.

00061 {
00062     int i, j;
00063     char *ptr = ( char * ) event_list;
00064     int idx_q[count];                  /* queue of indexes of lowest rank events */
00065     int map_q[count];                  /* queue of mapped events (TRUE if mapped) */
00066     int head, tail;
00067     int size = _papi_hwd[cidx]->size.reg_alloc;
00068 
00069     /* build a queue of indexes to all events 
00070        that live on one counter only (rank == 1) */
00071     head = 0;                /* points to top of queue */
00072     tail = 0;                /* points to bottom of queue */
00073     for ( i = 0; i < count; i++ ) {
00074         map_q[i] = 0;
00075         if ( _bpt_map_exclusive( ( hwd_reg_alloc_t * ) & ptr[size * i] ) )
00076             idx_q[tail++] = i;
00077     }
00078     /* scan the single counter queue looking for events that share counters.
00079        If two events can live only on one counter, return failure.
00080        If the second event lives on more than one counter, remove shared counter
00081        from its selector and reduce its rank. 
00082        Mark first event as mapped to its counter. */
00083     while ( head < tail ) {
00084         for ( i = 0; i < count; i++ ) {
00085             if ( i != idx_q[head] ) {
00086                 if ( _bpt_map_shared( ( hwd_reg_alloc_t * ) & ptr[size * i],
00087                                      ( hwd_reg_alloc_t * ) & ptr[size *
00088                                                                  idx_q
00089                                                                  [head]] ) ) {
00090                     /* both share a counter; if second is exclusive, mapping fails */
00091                     if ( _bpt_map_exclusive( ( hwd_reg_alloc_t * ) &
00092                                             ptr[size * i] ) )
00093                         return 0;
00094                     else {
00095                         _bpt_map_preempt( ( hwd_reg_alloc_t * ) &
00096                                              ptr[size * i],
00097                                              ( hwd_reg_alloc_t * ) & ptr[size *
00098                                                                          idx_q
00099                                                                          [head]] );
00100                         if ( _bpt_map_exclusive( ( hwd_reg_alloc_t * ) &
00101                                                 ptr[size * i] ) )
00102                             idx_q[tail++] = i;
00103                     }
00104                 }
00105             }
00106         }
00107         map_q[idx_q[head]] = 1; /* mark this event as mapped */
00108         head++;
00109     }
00110     if ( tail == count ) {
00111         return 1;            /* idx_q includes all events; everything is successfully mapped */
00112     } else {
00113         char *rest_event_list;
00114         char *copy_rest_event_list;
00115         int remainder;
00116 
00117         rest_event_list =
00118             papi_calloc(  _papi_hwd[cidx]->cmp_info.num_cntrs, 
00119                       size );
00120 
00121         copy_rest_event_list =
00122                 papi_calloc( _papi_hwd[cidx]->cmp_info.num_cntrs,
00123                      size );
00124 
00125         if ( !rest_event_list || !copy_rest_event_list ) {
00126             if ( rest_event_list )
00127                 papi_free( rest_event_list );
00128             if ( copy_rest_event_list )
00129                 papi_free( copy_rest_event_list );
00130             return ( 0 );
00131         }
00132 
00133         /* copy all unmapped events to a second list and make a backup */
00134         for ( i = 0, j = 0; i < count; i++ ) {
00135             if ( map_q[i] == 0 ) {
00136                 memcpy( &copy_rest_event_list[size * j++], &ptr[size * i],
00137                         ( size_t ) size );
00138             }
00139         }
00140         remainder = j;
00141 
00142         memcpy( rest_event_list, copy_rest_event_list,
00143                 ( size_t ) size * ( size_t ) remainder );
00144 
00145         /* try each possible mapping until you fail or find one that works */
00146         for ( i = 0; i < _papi_hwd[cidx]->cmp_info.num_cntrs; i++ ) {
00147             /* for the first unmapped event, try every possible counter */
00148             if ( _bpt_map_avail( ( hwd_reg_alloc_t * ) rest_event_list, i ) ) {
00149                  _bpt_map_set( ( hwd_reg_alloc_t * ) rest_event_list, i );
00150                 /* remove selected counter from all other unmapped events */
00151                 for ( j = 1; j < remainder; j++ ) {
00152                     if ( _bpt_map_shared( ( hwd_reg_alloc_t * ) &
00153                                          rest_event_list[size * j],
00154                                          ( hwd_reg_alloc_t * )
00155                                          rest_event_list ) )
00156                         _bpt_map_preempt( ( hwd_reg_alloc_t * ) &
00157                                              rest_event_list[size * j],
00158                                              ( hwd_reg_alloc_t * )
00159                                              rest_event_list );
00160                 }
00161                 /* if recursive call to allocation works, break out of the loop */
00162                 if ( _papi_bipartite_alloc
00163                      ( ( hwd_reg_alloc_t * ) rest_event_list, remainder,
00164                        cidx ) )
00165                     break;
00166 
00167                 /* recursive mapping failed; copy the backup list and try the next combination */
00168                 memcpy( rest_event_list, copy_rest_event_list,
00169                         ( size_t ) size * ( size_t ) remainder );
00170             }
00171         }
00172         if ( i == _papi_hwd[cidx]->cmp_info.num_cntrs ) {
00173             papi_free( rest_event_list );
00174             papi_free( copy_rest_event_list );
00175             return 0;        /* fail to find mapping */
00176         }
00177         for ( i = 0, j = 0; i < count; i++ ) {
00178             if ( map_q[i] == 0 )
00179                 _bpt_map_update( ( hwd_reg_alloc_t * ) & ptr[size * i],
00180                                     ( hwd_reg_alloc_t * ) & rest_event_list[size
00181                                                                             *
00182                                                                             j++] );
00183         }
00184         papi_free( rest_event_list );
00185         papi_free( copy_rest_event_list );
00186         return 1;
00187     }
00188 }

Here is the call graph for this function:

Here is the caller graph for this function:


Generated on 8 Sep 2016 for PAPI by  doxygen 1.6.1