Apply clang-format to source tree
[alexxy/gromacs.git] / src / gromacs / hardware / hardwaretopology.h
index 66abb682def3b2bd38ddf98e9186fda758b40ed9..b52ad0a3b06887fcb4ab2ab3ce2947536c5482f4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -64,206 +64,200 @@ namespace gmx
  */
 class HardwareTopology
 {
-    public:
+public:
+    /*! \brief Amount of topology information present (incremental) */
+    enum class SupportLevel
+    {
+        None,                  //!< No hardware information whatsoever. Sorry.
+        LogicalProcessorCount, //!< Only machine().logicalProcessorCount is valid
+        Basic,                 //!< Socket, core and hardware thread info
+        Full,                  //!< Cache, memory and numa node info
+        FullWithDevices        //!< Information about devices on the PCI bus
+    };
 
-        /*! \brief Amount of topology information present (incremental) */
-        enum class SupportLevel
-        {
-            None,                  //!< No hardware information whatsoever. Sorry.
-            LogicalProcessorCount, //!< Only machine().logicalProcessorCount is valid
-            Basic,                 //!< Socket, core and hardware thread info
-            Full,                  //!< Cache, memory and numa node info
-            FullWithDevices        //!< Information about devices on the PCI bus
-        };
+    /*! \libinternal \brief Information about a single cache level */
+    struct Cache
+    {
+        int         level;         //!< Level relative to core (starts at 1)
+        std::size_t size;          //!< size in bytes, 0 if unknown
+        int         linesize;      //!< size of each cache line in bytes, 0 if unknown
+        int         associativity; //!< associativity, -1 means fully associative
+        int         shared;        //!< Number of logical processors sharing this cache
+    };
 
-        /*! \libinternal \brief Information about a single cache level */
-        struct Cache
-        {
-            int                    level;          //!< Level relative to core (starts at 1)
-            std::size_t            size;           //!< size in bytes, 0 if unknown
-            int                    linesize;       //!< size of each cache line in bytes, 0 if unknown
-            int                    associativity;  //!< associativity, -1 means fully associative
-            int                    shared;         //!< Number of logical processors sharing this cache
-        };
+    /*! \libinternal \brief Information about a single hardware thread in a core
+     *
+     * The id of the thread typically increases continuously as you walk
+     * through sockets and cores in order of their ids. In general, this can
+     * be different from the logical processor id provided by the operating
+     * system. To achieve better load balancing when using SMT, Linux
+     * typically assigns logical processors in a round-robin fashion
+     * over all cores.
+     */
+    struct HWThread
+    {
+        int id;                 //!< Absolute id of this thread in hardware topology
+        int logicalProcessorId; //!< Id of the operating system logical processor
+    };
 
-        /*! \libinternal \brief Information about a single hardware thread in a core
-         *
-         * The id of the thread typically increases continuously as you walk
-         * through sockets and cores in order of their ids. In general, this can
-         * be different from the logical processor id provided by the operating
-         * system. To achieve better load balancing when using SMT, Linux
-         * typically assigns logical processors in a round-robin fashion
-         * over all cores.
-         */
-        struct HWThread
-        {
-            int                    id;                 //!< Absolute id of this thread in hardware topology
-            int                    logicalProcessorId; //!< Id of the operating system logical processor
-        };
+    /*! \libinternal \brief Information about a single core in a socket */
+    struct Core
+    {
+        int                   id;         //!< Absolute id of this core in hardware topology
+        int                   numaNodeId; //!< id of the numa node of this core
+        std::vector<HWThread> hwThreads;  //!< All the hardware threads in this core
+    };
 
-        /*! \libinternal \brief Information about a single core in a socket */
-        struct Core
-        {
-            int                    id;              //!< Absolute id of this core in hardware topology
-            int                    numaNodeId;      //!< id of the numa node of this core
-            std::vector<HWThread>  hwThreads;       //!< All the hardware threads in this core
-        };
+    /*! \libinternal \brief Information about a single socket in the system */
+    struct Socket
+    {
+        int               id;    //!< Absolute id of this socket in hardware topology
+        std::vector<Core> cores; //!< All the cores in this socket
+    };
 
-        /*! \libinternal \brief Information about a single socket in the system */
-        struct Socket
-        {
-            int                    id;             //!< Absolute id of this socket in hardware topology
-            std::vector<Core>      cores;          //!< All the cores in this socket
-        };
+    /*! \libinternal \brief Information about each numa node in system */
+    struct NumaNode
+    {
+        int              id;                 //!< Absolute id of numa node in hardware topology
+        std::size_t      memory;             //!< Total detected memory in bytes
+        std::vector<int> logicalProcessorId; //!< Vector of all the logical processors in this node
+    };
 
-        /*! \libinternal \brief Information about each numa node in system */
-        struct NumaNode
-        {
-            int                    id;                 //!< Absolute id of numa node in hardware topology
-            std::size_t            memory;             //!< Total detected memory in bytes
-            std::vector<int>       logicalProcessorId; //!< Vector of all the logical processors in this node
-        };
+    /*! \libinternal \brief Information about a single numa node */
+    struct Numa
+    {
+        std::vector<NumaNode> nodes;                     //!< Information about each numa node
+        float                 baseLatency;               //!< Scale factor for relative latencies
+        std::vector<std::vector<float>> relativeLatency; //!< 2D matrix of relative latencies between nodes
+        float                           maxRelativeLatency; //!< Largest relative latency
+    };
 
-        /*! \libinternal \brief Information about a single numa node */
-        struct Numa
-        {
-            std::vector<NumaNode>               nodes;              //!< Information about each numa node
-            float                               baseLatency;        //!< Scale factor for relative latencies
-            std::vector< std::vector<float> >   relativeLatency;    //!< 2D matrix of relative latencies between nodes
-            float                               maxRelativeLatency; //!< Largest relative latency
-        };
+    /*! \libinternal \brief Information about a single PCI device.
+     *
+     *  \note On many systems the PCI bus is not directly connected to any numa node.
+     *        For these systems the numaNodeId will be -1, so you cannot rely on this
+     *        number reflecting a specific numa node.
+     */
+    struct Device
+    {
+        std::uint16_t vendorId;   //!< Vendor identification
+        std::uint16_t deviceId;   //!< Vendor-specific device identification
+        std::uint16_t classId;    //!< class (high 8 bits) and subclass (low 8 bits)
+        std::uint16_t domain;     //!< Domain, usually 0 for PCI bus
+        std::uint8_t  bus;        //!< Bus number in domain
+        std::uint8_t  dev;        //!< Device on bus
+        std::uint8_t  func;       //!< Function id for multi-function devices
+        int           numaNodeId; //!< Numa node, -1 if the bus is not located inside a node
+    };
 
-        /*! \libinternal \brief Information about a single PCI device.
-         *
-         *  \note On many systems the PCI bus is not directly connected to any numa node.
-         *        For these systems the numaNodeId will be -1, so you cannot rely on this
-         *        number reflecting a specific numa node.
-         */
-        struct Device
-        {
-            std::uint16_t          vendorId;    //!< Vendor identification
-            std::uint16_t          deviceId;    //!< Vendor-specific device identification
-            std::uint16_t          classId;     //!< class (high 8 bits) and subclass (low 8 bits)
-            std::uint16_t          domain;      //!< Domain, usually 0 for PCI bus
-            std::uint8_t           bus;         //!< Bus number in domain
-            std::uint8_t           dev;         //!< Device on bus
-            std::uint8_t           func;        //!< Function id for multi-function devices
-            int                    numaNodeId;  //!< Numa node, -1 if the bus is not located inside a node
-        };
+    /*! \libinternal \brief Information about socket, core and hwthread for a logical processor */
+    struct LogicalProcessor
+    {
+        int socketRankInMachine; //!< Index of socket in machine
+        int coreRankInSocket;    //!< Index of core in socket
+        int hwThreadRankInCore;  //!< Index of hardware thread in core
+        int numaNodeId;          //!< Index of numa node
+    };
 
-        /*! \libinternal \brief Information about socket, core and hwthread for a logical processor */
-        struct LogicalProcessor
-        {
-            int                    socketRankInMachine; //!< Index of socket in machine
-            int                    coreRankInSocket;    //!< Index of core in socket
-            int                    hwThreadRankInCore;  //!< Index of hardware thread in core
-            int                    numaNodeId;          //!< Index of numa node
-        };
+    /*! \libinternal \brief Hardware topology information about the entire machine
+     *
+     * The machine structure is a tree with top-down information about all
+     * sockets, cores, and hardware threads in the system. For example, an
+     * operating system logical processor index can be found as
+     * machine.socket[0].core[1].hwthread[2].logicalProcessorId.
+     * In some cases you might need the opposite lookup, i.e. the physical
+     * hardware data for a specific logical processor. This is present in the
+     * logicalProcessor vector for convenience.
+     *
+     * \note The logicalProcessor vector will only have non-zero length if the
+     *       support level is SupportLevel::Basic or higher. You cannot use the
+     *       size of this vector to query the number of logical processors on
+     *       lower support levels.
+     */
+    struct Machine
+    {
+        Machine();
 
-        /*! \libinternal \brief Hardware topology information about the entire machine
-         *
-         * The machine structure is a tree with top-down information about all
-         * sockets, cores, and hardware threads in the system. For example, an
-         * operating system logical processor index can be found as
-         * machine.socket[0].core[1].hwthread[2].logicalProcessorId.
-         * In some cases you might need the opposite lookup, i.e. the physical
-         * hardware data for a specific logical processor. This is present in the
-         * logicalProcessor vector for convenience.
-         *
-         * \note The logicalProcessor vector will only have non-zero length if the
-         *       support level is SupportLevel::Basic or higher. You cannot use the
-         *       size of this vector to query the number of logical processors on
-         *       lower support levels.
-         */
-        struct Machine
-        {
-            Machine();
+        int logicalProcessorCount;                       //!< Number of logical processors in system
+        std::vector<LogicalProcessor> logicalProcessors; //!< Map logical processors to socket/core
+        std::vector<Socket>           sockets;           //!< All the sockets in the system
+        std::vector<Cache>            caches;            //!< Caches in increasing level order
+        Numa                          numa;              //!< Structure with all numa information
+        std::vector<Device>           devices;           //!< Devices on PCI bus
+    };
 
-            int                            logicalProcessorCount; //!< Number of logical processors in system
-            std::vector<LogicalProcessor>  logicalProcessors;     //!< Map logical processors to socket/core
-            std::vector<Socket>            sockets;               //!< All the sockets in the system
-            std::vector<Cache>             caches;                //!< Caches in increasing level order
-            Numa                           numa;                  //!< Structure with all numa information
-            std::vector<Device>            devices;               //!< Devices on PCI bus
-        };
+public:
+    /*! \brief Detects the hardware topology. */
+    static HardwareTopology detect();
 
-    public:
+    /*! \brief Creates a topology with given number of logical cores.
+     *
+     * The support level will be either None or LogicalProcessorCount.
+     *
+     * Intended for testing of code that uses the hardware topology.
+     */
+    explicit HardwareTopology(int logicalProcessorCount);
 
-        /*! \brief Detects the hardware topology. */
-        static HardwareTopology detect();
+    /*! \brief Check what topology information that is available and valid
+     *
+     *  The amount of hardware topology information that can be detected depends
+     *  on both the hardware and whether GROMACS was linked with the external
+     *  hwloc library. You cannot assume that any information is present,
+     *  although we can almost always provide the number of logical processors.
+     *  On x86 we can usually get basic information about how sockets, cores
+     *  and hardware threads are ordered even without hwloc.
+     *  With the hwloc library we can usually also get information about cache,
+     *  memory and concepts such as core groups and ccNUMA nodes.
+     *  Finally, if hwloc was built with support for libpci we can also
+     *  detect how the PCI devices are connected.
+     */
+    SupportLevel supportLevel() const { return supportLevel_; }
 
-        /*! \brief Creates a topology with given number of logical cores.
-         *
-         * The support level will be either None or LogicalProcessorCount.
-         *
-         * Intended for testing of code that uses the hardware topology.
-         */
-        explicit HardwareTopology(int logicalProcessorCount);
+    /*! \brief Return true if we actually detected hardware.
+     *
+     *  \return This method will normally return true, when we actually ran
+     *          the hardware detection as part of this process to construct
+     *          the object. It will be false when the object was constructed
+     *          by reading a cached XML file, or possibly generated from
+     *          synthetic data.
+     */
+    bool isThisSystem() const { return isThisSystem_; }
 
-        /*! \brief Check what topology information that is available and valid
-         *
-         *  The amount of hardware topology information that can be detected depends
-         *  on both the hardware and whether GROMACS was linked with the external
-         *  hwloc library. You cannot assume that any information is present,
-         *  although we can almost always provide the number of logical processors.
-         *  On x86 we can usually get basic information about how sockets, cores
-         *  and hardware threads are ordered even without hwloc.
-         *  With the hwloc library we can usually also get information about cache,
-         *  memory and concepts such as core groups and ccNUMA nodes.
-         *  Finally, if hwloc was built with support for libpci we can also
-         *  detect how the PCI devices are connected.
-         */
-        SupportLevel
-        supportLevel() const { return supportLevel_; }
+    /*! \brief Return the machine topology tree
+     *
+     *  You can always call this routine, but be aware that some or all contents
+     *  will not be valid unless supportLevel() returns a sufficient level.
+     *
+     *  - With SupportLevel::LogicalProcessorCount, only the field
+     *    machine.logicalProcessorCount is valid.
+     *  - With SupportLevel::Basic, you can access the vectors of sockets,
+     *    cores, and hardware threads, and query what logical processorId
+     *    each hardware thread corresponds to.
+     *  - SupportLevel::Full adds cache, memory and ccNUMA information.
+     *  - SupportLevel::FullWithDevices also adds the PCI express bus.
+     *
+     *  While data that is not valid has been initialized to special values,
+     *  you should not rely on those but query the supportLevel() method before
+     *  accessing it.
+     */
+    const Machine& machine() const { return machine_; }
 
-        /*! \brief Return true if we actually detected hardware.
-         *
-         *  \return This method will normally return true, when we actually ran
-         *          the hardware detection as part of this process to construct
-         *          the object. It will be false when the object was constructed
-         *          by reading a cached XML file, or possibly generated from
-         *          synthetic data.
-         */
-        bool
-        isThisSystem() const { return isThisSystem_; }
+    /*! \brief Returns the number of cores.
+     *
+     * You can always call this routine, but if sufficient support is not
+     * available, it may return the logical processor count or zero instead
+     * of the physical core count.
+     */
+    int numberOfCores() const;
 
-        /*! \brief Return the machine topology tree
-         *
-         *  You can always call this routine, but be aware that some or all contents
-         *  will not be valid unless supportLevel() returns a sufficient level.
-         *
-         *  - With SupportLevel::LogicalProcessorCount, only the field
-         *    machine.logicalProcessorCount is valid.
-         *  - With SupportLevel::Basic, you can access the vectors of sockets,
-         *    cores, and hardware threads, and query what logical processorId
-         *    each hardware thread corresponds to.
-         *  - SupportLevel::Full adds cache, memory and ccNUMA information.
-         *  - SupportLevel::FullWithDevices also adds the PCI express bus.
-         *
-         *  While data that is not valid has been initialized to special values,
-         *  you should not rely on those but query the supportLevel() method before
-         *  accessing it.
-         */
-        const Machine &
-        machine() const { return machine_; }
+private:
+    HardwareTopology();
 
-        /*! \brief Returns the number of cores.
-         *
-         * You can always call this routine, but if sufficient support is not
-         * available, it may return the logical processor count or zero instead
-         * of the physical core count.
-         */
-        int numberOfCores() const;
-
-    private:
-
-        HardwareTopology();
-
-        SupportLevel        supportLevel_; //!< Available topology information
-        Machine             machine_;      //!< The machine map
-        bool                isThisSystem_; //!< Machine map is real (vs. cached/synthetic)
+    SupportLevel supportLevel_; //!< Available topology information
+    Machine      machine_;      //!< The machine map
+    bool         isThisSystem_; //!< Machine map is real (vs. cached/synthetic)
 };
 
-}      // namespace gmx
+} // namespace gmx
 
 #endif // GMX_HARDWARE_HARDWARETOPOLOGY_H