void vt_rusage_init()
{
  uint32_t gid;
  uint32_t i;

  /* allocate vector of counter ids */
  vt_rusage_cidv = (uint32_t*)calloc(ru_active_cntrn, sizeof(uint32_t));
  if ( vt_rusage_cidv == NULL )
    vt_error();

  /* write counter group name definition */
  gid = vt_def_counter_group(VT_CURRENT_THREAD, "Resources");

  /* write counter definition for active counters */
  for ( i = 0; i < ru_active_cntrn; i++ )
  {
    vt_rusage_cidv[i] =
      vt_def_counter(VT_CURRENT_THREAD,
		     ru_active_cntrv[i]->name,
		     ru_active_cntrv[i]->unit,
		     ru_active_cntrv[i]->prop,
		     gid,
		     0);
  }
}
Beispiel #2
0
void vt_getcpu_init()
{
  vt_assert(vt_misc_cgid != 0);

  /* write counter definition */
  vt_getcpu_cid = vt_def_counter(VT_CURRENT_THREAD, "CPU_ID",
                                 VT_CNTR_ABS | VT_CNTR_NEXT,
                                 vt_misc_cgid, "#");
}
Beispiel #3
0
void vt_memhook_init()
{
  uint32_t fid;
  uint32_t gid;

#if (defined(VT_MT) || defined(VT_HYB) || defined(VT_JAVA))
  vt_error_msg("Memory tracing by GNU C malloc-hooks for threaded application "
               "not yet supported");
#endif /* VT_MT || VT_HYB || VT_JAVA */

  if( vt_memhook_is_initialized ) return;

  vt_malloc_hook_org = __malloc_hook;
  vt_realloc_hook_org = __realloc_hook;
  vt_free_hook_org = __free_hook;

  /* define source */
  fid = vt_def_scl_file(VT_CURRENT_THREAD, "MEM");

  /* define regions */
  memhook_regid[MEMHOOK_REG_MALLOC] =
    vt_def_region(VT_CURRENT_THREAD, "malloc", fid, VT_NO_LNO, VT_NO_LNO, NULL,
                  VT_MEMORY);
  memhook_regid[MEMHOOK_REG_REALLOC] =
    vt_def_region(VT_CURRENT_THREAD, "realloc", fid, VT_NO_LNO, VT_NO_LNO, NULL,
                  VT_MEMORY);
  memhook_regid[MEMHOOK_REG_FREE] =
    vt_def_region(VT_CURRENT_THREAD, "free", fid, VT_NO_LNO, VT_NO_LNO, NULL,
                  VT_MEMORY);

  /* define markers, if necessary */
  if( (memalloc_marker = vt_env_memtrace_marker()) )
  {
    memalloc_mid[MEMHOOK_MARK_ALLOC] =
      vt_def_marker(VT_CURRENT_THREAD, "Memory Allocation", VT_MARKER_HINT);
    memalloc_mid[MEMHOOK_MARK_FREE] =
      vt_def_marker(VT_CURRENT_THREAD, "Memory Deallocation", VT_MARKER_HINT);
  }

  /* define counter group */
  gid = vt_def_counter_group(VT_CURRENT_THREAD, "Memory");

  /* define counter */
  memalloc_cid =
    vt_def_counter(VT_CURRENT_THREAD, "MEM_ALLOC",
                   VT_CNTR_ABS | VT_CNTR_NEXT,
                   gid, "Bytes");

  vt_memhook_is_initialized = 1;
}
void vt_mallocwrap_init()
{
  /* define memory related counter group */
  mallocwrap_counter_group_id =
    vt_def_counter_group(VT_CURRENT_THREAD, "Memory");

  /* define memory allocation counter */
  mallocwrap_counter_id =
    vt_def_counter(VT_CURRENT_THREAD, "Memory Allocation", "Bytes",
      VT_CNTR_ABS | VT_CNTR_NEXT, mallocwrap_counter_group_id, 0);

  /* define memory (de)allocation markers, if desired
     (env. VT_MEMTRACE_MARKER) */
  if( (mallocwrap_write_markers = vt_env_memtrace_marker()) )
  {
    mallocwrap_marker_alloc_id =
      vt_def_marker(VT_CURRENT_THREAD, "Memory Allocation", VT_MARKER_HINT);
    mallocwrap_marker_free_id =
      vt_def_marker(VT_CURRENT_THREAD, "Memory Deallocation", VT_MARKER_HINT);
  }
}
/*
 * Parse the environment variable for CUPTI metrics (including CUDA device
 * capabilities) and fill the capability metric list.
 *
 * @param capList points to the first element of the capability metric list
 */
static void vt_cupti_fillMetricList(vt_cupti_device_t *capList)
{
  char *metricString = vt_env_cupti_events();
  char *metric_sep = vt_env_metrics_sep();
  char *metric, *metric_cap;

  metric = strtok(metricString, metric_sep);

  while (metric != NULL){
    CUptiResult cuptiErr = CUPTI_SUCCESS;
    vt_cupti_device_t *cuptiDev = NULL;
    vt_cupti_evtctr_t *vtcuptiEvt = NULL;
    int metr_major = 0;
    int metr_minor = 0;

    /* try to get CUDA device capability parsed from metric */
    metr_major = atoi(metric);
    metric_cap = strchr(metric+1, '.');
    if(metric_cap){
      metr_minor = atoi(metric_cap+1);
      metric_cap = strchr(metric_cap+1, '_');
    }
    
    /* check whether device capability is given or not */
    if(metric_cap){
      metric = metric_cap + 1;

      vt_cntl_msg(2, "Metric '%s', %d.%d", metric, metr_major, metr_minor);

      cuptiDev = vt_cupti_checkMetricList(capList, metr_major, metr_minor);
      if(cuptiDev == NULL){
        metric = strtok(NULL, metric_sep);
        continue;
      }
      
      vtcuptiEvt = (vt_cupti_evtctr_t*)malloc(sizeof(vt_cupti_evtctr_t));
      cuptiErr = cuptiEventGetIdFromName(cuptiDev->cuDev, metric,
                                         &vtcuptiEvt->cuptiEvtID);
      if(cuptiErr != CUPTI_SUCCESS){
        if(!strncmp(metric, "help", 4)) vt_cupti_showAllCounters(capList);
        vt_warning("[CUPTI Events] Skipping invalid event '%s' for device %d",
                   metric, cuptiDev->cuDev);
        metric = strtok(NULL, metric_sep);
        continue;
      }

      /* create VampirTrace counter ID */
#if (defined(VT_MT) || defined(VT_HYB))
      VTTHRD_LOCK_IDS();
#endif
      vtcuptiEvt->vtCID = vt_def_counter(VT_MASTER_THREAD, metric, "#",
            VT_CNTR_ABS | VT_CNTR_LAST | VT_CNTR_UNSIGNED, vt_cuptievt_cgid, 0);
#if (defined(VT_MT) || defined(VT_HYB))
      VTTHRD_UNLOCK_IDS();
#endif

      cuptiDev->evtNum++;
      vtcuptiEvt->next = cuptiDev->vtcuptiEvtList;
      cuptiDev->vtcuptiEvtList = vtcuptiEvt;
    }else{ 
      /* device capability is not given. Try to add metric to all devices */
      uint32_t cid_metric = VT_NO_ID;

      cuptiDev = capList;
      while(cuptiDev != NULL){
        vtcuptiEvt = (vt_cupti_evtctr_t*)malloc(sizeof(vt_cupti_evtctr_t));
        cuptiErr = cuptiEventGetIdFromName(cuptiDev->cuDev, metric,
                                           &vtcuptiEvt->cuptiEvtID);

        if(cuptiErr != CUPTI_SUCCESS){
          if(!strncmp(metric, "help", 4)) vt_cupti_showAllCounters(capList);
          vt_warning("[CUPTI Events] Skipping invalid event '%s' for device %d",
                     metric, cuptiDev->cuDev);
        }else{
          /* create VampirTrace counter ID, if not yet done for other device */
          if(cid_metric == VT_NO_ID){
#if (defined(VT_MT) || defined(VT_HYB))
      VTTHRD_LOCK_IDS();
#endif
      cid_metric = vt_def_counter(VT_MASTER_THREAD, metric, "#", 
            VT_CNTR_ABS | VT_CNTR_LAST | VT_CNTR_UNSIGNED, vt_cuptievt_cgid, 0);
#if (defined(VT_MT) || defined(VT_HYB))
      VTTHRD_UNLOCK_IDS();
#endif
          }
          
          cuptiDev->evtNum++;
          vtcuptiEvt->vtCID = cid_metric;
          vtcuptiEvt->next = cuptiDev->vtcuptiEvtList;
          cuptiDev->vtcuptiEvtList = vtcuptiEvt;
        }

        cuptiDev = cuptiDev->next;
      }
    }

    metric = strtok(NULL, metric_sep);
  }
}
Beispiel #6
0
unsigned int VT_User_count_def__(const char* cname, const char* cunit, int ctype,
				 unsigned int gid)
{
  uint32_t cid;
  uint32_t cprop = VT_CNTR_ABS | VT_CNTR_NEXT;

  VT_INIT;

  VT_MEMHOOKS_OFF();

  if (gid == (uint32_t)VT_COUNT_DEFGROUP)
  {
    if (def_gid == 0)
      def_gid = VT_User_count_group_def__("User");

    gid = def_gid;
  }

  switch(ctype)
  {
    case VT_COUNT_TYPE_SIGNED:
    case VT_COUNT_TYPE_INTEGER:
    case VT_COUNT_TYPE_INTEGER8:
    {
      cprop |= VT_CNTR_SIGNED;
      break;
    }
    case VT_COUNT_TYPE_UNSIGNED:
    {
      cprop |= VT_CNTR_UNSIGNED;
      break;
    }
    case VT_COUNT_TYPE_FLOAT:
    case VT_COUNT_TYPE_REAL:
    {
      cprop |= VT_CNTR_FLOAT;
      break;
    }
    case VT_COUNT_TYPE_DOUBLE:
    {
      cprop |= VT_CNTR_DOUBLE;
      break;
    }
    default:
    {
      vt_error_msg("Unknown counter type %i", ctype);
      break;
    }
  }

#if (defined(VT_MT) || defined(VT_HYB))
  VTTHRD_LOCK_IDS();
#endif
  cid = vt_def_counter(VT_CURRENT_THREAD, cname, cprop, gid, cunit);
#if (defined(VT_MT) || defined(VT_HYB))
  VTTHRD_UNLOCK_IDS();
#endif

    VT_MEMHOOKS_ON();

    return cid;
}
/* no need to lock, because it is only called by vt_cupti_callback_init() */
void vt_cupti_activity_init()
{
  /*if(!vt_cuptiact_initialized){
    vt_cupti_init();
    VT_CUPTI_LOCK();*/
    if(!vt_cuptiact_initialized){
      vt_cntl_msg(2, "[CUPTI Activity] Initializing ... ");
      
      {        
        vt_cuptiact_bufSize = vt_env_cudatrace_bsize();
        
        /* no buffer size < 1024 bytes allowed (see CUPTI documentation) */
        if(vt_cuptiact_bufSize < 1024){
          if(vt_cuptiact_bufSize > 0){
            vt_warning("[CUPTI Activity] Buffer size has to be at least 1024 "
                       "bytes! It has been set to %d.", vt_cuptiact_bufSize);
          }
          vt_cuptiact_bufSize = VT_CUPTI_ACT_DEFAULT_BSIZE;
        }
        
        /* queue a global buffer to initialize CUPTI before CUDA init 
        vt_cuptiact_buffer = (uint8_t *)malloc(vt_cuptiact_bufSize);
        VT_CUPTI_CALL(cuptiActivityEnqueueBuffer(NULL, 0, 
                                      vt_cuptiact_buffer, vt_cuptiact_bufSize), 
                      "cuptiActivityEnqueueBuffer");*/
      }
      
#if (defined(VT_MT) || defined(VT_HYB))
      VTTHRD_LOCK_IDS();
#endif
      if(vt_gpu_trace_kernels > 1){
        /* define kernel counters */
        vt_cuptiact_cid_knStaticSharedMem = vt_def_counter(VT_MASTER_THREAD, 
                      "staticSharedMemory", "Bytes",
                      VT_CNTR_ABS | VT_CNTR_NEXT | VT_CNTR_UNSIGNED, 
                      vt_cupti_cgid_cuda_kernel, 0);
        vt_cuptiact_cid_knDynamicSharedMem = vt_def_counter(VT_MASTER_THREAD, 
                      "dynamicSharedMemory", "Bytes",
                      VT_CNTR_ABS | VT_CNTR_NEXT | VT_CNTR_UNSIGNED, 
                      vt_cupti_cgid_cuda_kernel, 0);
        vt_cuptiact_cid_knLocalMemTotal = vt_def_counter(VT_MASTER_THREAD, 
                      "localMemoryPerKernel", "Bytes",
                      VT_CNTR_ABS | VT_CNTR_NEXT | VT_CNTR_UNSIGNED, 
                      vt_cupti_cgid_cuda_kernel, 0);
        vt_cuptiact_cid_knRegistersPerThread = vt_def_counter(VT_MASTER_THREAD, 
                      "registersPerThread", "#",
                      VT_CNTR_ABS | VT_CNTR_NEXT | VT_CNTR_UNSIGNED, 
                      vt_cupti_cgid_cuda_kernel, 0);
      }
     
      /* define region for GPU activity flush */
      vt_cuptiact_rid_flush = vt_def_region(VT_MASTER_THREAD, "flushActivities", 
                        VT_NO_ID, VT_NO_LNO, VT_NO_LNO, "VT_CUDA", VT_FUNCTION);
#if (defined(VT_MT) || defined(VT_HYB))
      VTTHRD_UNLOCK_IDS();
#endif
      
      /*** enable the activities ***/
      /* enable kernel tracing */
      if(vt_gpu_trace_kernels > 0){
#if (defined(CUPTI_API_VERSION) && (CUPTI_API_VERSION >= 3))
        if((vt_gpu_config & VT_GPU_TRACE_CONCURRENT_KERNEL) 
           == VT_GPU_TRACE_CONCURRENT_KERNEL){
          /*VT_CUPTI_CALL(cuptiActivityEnable(CUPTI_ACTIVITY_KIND_KERNEL), 
                        "cuptiActivityEnable");*/
          VT_CUPTI_CALL(cuptiActivityEnable(CUPTI_ACTIVITY_KIND_CONCURRENT_KERNEL), 
                        "cuptiActivityEnable");
        }else
#endif
          VT_CUPTI_CALL(cuptiActivityEnable(CUPTI_ACTIVITY_KIND_KERNEL), 
                        "cuptiActivityEnable");
      }
      
      /* enable memory copy tracing */
      if(vt_gpu_trace_mcpy){
        VT_CUPTI_CALL(cuptiActivityEnable(CUPTI_ACTIVITY_KIND_MEMCPY), 
                      "cuptiActivityEnable");
      }
      
      /* register the finalize function of VampirTrace CUPTI to be called before
       * the program exits 
      atexit(vt_cupti_activity_finalize);*/

      vt_cuptiact_initialized = 1;
      /*VT_CUPTI_UNLOCK();
    }*/
  }
}
void vt_plugin_cntr_init() {
  char ** plugins;
  int nr_selected_plugins = 0;
  char * plugin_read_start;
  int read_plugin;
  char * current_plugin;

  char * env_vt_plugin_metrics;
  char current_plugin_metric[255];
  char * next_plugin_metric;

  char * env_vt_callback_buffer;

  char buffer[512];

  char * dl_lib_error;

  void * handle;
  vt_plugin_cntr_info info;

  /* used union to get rid of compiler warning */
  union {
    void * vp;
    vt_plugin_cntr_info (* function)(void);

  } get_info;

  int index;
  int i;
  int found = 0;

  struct vt_plugin * current;

  /* set some internal variables to zero */
  vt_plugin_handles = calloc(VT_PLUGIN_CNTR_SYNCH_TYPE_MAX,
      sizeof(struct vt_plugin *));
  nr_plugins = calloc(VT_PLUGIN_CNTR_SYNCH_TYPE_MAX, sizeof(uint32_t));

  /* check whether plugins are activated */
  env_vt_plugin_metrics = getenv("VT_PLUGIN_CNTR_METRICS");
  if (env_vt_plugin_metrics == NULL)
    return;

  env_vt_callback_buffer = getenv("VT_PLUGIN_CNTR_CALLBACK_BUFFER");
  /* default: 1 M elements (16 MiB memory) per thread and callback counter */
  if (env_vt_callback_buffer == NULL)
    max_values_callback = 1024 * 1024;
  else
    max_values_callback = atoi(env_vt_callback_buffer);

  /* extract the plugin names */
  plugin_read_start = env_vt_plugin_metrics;
  read_plugin = 1;
  current_plugin = plugin_read_start;
  plugins = NULL;
  /* go through the plugin env. variable */
  for (; *current_plugin != '\0'; current_plugin++) {
    if (read_plugin) {
      if (*current_plugin == '_') {
        /* do not use the same plugin twice! */
        memcpy(buffer, plugin_read_start,
            ((current_plugin - plugin_read_start)) * sizeof(char));
        buffer[(current_plugin - plugin_read_start)] = '\0';
        found = 0;
        for (i = 0; i < nr_selected_plugins; i++) {
          if (strcmp(buffer, plugins[i]) == 0)
            found = 1;
        }
        if (found) {
          read_plugin = 0;
          continue;
        } else {
          nr_selected_plugins++;
          /* allocate the plugin name buffer */
          plugins = realloc(plugins, nr_selected_plugins * sizeof(char*));
          plugins[nr_selected_plugins - 1] = malloc(
              (current_plugin - plugin_read_start + 1) * sizeof(char));
          /* copy the content to the buffer */
          memcpy(plugins[nr_selected_plugins - 1], plugin_read_start,
              ((current_plugin - plugin_read_start)) * sizeof(char));
          /* finish with null */
          plugins[nr_selected_plugins - 1]
                 [(current_plugin - plugin_read_start)] = '\0';
          read_plugin = 0;
        }
      }
    } else {
      /* a new plugin/counter starts after the ':' */
      if (*current_plugin == ':') {
        read_plugin = 1;
        plugin_read_start = current_plugin + 1;
      }
    }
  }
  /*go through all plugins:*/
  for (i = 0; i < nr_selected_plugins; i++) {
    uint32_t group = 0;
    current_plugin = plugins[i];
    vt_cntl_msg(2, "Loading plugin counter library: lib%s.so", current_plugin);
    /* next one is stored in next_plugin,
     / * current is stored in current_plugin_buffer */
    /* load it from LD_LIBRARY_PATH*/
    sprintf(buffer, "lib%s.so", current_plugin);

    /* now dlopen it */
    handle = dlopen(buffer, RTLD_NOW);

    /* if it is not valid */
    if ((dl_lib_error = dlerror()) != NULL) {
      vt_error_msg("Error loading plugin: %s\n", dl_lib_error);
      /* try loading next */
      continue;
    }

    /* now get the info */
    get_info.vp = dlsym(handle, "get_info");
    if ((dl_lib_error = dlerror()) != NULL) {
      vt_error_msg("Error getting info from plugin: %s\n", dl_lib_error);
      dlclose(handle);
      /* try loading next */
      continue;
    }

    /* now store it */

    /* get the info */
    info = get_info.function();

    /* check the run per type */

    if (info.run_per == VT_PLUGIN_CNTR_PER_PROCESS) {
      if (thread_group == INVALID_GROUP_NUMBER){
        vt_cntl_msg(3, "No process group defined, using master thread for %s",
            current_plugin);
      }
      else{
# if (defined(VT_MT) || defined(VT_HYB))
        /* only called per process */
        group = vt_get_curid();
        thread_group = group;
# else
        /* not multithreaded -> keep information on local process */
#endif
      }
    }

    if (info.run_per == VT_PLUGIN_CNTR_PER_HOST) {
      if (!vt_my_trace_is_master)
        continue;
      else if (host_group == INVALID_GROUP_NUMBER){
        host_group = vt_node_pgid;
        vt_def_procgrp_attributes(VT_MY_THREAD ,vt_node_pgid,
            VT_PROCGRP_HASCOUNTERS);
      }
      group = host_group;
    }

    if (info.run_per == VT_PLUGIN_CNTR_ONCE) {
      if (vt_my_trace != 0)
        continue;
      else if (all_group == INVALID_GROUP_NUMBER){
        all_group = vt_all_pgid;
        vt_def_procgrp_attributes(VT_MY_THREAD ,vt_all_pgid,
            VT_PROCGRP_HASCOUNTERS);
      }
      group = all_group;
    }

    if (info.init == NULL) {
      vt_error_msg(
          "Init not implemented in plugin %s\n",
          current_plugin);
      /* try loading next */
      continue;
    }

    if (info.add_counter == NULL) {
      vt_error_msg(
          "Add counter not implemented in plugin %s\n",
          current_plugin);
      /* try loading next */
      continue;
    }

    if (info.get_event_info == NULL) {
      vt_error_msg("Get event info not implemented in plugin %s\n",
          current_plugin);
      /* try loading next */
      continue;
    }

    /* check the type of plugin */
    switch (info.synch) {
    case VT_PLUGIN_CNTR_SYNCH:
      nr_plugins[VT_PLUGIN_CNTR_SYNCH]++;
      vt_plugin_handles[VT_PLUGIN_CNTR_SYNCH] = realloc(
          vt_plugin_handles[VT_PLUGIN_CNTR_SYNCH],
          nr_plugins[VT_PLUGIN_CNTR_SYNCH] * sizeof(struct vt_plugin));
      current
          = &vt_plugin_handles[VT_PLUGIN_CNTR_SYNCH]
                              [nr_plugins[VT_PLUGIN_CNTR_SYNCH] - 1];
      if (info.get_current_value == NULL) {
        nr_plugins[VT_PLUGIN_CNTR_SYNCH]--;
        vt_error_msg("Get current results not implemented in plugin %s\n",
            current_plugin);
        /* try loading next */
        continue;
      }
      break;
    case VT_PLUGIN_CNTR_ASYNCH_CALLBACK:
      nr_plugins[VT_PLUGIN_CNTR_ASYNCH_CALLBACK]++;
      vt_plugin_handles[VT_PLUGIN_CNTR_ASYNCH_CALLBACK]
          = realloc(
              vt_plugin_handles[VT_PLUGIN_CNTR_ASYNCH_CALLBACK],
              nr_plugins[VT_PLUGIN_CNTR_ASYNCH_CALLBACK]
                  * sizeof(struct vt_plugin));
      current
          = &vt_plugin_handles[VT_PLUGIN_CNTR_ASYNCH_CALLBACK]
                              [nr_plugins[VT_PLUGIN_CNTR_ASYNCH_CALLBACK] - 1];
      if (info.set_callback_function == NULL) {
        nr_plugins[VT_PLUGIN_CNTR_ASYNCH_CALLBACK]--;
        vt_error_msg("set callback not implemented in plugin %s\n",
            current_plugin);
        /* try loading next */
        continue;
      }
      if (info.set_pform_wtime_function == NULL) {
        nr_plugins[VT_PLUGIN_CNTR_ASYNCH_CALLBACK]--;
        vt_error_msg(
            "set wtime not implemented in plugin %s\n",
            current_plugin);
        /* try loading next */
        continue;
      }
      break;
    case VT_PLUGIN_CNTR_ASYNCH_EVENT:
      nr_plugins[VT_PLUGIN_CNTR_ASYNCH_EVENT]++;
      vt_plugin_handles[VT_PLUGIN_CNTR_ASYNCH_EVENT] = realloc(
          vt_plugin_handles[VT_PLUGIN_CNTR_ASYNCH_EVENT],
          nr_plugins[VT_PLUGIN_CNTR_ASYNCH_EVENT] * sizeof(struct vt_plugin));
      current
          = &vt_plugin_handles[VT_PLUGIN_CNTR_ASYNCH_EVENT]
                               [nr_plugins[VT_PLUGIN_CNTR_ASYNCH_EVENT] - 1];
      if (info.get_all_values == NULL) {
        nr_plugins[VT_PLUGIN_CNTR_ASYNCH_EVENT]--;
        vt_error_msg("get all values not implemented in plugin %s\n",
            current_plugin);
        /* try loading next */
        continue;
      }
      if (info.set_pform_wtime_function == NULL) {
        nr_plugins[VT_PLUGIN_CNTR_ASYNCH_EVENT]--;
        vt_error_msg(
            "set wtime not implemented in plugin %s\n",
            current_plugin);
        /* try loading next */
        continue;
      }
      break;
    case VT_PLUGIN_CNTR_ASYNCH_POST_MORTEM:
      nr_plugins[VT_PLUGIN_CNTR_ASYNCH_POST_MORTEM]++;
      vt_plugin_handles[VT_PLUGIN_CNTR_ASYNCH_POST_MORTEM] = realloc(
          vt_plugin_handles[VT_PLUGIN_CNTR_ASYNCH_POST_MORTEM],
          nr_plugins[VT_PLUGIN_CNTR_ASYNCH_POST_MORTEM]
              * sizeof(struct vt_plugin));
      current
          = &vt_plugin_handles[VT_PLUGIN_CNTR_ASYNCH_POST_MORTEM]
                           [nr_plugins[VT_PLUGIN_CNTR_ASYNCH_POST_MORTEM] - 1];
      if (info.get_all_values == NULL) {
        vt_error_msg("get all values not implemented in plugin %s\n",
            current_plugin);
        nr_plugins[VT_PLUGIN_CNTR_ASYNCH_POST_MORTEM]--;
        /* try loading next */
        continue;
      }
      if (info.set_pform_wtime_function == NULL) {
        vt_error_msg(
            "set wtime not implemented in plugin %s\n",
            current_plugin);
        nr_plugins[VT_PLUGIN_CNTR_ASYNCH_POST_MORTEM]--;
        /* try loading next */
        continue;
      }
      break;
    default:
      vt_error_msg(
          "Error getting synch type from plugin (invalid synch type)\n");
      continue;
    }

    /* clear out current plugin */
    memset(current, 0, sizeof(struct vt_plugin));

    /* add handle (should be closed in the end) */
    current->dlfcn_handle = handle;

    /* store the info object of the plugin */
    current->info = info;

    /* store the name of the plugin */
    current->name = current_plugin;

    /* give plugin the wtime function to make it possible to convert times */
    if (current->info.set_pform_wtime_function != NULL) {
      current->info.set_pform_wtime_function(vt_pform_wtime);
    }
    vt_cntl_msg(3, "Initializing plugin counter library: lib%s.so",
        current_plugin);
    /* initialize plugin */
    if (current->info.init()) {
      vt_error_msg("Error initializing plugin %s, init returned != 0\n",
          current_plugin);
      continue;
    }
    /* define a counter group for every plugin*/
    current->counter_group = vt_def_counter_group(VT_MY_THREAD, current_plugin);

    /* now search for all available events on that plugin */
    next_plugin_metric = env_vt_plugin_metrics;
    while (next_plugin_metric[0] != 0) {
      /* shall contain current index in environment VT_PLUGIN_METRICS */
      index = 0;

      /* copy metric to current_plugin_metric char by char */
      while ((next_plugin_metric[index] != ':') && (next_plugin_metric[index]
          != '\0')) {
        current_plugin_metric[index] = next_plugin_metric[index];
        index++;
      }
      current_plugin_metric[index] = 0;
      if (next_plugin_metric[index] == ':')
        next_plugin_metric = &next_plugin_metric[index + 1];
      else
        next_plugin_metric = &next_plugin_metric[index];
      /* If the plugin metric belongs to the current plugin */
      if (strstr(current_plugin_metric, current_plugin)
          == current_plugin_metric) {
        /* some meta data*/
        char * unit = NULL;
        uint32_t otf_prop = 0;

        /* This will be needed to iterate over the infos */
        vt_plugin_cntr_metric_info * current_event_info;

        /* check the event name from plugin */
        /* it could contain wildcards and other stuff */
        vt_plugin_cntr_metric_info * event_infos = info.get_event_info(
            &current_plugin_metric[strlen(current_plugin) + 1]);

        vt_cntl_msg(3, "Adding metric %s for plugin counter library: lib%s.so",
            current_plugin_metric, current_plugin);

        /* check the event name from plugin */
        /* it could contain wildcards and other stuff */
        if (event_infos == NULL) {
          vt_error_msg(
              "Error initializing plugin metric %s, no info returned\n",
              current_plugin_metric);
          continue;
        }
        /* now for all events which are present in the struct */
        current_event_info = event_infos;
        for (current_event_info = event_infos;
            current_event_info->name != NULL;
            current_event_info++) {

          vt_cntl_msg(3,
              "Retrieved metric %s for plugin counter library: lib%s.so."
                " Initializing data structures", current_event_info->name,
              current_plugin);

          /* event is part of this plugin */
          current->num_selected_events++;

          /* allocate space for events */
          current->selected_events = realloc(current->selected_events,
              current->num_selected_events * sizeof(char*));

          /*the metric is everything after "plugin_"*/
          current->selected_events[current->num_selected_events - 1]
              = current_event_info->name;

          current->vt_counter_ids = realloc(current->vt_counter_ids,
              current->num_selected_events * sizeof(uint32_t));

          current->vt_asynch_keys = realloc(current->vt_asynch_keys,
              current->num_selected_events * sizeof(uint32_t));

          /* if a unit is provided, use it */
          unit = current_event_info->unit == NULL ? "#"
              : current_event_info->unit;

          /* if otf properties are provided, use them */
          otf_prop = current_event_info->cntr_property;
          /* define new counter */
          current->vt_counter_ids[current->num_selected_events - 1]
              = vt_def_counter(VT_MY_THREAD,
                  current->selected_events[current->num_selected_events - 1],
                  unit, otf_prop, current->counter_group, group);

          switch (current->info.synch) {
          case VT_PLUGIN_CNTR_SYNCH:
          	/* no asynch_keys at all */
        	  break;
          case VT_PLUGIN_CNTR_ASYNCH_POST_MORTEM:
        	  /* One asynch_key for all */
              current->vt_asynch_keys[current->num_selected_events - 1] = post_mortem_asynch_key();
        	  break;
          default:
            {
              char buffer[512];
              sprintf(buffer, "%s_%s", current_plugin, current_event_info->name);
              current->vt_asynch_keys[current->num_selected_events - 1]
                 = vt_def_async_source(VT_MY_THREAD, buffer);
            }
            break;
          }
          /* enable plugin counters */
          vt_plugin_cntr_used = 1;
        } /* end of: for all metrics related to the metric string */
        if (event_infos != NULL)
          free(event_infos);
      } /* end of if metric belongs to this plugin */
    } /* end of: for all plugin metrics */
  } /* end of: for all plugins */

  /* free temporary variables */
  if (plugins != NULL)
    free(plugins);

}