Пример #1
0
void vt_metric_free(struct vt_metv* metv, uint32_t tid)
{
  int retval, i;
  long_long papi_vals[VT_METRIC_MAXNUM];

  if ( metv == NULL )
    return;

  /* treat PAPI failures at this point as non-fatal */

  VT_SUSPEND_IO_TRACING(tid);

  /* foreach used eventset */
  for (i=0; i < VT_METRIC_MAXNUM && metv->EventSet[i]!=NULL; i++)
  {
    retval = PAPI_stop(metv->EventSet[i]->EventId, papi_vals);
    if ( retval != PAPI_OK ) {
      metric_warning(retval, "PAPI_stop");
    } else { /* cleanup/destroy require successful PAPI_stop */
      retval = PAPI_cleanup_eventset(metv->EventSet[i]->EventId);
      if ( retval != PAPI_OK )
        metric_warning(retval, "PAPI_cleanup_eventset");
      retval = PAPI_destroy_eventset(&metv->EventSet[i]->EventId);
      if ( retval != PAPI_OK )
        metric_warning(retval, "PAPI_destroy_eventset");
    }
    free(metv->EventSet[i]);
  }

  VT_RESUME_IO_TRACING(tid);

  free(metv);
}
Пример #2
0
void vt_metric_read(struct vt_metv* metv, uint64_t offsets[],
                    uint64_t values[])
{
  int retval;
  int i;

  if ( metv == NULL )
    return;

  VT_SUSPEND_IO_TRACING(VT_CURRENT_THREAD);

  /* foreach used eventset */
  for (i=0; i < VT_METRIC_MAXNUM && metv->EventSet[i]!=NULL; i++)
  {
    retval = PAPI_read(metv->EventSet[i]->EventId, metv->EventSet[i]->Values );
    if ( retval != PAPI_OK )
      metric_error(retval, "PAPI_read");
  }

  if ( offsets != NULL )
    for ( i = 0; i < nmetrics; i++ )
      values[i] = (uint64_t) *metv->Values[i] + offsets[i];
  else
    for ( i = 0; i < nmetrics; i++ )
      values[i] = (uint64_t) *metv->Values[i];

  VT_RESUME_IO_TRACING(VT_CURRENT_THREAD);
}
Пример #3
0
uint32_t vt_fork_get_num_childs_tot()
{
  uint32_t nchilds_tot;

  /* any fork performed? (trace-id file exists?) */
  if ( fork_performed )
  {
    int fd;
    char tmp[16] = "";

    vt_libassert(trcid_filename[0] != '\0');

    VT_SUSPEND_IO_TRACING(VT_CURRENT_THREAD);

    /* open temp. id file for reading */
    if ( (fd = open(trcid_filename, O_RDONLY)) == -1 )
      vt_error_msg("Cannot open file %s: %s", trcid_filename, strerror(errno));

    /* read current trace id */
    if ( read(fd, tmp, 16) == -1 )
      vt_error_msg("Cannot read file %s: %s", trcid_filename, strerror(errno));

    vt_libassert(tmp[0] != '\0');
    nchilds_tot = atoi(tmp);
    vt_libassert(nchilds_tot > 0);

    /* close temp. id file */
    close(fd);

    VT_RESUME_IO_TRACING(VT_CURRENT_THREAD);
  }
  else
  {
    nchilds_tot = 0;
  }
  
  return nchilds_tot;
}
Пример #4
0
void vt_sync(MPI_Comm comm, uint64_t* ltime, int64_t* offset)
{
  VT_MPI_INT myrank, myrank_host, myrank_sync;
  VT_MPI_INT numnodes;
  uint64_t time;

  MPI_Comm host_comm;
  MPI_Comm sync_comm;

  VT_SUSPEND_IO_TRACING(VT_CURRENT_THREAD);

  /* mark begin of clock synchronization */
  time = vt_pform_wtime();
  vt_enter(VT_CURRENT_THREAD, &time, vt_trc_regid[VT__TRC_SYNCTIME]);

  /* barrier at entry */
  PMPI_Barrier(comm);

  *offset = 0;
  *ltime = vt_pform_wtime();

  PMPI_Comm_rank(comm, &myrank);

  /* create communicator containing all processes on the same node */

  PMPI_Comm_split(comm, (vt_pform_node_id() & 0x7FFFFFFF), 0, &host_comm);
  PMPI_Comm_rank(host_comm, &myrank_host);

  /* create communicator containing all processes with rank zero in the
     previously created communicators */
  
  PMPI_Comm_split(comm, myrank_host, 0, &sync_comm);
  PMPI_Comm_rank(sync_comm, &myrank_sync);
  PMPI_Comm_size(sync_comm, &numnodes);

  /* measure offsets between all nodes and the root node (rank 0 in sync_comm) */

  if (myrank_host == 0)
  {
    VT_MPI_INT i;

    for (i = 1; i < numnodes; i++)
    {
      PMPI_Barrier(sync_comm);
      if (myrank_sync == i)
	*offset = sync_slave(ltime, 0, sync_comm);
      else if (myrank_sync == 0)
	*offset = sync_master(ltime, i, sync_comm);
    }
  }

  /* distribute offset and ltime across all processes on the same node */

  PMPI_Bcast(offset, 1, MPI_LONG_LONG_INT, 0, host_comm);
  PMPI_Bcast(ltime, 1, MPI_LONG_LONG_INT, 0, host_comm);

  PMPI_Comm_free(&host_comm);
  PMPI_Comm_free(&sync_comm);

  /* barrier at exit */
  PMPI_Barrier(comm);

  /* mark end of clock synchronization */
  time = vt_pform_wtime();
  vt_exit(VT_CURRENT_THREAD, &time);

  VT_RESUME_IO_TRACING(VT_CURRENT_THREAD);
}
Пример #5
0
static void get_symtab(void)
{
  char* nm_cmd = NULL;
  char* nm_filename;
  FILE* nm_stream;

  char* line;
  size_t line_size;
  uint32_t lineno = 0;

  uint8_t parse_error = 0;

  VT_SUSPEND_IO_TRACING(VT_CURRENT_THREAD);

  /* open nm-file, if given */
  nm_filename = vt_env_gnu_nmfile();
  if ( nm_filename != NULL && strlen(nm_filename) > 0 )
  {
    vt_cntl_msg(2, "Collecting symbols from file %s", nm_filename);

    /* open nm-file */
    if ( (nm_stream = fopen(nm_filename, "r")) == NULL )
      vt_error_msg("Could not open symbol list file %s", nm_filename);
  }
  /* otherwise, try to get symbol table automatically */
  else
  {
    char* apppath;
    char* nm;
    size_t nm_cmd_len;

    vt_cntl_msg(2, "Collecting symbols by 'nm'");

    /* get executable path specified by VT_APPPATH */
    apppath = vt_env_apppath();
    if ( apppath == NULL || strlen(apppath) == 0 )
    {
      vt_error_msg("Could not determine path of executable.\n"
                   "Please set the environment variable VT_APPPATH to the path "
                   "of your executable or set VT_GNU_NMFILE to a symbol list "
                   "file created with 'nm'.");
    }

    /* get nm command specified by VT_GNU_NM */
    nm = vt_env_gnu_nm();
    if ( nm == NULL )
    {
      vt_error_msg("VampirTrace was configured without an 'nm' command.\n"
                   "Please set the environment variable VT_GNU_NM to the 'nm' "
                   "command including command line switches which lists "
                   "symbol/addresses of an object file in BSD-style or set "
                   "VT_GNU_NMFILE to a pre-created symbol list file." );
    }

    /* allocate memory for nm command */
    nm_cmd_len = strlen(nm) + 1 + strlen(apppath) + 1;
    nm_cmd = (char*)malloc(nm_cmd_len * sizeof(char));
    if ( nm_cmd == NULL )
      vt_error();

    /* compose nm command */
    snprintf(nm_cmd, nm_cmd_len, "%s %s", nm, apppath);

    /* execute nm command */
    vt_cntl_msg(2, "Executing %s", nm_cmd);
    nm_stream = popen(nm_cmd, "r");
    /* error handling after pclose below */

    nm_filename = NULL;
  }

  /* allocate memory for lines */
  line = (char*)malloc(NM_LINE_BLK_LEN * sizeof(char));
  if ( line == NULL )
    vt_error();
  line_size = NM_LINE_BLK_LEN;

  /* read lines */

  while( nm_stream != NULL && fgets(line, line_size, nm_stream) )
  {
    char* col;
    char  delim[2] = " ";
    int   nc = 1;

    long  addr = -1;
    char* filename = NULL;
    char* funcname = NULL;
    unsigned int lno = VT_NO_LNO;

    lineno++;

    /* trigger a parse error, if line is empty */
    if ( strlen(line) == 0 )
    {
      parse_error = 1;
      break;
    }

    /* if line seems to be incomplete, enlarge line buffer and read the
       remaining line */
    while( !parse_error && line[strlen(line)-1] != '\n' )
    {
      char tmp[NM_LINE_BLK_LEN];

      /* read the remaining line; if it fails (EOF) the line seems to
         be complete after all */
      if ( !fgets(tmp, sizeof(tmp), nm_stream) )
        break;

      /* trigger a parse error, if line is to long (>NM_LINE_MAX_LEN) */
      if ( line_size + NM_LINE_BLK_LEN > NM_LINE_MAX_LEN )
      {
        parse_error = 1;
        break;
      }

      /* enlarge line buffer */
      line = (char*)realloc(line, (line_size + NM_LINE_BLK_LEN) * sizeof(char));
      if ( line == NULL )
        vt_error();
      line_size += NM_LINE_BLK_LEN;

      /* complete line */
      strcat(line, tmp);
    }
    if ( parse_error )
      break;

    /* chop new-line character from line */
    if ( line[strlen(line)-1] == '\n' )
      line[strlen(line)-1] = '\0';

    /* split line to columns */
    col = strtok(line, delim);
    do
    {
      if ( nc == 1 ) /* column 1 (address) */
      {
        /* if there is no address in the first column the symbol could be
           undefined; try get its address later (nc==3) */
        if ( strlen(col) == 1 )
        {
          nc++; /* <- will be 3 in the next round */
          strcpy(delim, "\t");
        }
        /* otherwise, convert address string */
        else
        {
          addr = strtol(col, NULL, 16);
        }
      }
      else if ( nc == 2 ) /* column 2 (type) */
      {
        /* type must have a length of 1 */
        if ( strlen(col) != 1 )
        {
          parse_error = 1;
          break;
        }
        strcpy(delim, "\t");
      }
      else if ( nc == 3 ) /* column 3 (symbol) */
      {
        funcname = col;
        strcpy(delim, ":");

        /* try to get address of undefined function, if necessary */
        if ( addr == -1 )
          addr = (long)GET_ADDR_OF_UNDEF_FUNC(funcname);

        /* ignore function, if its address could not be determined */
        if ( addr == 0 )
          break;
      }
      else if( nc == 4 ) /* column 4 (filename) */
      {
        filename = col;
      }
      else /* column 5 (line) */
      {
        lno = atoi(col);
        if( lno == 0 ) lno = VT_NO_LNO;
        break;
      }

      nc++;
      col = strtok(0, delim);
    } while( col );

    /* stop reading file, if an parse error occurred */
    if ( parse_error )
    {
      break;
    }
    /* at least two columns must be read */
    else if ( nc < 3 )
    {
      parse_error = 1;
      break;
    }
    /* add symbol to hash table, if we have its address and name */
    else if ( addr > 0 && funcname )
    {
      char* n = strdup(funcname);
      char* p;

      if ( n == NULL )
        vt_error();

      /* chop function name at '??', if necessary */
      p = strstr(n, "??");
      if ( p != NULL && p != n )
        *p = '\0';

      hash_put(addr, n, filename, lno);
    }
  }

  /* close file/pipe stream */

  if ( nm_filename != NULL )
  {
    fclose(nm_stream);

    if ( parse_error )
    {
      vt_error_msg("%s:%u: could not be parsed.\n"
                   "Please check the content of %s for BSD-style.",
                   nm_filename, lineno, nm_filename);
    }
  }
  else
  {
    uint8_t nmcmd_error = (nm_stream == NULL || pclose(nm_stream) != 0);

    if ( parse_error )
    {
      vt_error_msg("Could not parse 'nm' output created with %s.\n"
                   "Please set the environment variable VT_GNU_NM to the 'nm' "
                   "command including command line switches which lists "
                   "symbol/addresses of an object file in BSD-style or set "
                   "VT_GNU_NMFILE to a pre-created symbol list file.",
                   nm_cmd);
    }
    else if ( nmcmd_error )
    {
      vt_error_msg("Failed to execute %s\n"
                   "Please set the environment variable VT_GNU_NM to the 'nm' "
                   "command including command line switches which lists "
                   "symbol/addresses of an object file in BSD-style or set "
                   "VT_GNU_NMFILE to a pre-created symbol list file.",
                   nm_cmd);
    }

    free(nm_cmd);
  }

  free(line);

  VT_RESUME_IO_TRACING(VT_CURRENT_THREAD);
}
Пример #6
0
void vt_esync(MPI_Comm comm)
{
  uint64_t time, etime;
  Sync_TsPerRun* temp_ts;
  Sync_Map* temp_map;

  VT_MPI_INT myrank;
  VT_MPI_INT numnodes;
  VT_MPI_INT partnerid, numslots;
  VT_MPI_INT i;

  VT_SUSPEND_IO_TRACING();

  /* mark begin of clock synchronization */
  time = vt_pform_wtime();
  vt_enter(&time, vt_trc_regid[VT__TRC_SYNCTIME]);
  /* ... also as comment for vtunify */
  vt_comment(&time, "__ETIMESYNC__");

  /* barrier at entry */
  PMPI_Barrier(comm);

  temp_ts = (Sync_TsPerRun*) malloc(sizeof(Sync_TsPerRun));
  if (temp_ts == NULL) vt_error();

  temp_ts->sync_phase = NULL;
  temp_ts->next       = NULL;

  if (SyncTsPerRunFirst == NULL)
  {
    SyncTsPerRunFirst = temp_ts;
    SyncTsPerRunLast  = temp_ts;
  }
  else
  {
    SyncTsPerRunLast->next = temp_ts;    
    SyncTsPerRunLast = temp_ts;
  }

  /* measure time synchronization */

  PMPI_Comm_rank(comm, &myrank);
  PMPI_Comm_size(comm, &numnodes);

  numslots = (VT_MPI_INT)ceil(log((double)(numnodes)) / log(2.0));

  for(i = 0; i < numslots; i++)
  {
    partnerid = esync_commpartner(myrank, numnodes, i);
    if( partnerid < numnodes )
    {
      if( myrank < partnerid )
      {
	esync_master(partnerid, comm, myrank);
      }
      else
      {
	esync_slave(partnerid, comm);
      }
    }
  }
   
  /* add myrank to list of map ids */

  temp_map = (Sync_Map*)malloc(sizeof(Sync_Map));
  if (temp_map == NULL) vt_error();
  temp_map->id       = myrank;
  temp_map->time     = time;
  temp_map->duration = (uint32_t) 0;
  temp_map->next     = NULL;

  if (SyncMapIdFirst == NULL)
  {
    SyncMapIdFirst = temp_map;
    SyncMapIdLast = temp_map;
  }
  else
  {
    SyncMapIdLast->next = temp_map;
    SyncMapIdLast = temp_map;
  }

  /* barrier at exit */
  PMPI_Barrier(comm);

  /* mark end of clock synchronization */
  etime = vt_pform_wtime();
  vt_exit(&etime);

  /* increment number of sync. phases */
  SyncRound++;

  /* set timestamp of next synchronization if necessary */
  if (SyncNext != (uint64_t)-1)
    SyncNext = etime + SyncIntv;

  /* calculate sync. duration */
  SyncMapIdLast->duration = etime - time;

  VT_RESUME_IO_TRACING();
}
Пример #7
0
static int get_new_trcid()
{
  int new_trcid;
  int fd;
  int8_t tmp_len;
  struct flock fl;
  char tmp[10] = "";
  uint8_t do_unlock = 1;

  vt_libassert(trcid_filename[0] != '\0');

  VT_SUSPEND_IO_TRACING(VT_CURRENT_THREAD);

  /* open/create temp. id file */
  if ( (fd = open(trcid_filename,
		  (O_RDWR | O_CREAT),
		  (S_IRUSR | S_IWUSR))) == -1 )
    vt_error_msg("Cannot open file %s: %s", trcid_filename, strerror(errno));

  /* lock temp. id file */
  fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0;
  if (fcntl(fd, F_SETLKW, &fl) == -1)
  {
    do_unlock = 0;
    vt_warning("Cannot lock file %s: %s", trcid_filename, strerror(errno));
  }

  /* read current trace id */
  if ( read(fd, tmp, 9) == -1 )
    vt_error_msg("Cannot read file %s: %s", trcid_filename, strerror(errno));
  tmp[9] = '\0';

  if ( tmp[0] == '\0' )
    new_trcid = 1;             /* set trace id to 1, if file is empty */
  else
    new_trcid = atoi(tmp) + 1; /* increment trace id */

  /* write new trace id */
  lseek(fd, 0, SEEK_SET);
  snprintf(tmp, sizeof(tmp)-1, "%i\n", new_trcid);
  tmp_len = strlen( tmp );
  if( tmp_len > write( fd, tmp, tmp_len ) ){
    vt_error_msg( "Failed to write to file %s: %s", trcid_filename,strerror(errno) );
  }

  /* unlock temp. id file */
  if ( do_unlock )
  {
    fl.l_type = F_UNLCK;
    if ( fcntl(fd, F_SETLK, &fl) == -1 )
      vt_error_msg("Cannot unlock file %s: %s", trcid_filename, strerror(errno));
  }

  /* close temp. id file */
  close(fd);

  vt_cntl_msg(2, "Updated trace-id in %s to %i", trcid_filename, new_trcid);

  VT_RESUME_IO_TRACING(VT_CURRENT_THREAD);

  return new_trcid;
}