LCOV - code coverage report
Current view: top level - home/fuchsto/workspaces/dash-development/dart-impl/base/src - hwinfo.c (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 60 66 90.9 %
Date: 2016-06-29 12:30:40 Functions: 1 1 100.0 %

          Line data    Source code
       1             : 
       2             : /*
       3             :  * Include config and utmpx.h first to prevent previous include of utmpx.h
       4             :  * without _GNU_SOURCE in included headers:
       5             :  */
       6             : #include <dash/dart/base/config.h>
       7             : #ifdef DART__PLATFORM__LINUX
       8             : #  define _GNU_SOURCE
       9             : #  include <utmpx.h>
      10             : #  include <sched.h>
      11             : #endif
      12             : #include <dash/dart/base/macro.h>
      13             : #include <dash/dart/base/logging.h>
      14             : #include <dash/dart/base/locality.h>
      15             : #include <dash/dart/base/logging.h>
      16             : #include <dash/dart/base/assert.h>
      17             : 
      18             : #include <dash/dart/base/internal/papi.h>
      19             : #include <dash/dart/base/internal/unit_locality.h>
      20             : 
      21             : #include <dash/dart/base/hwinfo.h>
      22             : 
      23             : #include <dash/dart/if/dart_types.h>
      24             : #include <dash/dart/if/dart_locality.h>
      25             : 
      26             : #include <inttypes.h>
      27             : #include <string.h>
      28             : #include <unistd.h>
      29             : #include <stdio.h>
      30             : #include <limits.h>
      31             : 
      32             : #ifdef DART_ENABLE_LIKWID
      33             : #  include <likwid.h>
      34             : #endif
      35             : 
      36             : #ifdef DART_ENABLE_HWLOC
      37             : #  include <hwloc.h>
      38             : #  include <hwloc/helper.h>
      39             : #endif
      40             : 
      41             : #ifdef DART_ENABLE_PAPI
      42             : #  include <papi.h>
      43             : #endif
      44             : 
      45             : #ifdef DART_ENABLE_NUMA
      46             : #  include <utmpx.h>
      47             : #  include <numa.h>
      48             : #endif
      49             : 
      50             : 
      51           8 : dart_ret_t dart_hwinfo(
      52             :   dart_hwinfo_t * hwinfo)
      53             : {
      54             :   DART_LOG_DEBUG("dart_hwinfo()");
      55             : 
      56             :   dart_hwinfo_t hw;
      57             : 
      58           8 :   hw.num_sockets         = -1;
      59           8 :   hw.num_numa            = -1;
      60           8 :   hw.numa_id             = -1;
      61           8 :   hw.num_cores           = -1;
      62           8 :   hw.cpu_id              = -1;
      63           8 :   hw.min_cpu_mhz         = -1;
      64           8 :   hw.max_cpu_mhz         = -1;
      65           8 :   hw.min_threads         = -1;
      66           8 :   hw.max_threads         = -1;
      67           8 :   hw.cache_sizes[0]      = -1;
      68           8 :   hw.cache_sizes[1]      = -1;
      69           8 :   hw.cache_sizes[2]      = -1;
      70           8 :   hw.cache_line_sizes[0] = -1;
      71           8 :   hw.cache_line_sizes[1] = -1;
      72           8 :   hw.cache_line_sizes[2] = -1;
      73           8 :   hw.cache_shared[0]     = -1;
      74           8 :   hw.cache_shared[1]     = -1;
      75           8 :   hw.cache_shared[2]     = -1;
      76             : 
      77             : #ifdef DART_ENABLE_LIKWID
      78             :   DART_LOG_TRACE("dart_hwinfo: using likwid");
      79             :   /*
      80             :    * see likwid API documentation:
      81             :    * https://rrze-hpc.github.io/likwid/Doxygen/C-likwidAPI-code.html
      82             :    */
      83             :   int likwid_ret = topology_init();
      84             :   if (likwid_ret < 0) {
      85             :     DART_LOG_ERROR("dart_hwinfo: "
      86             :                    "likwid: topology_init failed, returned %d", likwid_ret);
      87             :   } else {
      88             :     CpuInfo_t     info = get_cpuInfo();
      89             :     CpuTopology_t topo = get_cpuTopology();
      90             :     if (hw.min_cpu_mhz < 0 || hw.max_cpu_mhz < 0) {
      91             :       hw.min_cpu_mhz = info->clock;
      92             :       hw.max_cpu_mhz = info->clock;
      93             :     }
      94             :     if (hw.num_sockets < 0) {
      95             :       hw.num_sockets = topo->numSockets;
      96             :     }
      97             :     if (hw.num_numa < 0) {
      98             :       hw.num_numa    = hw.num_sockets;
      99             :     }
     100             :     if (hw.num_cores < 0) {
     101             :       hw.num_cores    = topo->numCoresPerSocket * hw.num_sockets;
     102             :     }
     103             :     topology_finalize();
     104             :     DART_LOG_TRACE("dart_hwinfo: likwid: "
     105             :                    "num_sockets: %d num_numa: %d num_cores: %d",
     106             :                    hw.num_sockets, hw.num_numa, hw.num_cores);
     107             :   }
     108             : #endif /* DART_ENABLE_LIKWID */
     109             : 
     110             : #ifdef DART_ENABLE_HWLOC
     111             :   DART_LOG_TRACE("dart_hwinfo: using hwloc");
     112             : 
     113             :   hwloc_topology_t topology;
     114           8 :   hwloc_topology_init(&topology);
     115           8 :   hwloc_topology_load(topology);
     116             :   // Resolve cache sizes, ordered by locality (i.e. smallest first):
     117           8 :   int level = 0;
     118             :   hwloc_obj_t obj;
     119          72 :   for (obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_PU, 0);
     120             :        obj;
     121          56 :        obj = obj->parent) {
     122          56 :     if (obj->type == HWLOC_OBJ_CACHE) {
     123          24 :       hw.cache_sizes[level]      = obj->attr->cache.size;
     124          24 :       hw.cache_line_sizes[level] = obj->attr->cache.linesize;
     125          24 :       ++level;
     126             :     }
     127             :   }
     128           8 :   if (hw.num_sockets < 0) {
     129             :     // Resolve number of sockets:
     130           8 :     int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_SOCKET);
     131           8 :     if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
     132           8 :       hw.num_sockets = hwloc_get_nbobjs_by_depth(topology, depth);
     133             :     }
     134             :   }
     135           8 :   if (hw.num_numa < 0) {
     136             :     // Resolve number of NUMA nodes:
     137           8 :     int n_numa_nodes = hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_NODE);
     138           8 :     if (n_numa_nodes > 0) {
     139           0 :       hw.num_numa = n_numa_nodes;
     140             :     }
     141             :   }
     142           8 :   if (hw.num_cores < 0) {
     143             :     // Resolve number of cores:
     144           8 :     int n_cores = hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_CORE);
     145           8 :     if (n_cores > 0) {
     146           8 :       hw.num_cores = n_cores;
     147             :     }
     148             :         }
     149           8 :   if (hw.num_cores > 0 && hw.max_threads < 0) {
     150             :     // Resolve number of threads per core:
     151           8 :     int n_cpus     = hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_PU);
     152           8 :     hw.min_threads = 1;
     153           8 :     hw.max_threads = n_cpus / hw.num_cores;
     154             :   }
     155           8 :   hwloc_topology_destroy(topology);
     156             :   DART_LOG_TRACE("dart_hwinfo: hwloc: "
     157             :                  "num_sockets:%d num_numa:%d num_cores:%d",
     158             :                  hw.num_sockets, hw.num_numa, hw.num_cores);
     159             : #endif /* DART_ENABLE_HWLOC */
     160             : 
     161             : #ifdef DART_ENABLE_PAPI
     162             :   DART_LOG_TRACE("dart_hwinfo: using PAPI");
     163             : 
     164           8 :   const PAPI_hw_info_t * papi_hwinfo = NULL;
     165           8 :   if (dart__base__locality__papi_init(&papi_hwinfo) == DART_OK) {
     166           8 :     if (hw.num_sockets < 0) { hw.num_sockets = papi_hwinfo->sockets; }
     167           8 :     if (hw.num_numa    < 0) { hw.num_numa    = papi_hwinfo->nnodes;  }
     168           8 :     if (hw.num_cores   < 0) {
     169           0 :       int cores_per_socket = papi_hwinfo->cores;
     170           0 :       hw.num_cores   = hw.num_sockets * cores_per_socket;
     171             :     }
     172           8 :     if (hw.min_cpu_mhz < 0 || hw.max_cpu_mhz < 0) {
     173           8 :       hw.min_cpu_mhz = papi_hwinfo->cpu_min_mhz;
     174           8 :       hw.max_cpu_mhz = papi_hwinfo->cpu_max_mhz;
     175             :     }
     176             :     DART_LOG_TRACE("dart_hwinfo: PAPI: "
     177             :                    "num_sockets:%d num_numa:%d num_cores:%d",
     178             :                    hw.num_sockets, hw.num_numa, hw.num_cores);
     179             :   }
     180             : #endif /* DART_ENABLE_PAPI */
     181             : 
     182             : #ifdef DART__ARCH__IS_MIC
     183             :   DART_LOG_TRACE("dart_hwinfo: MIC architecture");
     184             : 
     185             :   if (hw.num_sockets < 0) { hw.num_sockets =  1; }
     186             :   if (hw.num_numa    < 0) { hw.num_numa    =  1; }
     187             :   if (hw.num_cores   < 0) { hw.num_cores   = 60; }
     188             :   if (hw.min_cpu_mhz < 0 || hw.max_cpu_mhz < 0) {
     189             :     hw.min_cpu_mhz = 1100;
     190             :     hw.max_cpu_mhz = 1100;
     191             :   }
     192             :   if (hw.min_threads < 0 || hw.max_threads < 0) {
     193             :     hw.min_threads = 4;
     194             :     hw.max_threads = 4;
     195             :   }
     196             : #endif
     197             : 
     198             : #ifdef DART__PLATFORM__POSIX
     199           8 :   if (hw.num_cores < 0) {
     200             :                 /*
     201             :      * NOTE: includes hyperthreading
     202             :      */
     203           0 :     int posix_ret = sysconf(_SC_NPROCESSORS_ONLN);
     204           0 :     hw.num_cores = (posix_ret > 0) ? posix_ret : hw.num_cores;
     205             :                 DART_LOG_TRACE(
     206             :       "dart_hwinfo: POSIX: hw.num_cores = %d",
     207             :       hw.num_cores);
     208             :   }
     209             : #endif
     210             : 
     211             : #ifdef DART__PLATFORM__LINUX
     212           8 :   if (hw.cpu_id < 0) {
     213           8 :     hw.cpu_id = sched_getcpu();
     214             :   }
     215             : #else
     216             :   DART_LOG_ERROR("dart_hwinfo: "
     217             :                  "Linux platform required");
     218             :   return DART_ERR_OTHER;
     219             : #endif
     220             : 
     221             : #ifdef DART_ENABLE_NUMA
     222             :   DART_LOG_TRACE("dart_hwinfo: using numalib");
     223           8 :   if (hw.num_numa < 0) {
     224           0 :     hw.num_numa = numa_max_node() + 1;
     225             :   }
     226           8 :   if (hw.numa_id < 0 && hw.cpu_id >= 0) {
     227           8 :     hw.numa_id  = numa_node_of_cpu(hw.cpu_id);
     228             :   }
     229             :   DART_LOG_TRACE("dart_hwinfo: numalib: "
     230             :                  "num_sockets:%d num_numa:%d numa_id:%d num_cores:%d",
     231             :                  hw.num_sockets, hw.num_numa, hw.numa_id, hw.num_cores);
     232             : #endif
     233             : 
     234             : #if 0
     235             :   if (hw.num_numa < 0) {
     236             :     hw.num_numa = 1;
     237             :   }
     238             :   if (hw.num_cores   < 0) {
     239             :     hw.num_cores     = 1;
     240             :   }
     241             :   if (hw.min_threads < 0) {
     242             :     hw.min_threads   = 1;
     243             :   }
     244             :   if (hw.max_threads < 0) {
     245             :     hw.max_threads   = 1;
     246             :   }
     247             : #endif
     248             : 
     249             :   DART_LOG_TRACE("dart_hwinfo: finished: "
     250             :                  "num_sockets:%d num_numa:%d "
     251             :                  "numa_id:%d cpu_id:%d, num_cores:%d "
     252             :                  "min_threads:%d max_threads:%d",
     253             :                  hw.num_sockets, hw.num_numa,
     254             :                  hw.numa_id, hw.cpu_id, hw.num_cores,
     255             :                  hw.min_threads, hw.max_threads);
     256             : 
     257           8 :   *hwinfo = hw;
     258             : 
     259             :   DART_LOG_DEBUG("dart_hwinfo >");
     260           8 :   return DART_OK;
     261             : }

Generated by: LCOV version 1.12