Use more const in hardwaretopology
authorRoland Schulz <roland.schulz@intel.com>
Tue, 28 Aug 2018 21:04:24 +0000 (14:04 -0700)
committerMark Abraham <mark.j.abraham@gmail.com>
Wed, 29 Aug 2018 07:24:48 +0000 (09:24 +0200)
Change-Id: I5b4240c246e3a87f3c85e506645d720960e09933

src/gromacs/hardware/hardwaretopology.cpp

index 1d8e6d48a24b8bcfedc7fe8f9f5023e7328e4b20..ae2ce7670640fd04810bf1d7d64f8975b94e1205 100644 (file)
@@ -175,7 +175,7 @@ parseCpuInfo(HardwareTopology::Machine *        machine,
 
 // Compatibility function for accessing hwloc_obj_t object memory with different API versions of hwloc
 std::size_t
-getHwLocObjectMemory(hwloc_obj_t obj)
+getHwLocObjectMemory(const hwloc_obj* obj)
 {
 #if GMX_HWLOC_API_VERSION_IS_2XX
     return obj->total_memory;
@@ -195,12 +195,12 @@ getHwLocObjectMemory(hwloc_obj_t obj)
  *          descendants of the provided object. If no objects of this type
  *          were found, the vector will be empty.
  */
-const std::vector<hwloc_obj_t>
-getHwLocDescendantsByType(hwloc_topology_t topo, hwloc_obj_t obj, const hwloc_obj_type_t type)
+const std::vector<const hwloc_obj*>
+getHwLocDescendantsByType(const hwloc_topology* topo, const hwloc_obj* obj, const hwloc_obj_type_t type)
 {
     GMX_RELEASE_ASSERT(obj, "NULL hwloc object provided to getHwLocDescendantsByType()");
 
-    std::vector<hwloc_obj_t> v;
+    std::vector<const hwloc_obj*> v;
 
     if (obj->type == type)
     {
@@ -209,9 +209,11 @@ getHwLocDescendantsByType(hwloc_topology_t topo, hwloc_obj_t obj, const hwloc_ob
     // Go through children; if this object has no children obj->arity is 0,
     // and we'll return an empty vector.
     hwloc_obj_t tempNode = nullptr;
-    while ((tempNode = hwloc_get_next_child(topo, obj, tempNode)) != nullptr)
+    while ((tempNode = hwloc_get_next_child(const_cast<hwloc_topology_t>(topo),
+                                            const_cast<hwloc_obj_t>(obj),
+                                            tempNode)) != nullptr)
     {
-        std::vector<hwloc_obj_t> v2 = getHwLocDescendantsByType(topo, tempNode, type);
+        std::vector<const hwloc_obj*> v2 = getHwLocDescendantsByType(topo, tempNode, type);
         v.insert(v.end(), v2.begin(), v2.end());
     }
     return v;
@@ -223,14 +225,14 @@ getHwLocDescendantsByType(hwloc_topology_t topo, hwloc_obj_t obj, const hwloc_ob
  *  \param machine Pointer to the machine structure in the HardwareTopology
  *                 class, where the tree of sockets/cores/threads will be written.
  *
- *  \return If all the data is found the return value is 0, otherwise non-zero.
+ *  \return If all the data is found
  */
-int
+bool
 parseHwLocSocketsCoresThreads(hwloc_topology_t                   topo,
                               HardwareTopology::Machine *        machine)
 {
-    hwloc_obj_t                            root         = hwloc_get_root_obj(topo);
-    std::vector<hwloc_obj_t>               hwlocSockets = getHwLocDescendantsByType(topo, root, HWLOC_OBJ_PACKAGE);
+    const hwloc_obj*                      root         = hwloc_get_root_obj(topo);
+    std::vector<const hwloc_obj*>         hwlocSockets = getHwLocDescendantsByType(topo, root, HWLOC_OBJ_PACKAGE);
 
     machine->logicalProcessorCount = hwloc_get_nbobjs_by_type(topo, HWLOC_OBJ_PU);
     machine->logicalProcessors.resize(machine->logicalProcessorCount);
@@ -244,7 +246,7 @@ parseHwLocSocketsCoresThreads(hwloc_topology_t                   topo,
         machine->sockets[i].id = hwlocSockets[i]->logical_index;
 
         // Get children (cores)
-        std::vector<hwloc_obj_t> hwlocCores = getHwLocDescendantsByType(topo, hwlocSockets[i], HWLOC_OBJ_CORE);
+        std::vector<const hwloc_obj*> hwlocCores = getHwLocDescendantsByType(topo, hwlocSockets[i], HWLOC_OBJ_CORE);
         machine->sockets[i].cores.resize(hwlocCores.size());
 
         topologyOk = topologyOk && !hwlocCores.empty(); // Fail if we have no cores in socket
@@ -257,7 +259,7 @@ parseHwLocSocketsCoresThreads(hwloc_topology_t                   topo,
             machine->sockets[i].cores[j].numaNodeId = -1;
 
             // Get children (hwthreads)
-            std::vector<hwloc_obj_t> hwlocPUs = getHwLocDescendantsByType(topo, hwlocCores[j], HWLOC_OBJ_PU);
+            std::vector<const hwloc_obj*> hwlocPUs = getHwLocDescendantsByType(topo, hwlocCores[j], HWLOC_OBJ_PU);
             machine->sockets[i].cores[j].hwThreads.resize(hwlocPUs.size());
 
             topologyOk = topologyOk && !hwlocPUs.empty(); // Fail if we have no hwthreads in core
@@ -286,25 +288,23 @@ parseHwLocSocketsCoresThreads(hwloc_topology_t                   topo,
         }
     }
 
-    if (topologyOk)
-    {
-        return 0;
-    }
-    else
+    if (!topologyOk)
     {
         machine->logicalProcessors.clear();
         machine->sockets.clear();
-        return -1;
     }
+    return topologyOk;
 }
 
-/*! \brief Fill \c machine with cache information from hwloc topology
+/*! \brief Read cache information from hwloc topology
  *
  *  \param topo    hwloc topology handle that has been initialized and loaded
  *  \param machine Pointer to the machine structure in the HardwareTopology
- *                 class, where cache data will be filled if found and valid.
+ *                 class, where cache data will be filled.
+ *
+ *  \return If any cache data is found
  */
-void
+bool
 parseHwLocCache(hwloc_topology_t                   topo,
                 HardwareTopology::Machine *        machine)
 {
@@ -318,7 +318,7 @@ parseHwLocCache(hwloc_topology_t                   topo,
             hwloc_obj_t cache = hwloc_get_next_obj_by_depth(topo, depth, nullptr);
             if (cache != nullptr)
             {
-                std::vector<hwloc_obj_t> hwThreads = getHwLocDescendantsByType(topo, cache, HWLOC_OBJ_PU);
+                std::vector<const hwloc_obj*> hwThreads = getHwLocDescendantsByType(topo, cache, HWLOC_OBJ_PU);
 
                 machine->caches.push_back( {
                                                static_cast<int>(cache->attr->cache.depth),
@@ -330,10 +330,11 @@ parseHwLocCache(hwloc_topology_t                   topo,
             }
         }
     }
+    return !machine->caches.empty();
 }
 
 
-/*! \brief Fill \c machine with numa information from hwloc topology
+/*! \brief Read numa information from hwloc topology
  *
  *  \param topo    hwloc topology handle that has been initialized and loaded
  *  \param machine Pointer to the machine structure in the HardwareTopology
@@ -348,17 +349,16 @@ parseHwLocCache(hwloc_topology_t                   topo,
  *  completed successfully before calling this one. If this is not the case,
  *  you will get an error return code.
  *
- *  If the data found makes sense (either in the numa node or the
- *  entire machine) the numa.nodes data structure in
- *  HardwareTopology::Machine will be filled upon exit.
+ *  \return If the data found makes sense (either in the numa node or the
+ *          entire machine)
  */
-void
+bool
 parseHwLocNuma(hwloc_topology_t                   topo,
                HardwareTopology::Machine *        machine)
 {
-    hwloc_obj_t                        root           = hwloc_get_root_obj(topo);
-    std::vector<hwloc_obj_t>           hwlocNumaNodes = getHwLocDescendantsByType(topo, root, HWLOC_OBJ_NUMANODE);
-    bool                               topologyOk     = true;
+    const hwloc_obj*                  root           = hwloc_get_root_obj(topo);
+    std::vector<const hwloc_obj*>     hwlocNumaNodes = getHwLocDescendantsByType(topo, root, HWLOC_OBJ_NUMANODE);
+    bool                              topologyOk     = true;
 
     if (!hwlocNumaNodes.empty())
     {
@@ -372,9 +372,9 @@ parseHwLocNuma(hwloc_topology_t                   topo,
 
             // Get list of PUs in this numa node. Get from numa node if v1.x.x, get from numa node's parent if 2.x.x
 #if GMX_HWLOC_API_VERSION_IS_2XX
-            std::vector<hwloc_obj_t> hwlocPUs = getHwLocDescendantsByType(topo, hwlocNumaNodes[i]->parent, HWLOC_OBJ_PU);
+            std::vector<const hwloc_obj*> hwlocPUs = getHwLocDescendantsByType(topo, hwlocNumaNodes[i]->parent, HWLOC_OBJ_PU);
 #else
-            std::vector<hwloc_obj_t> hwlocPUs = getHwLocDescendantsByType(topo, hwlocNumaNodes[i], HWLOC_OBJ_PU);
+            std::vector<const hwloc_obj*> hwlocPUs = getHwLocDescendantsByType(topo, hwlocNumaNodes[i], HWLOC_OBJ_PU);
 #endif
             for (auto &p : hwlocPUs)
             {
@@ -405,23 +405,23 @@ parseHwLocNuma(hwloc_topology_t                   topo,
         }
         else
         {
-            hwloc_distances_s** dist = new hwloc_distances_s*;
+            hwloc_distances_s* dist;
             // Set the number of distance matrices to return (1 in our case, but hwloc 2.x.x allows
             // for multiple distances types and therefore multiple distance matrices)
             unsigned nr = 1;
-            hwloc_distances_get(topo, &nr, dist, HWLOC_DISTANCES_KIND_MEANS_LATENCY, 0);
+            hwloc_distances_get(topo, &nr, &dist, HWLOC_DISTANCES_KIND_MEANS_LATENCY, 0);
             // If no distances were found, nr will be 0, otherwise distances will be populated with 1
             // hwloc_distances_s object
-            if (nr > 0 && dist[0]->nbobjs == hwlocNumaNodes.size())
+            if (nr > 0 && dist->nbobjs == hwlocNumaNodes.size())
             {
 
-                machine->numa.relativeLatency.resize(dist[0]->nbobjs);
-                for (std::size_t i = 0; i < dist[0]->nbobjs; i++)
+                machine->numa.relativeLatency.resize(dist->nbobjs);
+                for (std::size_t i = 0; i < dist->nbobjs; i++)
                 {
-                    machine->numa.relativeLatency[i].resize(dist[0]->nbobjs);
-                    for (std::size_t j = 0; j < dist[0]->nbobjs; j++)
+                    machine->numa.relativeLatency[i].resize(dist->nbobjs);
+                    for (std::size_t j = 0; j < dist->nbobjs; j++)
                     {
-                        machine->numa.relativeLatency[i][j] = dist[0]->values[i*dist[0]->nbobjs+j];
+                        machine->numa.relativeLatency[i][j] = dist->values[i*dist->nbobjs+j];
                     }
                 }
             }
@@ -429,7 +429,7 @@ parseHwLocNuma(hwloc_topology_t                   topo,
             {
                 topologyOk = false;
             }
-            hwloc_distances_release(topo, dist[0]);
+            hwloc_distances_release(topo, dist);
         }
 
         // hwloc-2.x provides latencies as integers, but to make things more similar to the case of a single
@@ -526,21 +526,23 @@ parseHwLocNuma(hwloc_topology_t                   topo,
     {
         machine->numa.nodes.clear();
     }
+    return topologyOk;
 }
 
-/*! \brief Fill \c machine with PCI device information from hwloc topology
+/*! \brief Read PCI device information from hwloc topology
  *
  *  \param topo    hwloc topology handle that has been initialized and loaded
  *  \param machine Pointer to the machine structure in the HardwareTopology
- *                 class, where PCI device information will be filled if found
- *                 and valid.
+ *                 class, where PCI device information will be filled.
+ * *
+ *  \return If any devices were found
  */
-void
+bool
 parseHwLocDevices(hwloc_topology_t                   topo,
                   HardwareTopology::Machine *        machine)
 {
-    hwloc_obj_t              root    = hwloc_get_root_obj(topo);
-    std::vector<hwloc_obj_t> pcidevs = getHwLocDescendantsByType(topo, root, HWLOC_OBJ_PCI_DEVICE);
+    const hwloc_obj *             root    = hwloc_get_root_obj(topo);
+    std::vector<const hwloc_obj*> pcidevs = getHwLocDescendantsByType(topo, root, HWLOC_OBJ_PCI_DEVICE);
 
     for (auto &p : pcidevs)
     {
@@ -558,7 +560,8 @@ parseHwLocDevices(hwloc_topology_t                   topo,
         }
 #else           // GMX_HWLOC_API_VERSION_IS_2XX = false, api v 1.x.x
         // numa nodes are normal part of tree, can use hwloc ancestor function
-        const hwloc_obj * const ancestor = hwloc_get_ancestor_obj_by_type(topo, HWLOC_OBJ_NUMANODE, p);
+        const hwloc_obj * const ancestor = hwloc_get_ancestor_obj_by_type(topo, HWLOC_OBJ_NUMANODE,
+                                                                          const_cast<hwloc_obj_t>(p));
 #endif          // end if GMX_HWLOC_API_VERSION_IS_2XX
         int                     numaId;
         if (ancestor != nullptr)
@@ -584,6 +587,7 @@ parseHwLocDevices(hwloc_topology_t                   topo,
                                         numaId
                                     } );
     }
+    return !pcidevs.empty();
 }
 
 void
@@ -616,10 +620,10 @@ parseHwLoc(HardwareTopology::Machine *        machine,
     }
 
     // If we get here, we can get a valid root object for the topology
-    *isThisSystem = bool(hwloc_topology_is_thissystem(topo));
+    *isThisSystem = hwloc_topology_is_thissystem(topo) != 0;
 
     // Parse basic information about sockets, cores, and hardware threads
-    if (parseHwLocSocketsCoresThreads(topo, machine) == 0)
+    if (parseHwLocSocketsCoresThreads(topo, machine))
     {
         *supportLevel = HardwareTopology::SupportLevel::Basic;
     }
@@ -630,9 +634,7 @@ parseHwLoc(HardwareTopology::Machine *        machine,
     }
 
     // Get information about cache and numa nodes
-    parseHwLocCache(topo, machine);
-    parseHwLocNuma(topo, machine);
-    if (!machine->caches.empty() && !machine->numa.nodes.empty())
+    if (parseHwLocCache(topo, machine) && parseHwLocNuma(topo, machine))
     {
         *supportLevel = HardwareTopology::SupportLevel::Full;
     }
@@ -643,8 +645,7 @@ parseHwLoc(HardwareTopology::Machine *        machine,
     }
 
     // PCI devices
-    parseHwLocDevices(topo, machine);
-    if (!machine->devices.empty())
+    if (parseHwLocDevices(topo, machine))
     {
         *supportLevel = HardwareTopology::SupportLevel::FullWithDevices;
     }