mirror of
https://github.com/xmrig/xmrig.git
synced 2024-10-30 21:17:52 +00:00
Update hwloc for MSVC to 2.4.0.
This commit is contained in:
parent
7c682ec91a
commit
ca3695a754
42 changed files with 4057 additions and 382 deletions
36
src/3rdparty/hwloc/CMakeLists.txt
vendored
36
src/3rdparty/hwloc/CMakeLists.txt
vendored
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required (VERSION 2.8)
|
||||
cmake_minimum_required (VERSION 2.8.12)
|
||||
project (hwloc C)
|
||||
|
||||
include_directories(include)
|
||||
|
@ -13,23 +13,25 @@ set(HEADERS
|
|||
)
|
||||
|
||||
set(SOURCES
|
||||
src/base64.c
|
||||
src/bind.c
|
||||
src/bitmap.c
|
||||
src/components.c
|
||||
src/diff.c
|
||||
src/distances.c
|
||||
src/misc.c
|
||||
src/pci-common.c
|
||||
src/shmem.c
|
||||
src/topology.c
|
||||
src/topology-noos.c
|
||||
src/topology-synthetic.c
|
||||
src/topology-windows.c
|
||||
src/topology-x86.c
|
||||
src/topology-xml.c
|
||||
src/topology-xml-nolibxml.c
|
||||
src/base64.c
|
||||
src/bind.c
|
||||
src/bitmap.c
|
||||
src/components.c
|
||||
src/diff.c
|
||||
src/distances.c
|
||||
src/misc.c
|
||||
src/pci-common.c
|
||||
src/shmem.c
|
||||
src/topology.c
|
||||
src/topology-noos.c
|
||||
src/topology-synthetic.c
|
||||
src/topology-windows.c
|
||||
src/topology-x86.c
|
||||
src/topology-xml.c
|
||||
src/topology-xml-nolibxml.c
|
||||
src/traversal.c
|
||||
src/memattrs.c
|
||||
src/cpukinds.c
|
||||
)
|
||||
|
||||
add_library(hwloc STATIC
|
||||
|
|
71
src/3rdparty/hwloc/NEWS
vendored
71
src/3rdparty/hwloc/NEWS
vendored
|
@ -2,6 +2,7 @@ Copyright © 2009 CNRS
|
|||
Copyright © 2009-2020 Inria. All rights reserved.
|
||||
Copyright © 2009-2013 Université Bordeaux
|
||||
Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
Copyright © 2020 Hewlett Packard Enterprise. All rights reserved.
|
||||
|
||||
$COPYRIGHT$
|
||||
|
||||
|
@ -16,6 +17,76 @@ bug fixes (and other actions) for each version of hwloc since version
|
|||
0.9.
|
||||
|
||||
|
||||
Version 2.4.0
|
||||
-------------
|
||||
* API
|
||||
+ Add hwloc/cpukinds.h for reporting information about hybrid CPUs.
|
||||
- Use Linux cpufreq frequencies to rank cores by efficiency.
|
||||
- Use x86 CPUID hybrid leaf and future Linux kernels sysfs CPU type
|
||||
files to identify Intel Atom and Core cores.
|
||||
- Use the Windows native EfficiencyClass to separate kinds.
|
||||
* Backends
|
||||
+ Properly handle Linux kernel 5.10+ exposing ACPI HMAT information
|
||||
with knowledge of Generic Initiators.
|
||||
* Tools
|
||||
+ lstopo has new --cpukinds and --no-cpukinds options for showing
|
||||
CPU kinds or not in textual and graphical modes respectively.
|
||||
+ hwloc-calc has a new --cpukind option for filtering PUs by kind.
|
||||
+ hwloc-annotate has a new cpukind command for modifying CPU kinds.
|
||||
* Misc
|
||||
+ Fix hwloc_bitmap_nr_ulongs(), thanks to Norbert Eicker.
|
||||
+ Add a documentation section about
|
||||
"Topology Attributes: Distances, Memory Attributes and CPU Kinds".
|
||||
+ Silence some spurious warnings in the OpenCL backend and when showing
|
||||
process binding with lstopo --ps.
|
||||
|
||||
|
||||
Version 2.3.0
|
||||
-------------
|
||||
* API
|
||||
+ Add hwloc/memattrs.h for exposing latency/bandwidth information
|
||||
between initiators (CPU sets for now) and target NUMA nodes,
|
||||
typically on heterogeneous platforms.
|
||||
- When available, bandwidths and latencies are read from the ACPI HMAT
|
||||
table exposed by Linux kernel 5.2+.
|
||||
- Attributes may also be customized to expose user-defined performance
|
||||
information.
|
||||
+ Add hwloc_get_local_numanode_objs() for listing NUMA nodes that are
|
||||
local to some locality.
|
||||
+ The new topology flag HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT causes
|
||||
support arrays to be loaded from XML exported with hwloc 2.3+.
|
||||
- hwloc_topology_get_support() now returns an additional "misc"
|
||||
array with feature "imported_support" set when support was imported.
|
||||
+ Add hwloc_topology_refresh() to refresh internal caches after modifying
|
||||
the topology and before consulting the topology in a multithread context.
|
||||
* Backends
|
||||
+ Add a ROCm SMI backend and a hwloc/rsmi.h helper file for getting
|
||||
the locality of AMD GPUs, now exposed as "rsmi" OS devices.
|
||||
Thanks to Mike Li.
|
||||
+ Remove POWER device-tree-based topology on Linux,
|
||||
(it was disabled by default since 2.1).
|
||||
* Tools
|
||||
+ Command-line options for specifying flags now understand comma-separated
|
||||
lists of flag names (substrings).
|
||||
+ hwloc-info and hwloc-calc have new --local-memory --local-memory-flags
|
||||
and --best-memattr options for reporting local memory nodes and filtering
|
||||
by memory attributes.
|
||||
+ hwloc-bind has a new --best-memattr option for filtering by memory attributes
|
||||
among the memory binding set.
|
||||
+ Tools that have a --restrict option may now receive a nodeset or
|
||||
some custom flags for restricting the topology.
|
||||
+ lstopo now has a --thickness option for changing line thickness in the
|
||||
graphical output.
|
||||
+ Fix lstopo drawing when autoresizing on Windows 10.
|
||||
+ Pressing the F5 key in lstopo X11 and Windows graphical/interactive outputs
|
||||
now refreshes the display according to the current topology and binding.
|
||||
+ Add a tikz lstopo graphical backend to generate picture easily included into
|
||||
LaTeX documents. Thanks to Clement Foyer.
|
||||
* Misc
|
||||
+ The default installation path of the Bash completion file has changed to
|
||||
${datadir}/bash-completion/completions/hwloc. Thanks to Tomasz Kłoczko.
|
||||
|
||||
|
||||
Version 2.2.0
|
||||
-------------
|
||||
* API
|
||||
|
|
8
src/3rdparty/hwloc/README
vendored
8
src/3rdparty/hwloc/README
vendored
|
@ -23,9 +23,9 @@ APIs are documented after these sections.
|
|||
|
||||
Installation
|
||||
|
||||
hwloc (http://www.open-mpi.org/projects/hwloc/) is available under the BSD
|
||||
license. It is hosted as a sub-project of the overall Open MPI project (http://
|
||||
www.open-mpi.org/). Note that hwloc does not require any functionality from
|
||||
hwloc (https://www.open-mpi.org/projects/hwloc/) is available under the BSD
|
||||
license. It is hosted as a sub-project of the overall Open MPI project (https:/
|
||||
/www.open-mpi.org/). Note that hwloc does not require any functionality from
|
||||
Open MPI -- it is a wholly separate (and much smaller!) project and code base.
|
||||
It just happens to be hosted as part of the overall Open MPI project.
|
||||
|
||||
|
@ -75,7 +75,7 @@ Bugs should be reported in the tracker (https://github.com/open-mpi/hwloc/
|
|||
issues). Opening a new issue automatically displays lots of hints about how to
|
||||
debug and report issues.
|
||||
|
||||
Questions may be sent to the users or developers mailing lists (http://
|
||||
Questions may be sent to the users or developers mailing lists (https://
|
||||
www.open-mpi.org/community/lists/hwloc.php).
|
||||
|
||||
There is also a #hwloc IRC channel on Freenode (irc.freenode.net).
|
||||
|
|
6
src/3rdparty/hwloc/VERSION
vendored
6
src/3rdparty/hwloc/VERSION
vendored
|
@ -8,7 +8,7 @@
|
|||
# Please update HWLOC_VERSION* in contrib/windows/hwloc_config.h too.
|
||||
|
||||
major=2
|
||||
minor=2
|
||||
minor=4
|
||||
release=0
|
||||
|
||||
# greek is used for alpha or beta release tags. If it is non-empty,
|
||||
|
@ -22,7 +22,7 @@ greek=
|
|||
|
||||
# The date when this release was created
|
||||
|
||||
date="Mar 30, 2020"
|
||||
date="Nov 26, 2020"
|
||||
|
||||
# If snapshot=1, then use the value from snapshot_version as the
|
||||
# entire hwloc version (i.e., ignore major, minor, release, and
|
||||
|
@ -41,7 +41,7 @@ snapshot_version=${major}.${minor}.${release}${greek}-git
|
|||
# 2. Version numbers are described in the Libtool current:revision:age
|
||||
# format.
|
||||
|
||||
libhwloc_so_version=17:0:2
|
||||
libhwloc_so_version=19:0:4
|
||||
libnetloc_so_version=0:0:0
|
||||
|
||||
# Please also update the <TargetName> lines in contrib/windows/libhwloc.vcxproj
|
||||
|
|
117
src/3rdparty/hwloc/include/hwloc.h
vendored
117
src/3rdparty/hwloc/include/hwloc.h
vendored
|
@ -2,7 +2,7 @@
|
|||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009-2012 Université Bordeaux
|
||||
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright © 2009-2020 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
|||
* ------------------------------------------------
|
||||
* $tarball_directory/doc/doxygen-doc/
|
||||
* or
|
||||
* http://www.open-mpi.org/projects/hwloc/doc/
|
||||
* https://www.open-mpi.org/projects/hwloc/doc/
|
||||
*=====================================================================
|
||||
*
|
||||
* FAIR WARNING: Do NOT expect to be able to figure out all the
|
||||
|
@ -93,7 +93,7 @@ extern "C" {
|
|||
* Two stable releases of the same series usually have the same ::HWLOC_API_VERSION
|
||||
* even if their HWLOC_VERSION are different.
|
||||
*/
|
||||
#define HWLOC_API_VERSION 0x00020100
|
||||
#define HWLOC_API_VERSION 0x00020400
|
||||
|
||||
/** \brief Indicate at runtime which hwloc API version was used at build time.
|
||||
*
|
||||
|
@ -102,7 +102,7 @@ extern "C" {
|
|||
HWLOC_DECLSPEC unsigned hwloc_get_api_version(void);
|
||||
|
||||
/** \brief Current component and plugin ABI version (see hwloc/plugins.h) */
|
||||
#define HWLOC_COMPONENT_ABI 6
|
||||
#define HWLOC_COMPONENT_ABI 7
|
||||
|
||||
/** @} */
|
||||
|
||||
|
@ -196,7 +196,7 @@ typedef enum {
|
|||
*/
|
||||
HWLOC_OBJ_CORE, /**< \brief Core.
|
||||
* A computation unit (may be shared by several
|
||||
* logical processors).
|
||||
* PUs, aka logical processors).
|
||||
*/
|
||||
HWLOC_OBJ_PU, /**< \brief Processing Unit, or (Logical) Processor.
|
||||
* An execution unit (may share a core with some
|
||||
|
@ -257,22 +257,31 @@ typedef enum {
|
|||
HWLOC_OBJ_BRIDGE, /**< \brief Bridge (filtered out by default).
|
||||
* Any bridge (or PCI switch) that connects the host or an I/O bus,
|
||||
* to another I/O bus.
|
||||
* They are not added to the topology unless I/O discovery
|
||||
* is enabled with hwloc_topology_set_flags().
|
||||
*
|
||||
* Bridges are not added to the topology unless their
|
||||
* filtering is changed (see hwloc_topology_set_type_filter()
|
||||
* and hwloc_topology_set_io_types_filter()).
|
||||
*
|
||||
* I/O objects are not listed in the main children list,
|
||||
* but rather in the dedicated io children list.
|
||||
* I/O objects have NULL CPU and node sets.
|
||||
*/
|
||||
HWLOC_OBJ_PCI_DEVICE, /**< \brief PCI device (filtered out by default).
|
||||
* They are not added to the topology unless I/O discovery
|
||||
* is enabled with hwloc_topology_set_flags().
|
||||
*
|
||||
* PCI devices are not added to the topology unless their
|
||||
* filtering is changed (see hwloc_topology_set_type_filter()
|
||||
* and hwloc_topology_set_io_types_filter()).
|
||||
*
|
||||
* I/O objects are not listed in the main children list,
|
||||
* but rather in the dedicated io children list.
|
||||
* I/O objects have NULL CPU and node sets.
|
||||
*/
|
||||
HWLOC_OBJ_OS_DEVICE, /**< \brief Operating system device (filtered out by default).
|
||||
* They are not added to the topology unless I/O discovery
|
||||
* is enabled with hwloc_topology_set_flags().
|
||||
*
|
||||
* OS devices are not added to the topology unless their
|
||||
* filtering is changed (see hwloc_topology_set_type_filter()
|
||||
* and hwloc_topology_set_io_types_filter()).
|
||||
*
|
||||
* I/O objects are not listed in the main children list,
|
||||
* but rather in the dedicated io children list.
|
||||
* I/O objects have NULL CPU and node sets.
|
||||
|
@ -282,6 +291,10 @@ typedef enum {
|
|||
* Objects without particular meaning, that can e.g. be
|
||||
* added by the application for its own use, or by hwloc
|
||||
* for miscellaneous objects such as MemoryModule (DIMMs).
|
||||
*
|
||||
* They are not added to the topology unless their filtering
|
||||
* is changed (see hwloc_topology_set_type_filter()).
|
||||
*
|
||||
* These objects are not listed in the main children list,
|
||||
* but rather in the dedicated misc children list.
|
||||
* Misc objects may only have Misc objects as children,
|
||||
|
@ -304,7 +317,6 @@ typedef enum {
|
|||
|
||||
HWLOC_OBJ_DIE, /**< \brief Die within a physical package.
|
||||
* A subpart of the physical package, that contains multiple cores.
|
||||
* \hideinitializer
|
||||
*/
|
||||
|
||||
HWLOC_OBJ_TYPE_MAX /**< \private Sentinel value */
|
||||
|
@ -338,8 +350,7 @@ typedef enum hwloc_obj_osdev_type_e {
|
|||
HWLOC_OBJ_OSDEV_DMA, /**< \brief Operating system dma engine device.
|
||||
* For instance the "dma0chan0" DMA channel on Linux. */
|
||||
HWLOC_OBJ_OSDEV_COPROC /**< \brief Operating system co-processor device.
|
||||
* For instance "mic0" for a Xeon Phi (MIC) on Linux,
|
||||
* "opencl0d0" for a OpenCL device,
|
||||
* For instance "opencl0d0" for a OpenCL device,
|
||||
* "cuda0" for a CUDA device. */
|
||||
} hwloc_obj_osdev_type_t;
|
||||
|
||||
|
@ -512,7 +523,7 @@ struct hwloc_obj {
|
|||
*
|
||||
* \note Its value must not be changed, hwloc_bitmap_dup() must be used instead.
|
||||
*/
|
||||
hwloc_cpuset_t complete_cpuset; /**< \brief The complete CPU set of logical processors of this object,
|
||||
hwloc_cpuset_t complete_cpuset; /**< \brief The complete CPU set of processors of this object,
|
||||
*
|
||||
* This may include not only the same as the cpuset field, but also some CPUs for
|
||||
* which topology information is unknown or incomplete, some offlines CPUs, and
|
||||
|
@ -533,6 +544,8 @@ struct hwloc_obj {
|
|||
* between this object and the NUMA node objects).
|
||||
*
|
||||
* In the end, these nodes are those that are close to the current object.
|
||||
* Function hwloc_get_local_numanode_objs() may be used to list those NUMA
|
||||
* nodes more precisely.
|
||||
*
|
||||
* If the ::HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED configuration flag is set,
|
||||
* some of these nodes may not be allowed for allocation,
|
||||
|
@ -1929,7 +1942,31 @@ enum hwloc_topology_flags_e {
|
|||
* would result in the same behavior.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_TOPOLOGY_FLAG_THISSYSTEM_ALLOWED_RESOURCES = (1UL<<2)
|
||||
HWLOC_TOPOLOGY_FLAG_THISSYSTEM_ALLOWED_RESOURCES = (1UL<<2),
|
||||
|
||||
/** \brief Import support from the imported topology.
|
||||
*
|
||||
* When importing a XML topology from a remote machine, binding is
|
||||
* disabled by default (see ::HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM).
|
||||
* This disabling is also marked by putting zeroes in the corresponding
|
||||
* supported feature bits reported by hwloc_topology_get_support().
|
||||
*
|
||||
* The flag ::HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT actually imports
|
||||
* support bits from the remote machine. It also sets the flag
|
||||
* \p imported_support in the struct hwloc_topology_misc_support array.
|
||||
* If the imported XML did not contain any support information
|
||||
* (exporter hwloc is too old), this flag is not set.
|
||||
*
|
||||
* Note that these supported features are only relevant for the hwloc
|
||||
* installation that actually exported the XML topology
|
||||
* (it may vary with the operating system, or with how hwloc was compiled).
|
||||
*
|
||||
* Note that setting this flag however does not enable binding for the
|
||||
* locally imported hwloc topology, it only reports what the remote
|
||||
* hwloc and machine support.
|
||||
*
|
||||
*/
|
||||
HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT = (1UL<<3)
|
||||
};
|
||||
|
||||
/** \brief Set OR'ed flags to non-yet-loaded topology.
|
||||
|
@ -1972,6 +2009,8 @@ struct hwloc_topology_discovery_support {
|
|||
unsigned char disallowed_pu;
|
||||
/** \brief Detecting and identifying NUMA nodes that are not available to the current process is supported. */
|
||||
unsigned char disallowed_numa;
|
||||
/** \brief Detecting the efficiency of CPU kinds is supported, see \ref hwlocality_cpukinds. */
|
||||
unsigned char cpukind_efficiency;
|
||||
};
|
||||
|
||||
/** \brief Flags describing actual PU binding support for this topology.
|
||||
|
@ -2042,6 +2081,13 @@ struct hwloc_topology_membind_support {
|
|||
unsigned char get_area_memlocation;
|
||||
};
|
||||
|
||||
/** \brief Flags describing miscellaneous features.
|
||||
*/
|
||||
struct hwloc_topology_misc_support {
|
||||
/** Support was imported when importing another topology, see ::HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT. */
|
||||
unsigned char imported_support;
|
||||
};
|
||||
|
||||
/** \brief Set of flags describing actual support for this topology.
|
||||
*
|
||||
* This is retrieved with hwloc_topology_get_support() and will be valid until
|
||||
|
@ -2052,6 +2098,7 @@ struct hwloc_topology_support {
|
|||
struct hwloc_topology_discovery_support *discovery;
|
||||
struct hwloc_topology_cpubind_support *cpubind;
|
||||
struct hwloc_topology_membind_support *membind;
|
||||
struct hwloc_topology_misc_support *misc;
|
||||
};
|
||||
|
||||
/** \brief Retrieve the topology support.
|
||||
|
@ -2062,6 +2109,18 @@ struct hwloc_topology_support {
|
|||
* call may still fail in some corner cases.
|
||||
*
|
||||
* These features are also listed by hwloc-info \--support
|
||||
*
|
||||
* The reported features are what the current topology supports
|
||||
* on the current machine. If the topology was exported to XML
|
||||
* from another machine and later imported here, support still
|
||||
* describes what is supported for this imported topology after
|
||||
* import. By default, binding will be reported as unsupported
|
||||
* in this case (see ::HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM).
|
||||
*
|
||||
* Topology flag ::HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT may be used
|
||||
* to report the supported features of the original remote machine
|
||||
* instead. If it was successfully imported, \p imported_support
|
||||
* will be set in the struct hwloc_topology_misc_support array.
|
||||
*/
|
||||
HWLOC_DECLSPEC const struct hwloc_topology_support *hwloc_topology_get_support(hwloc_topology_t __hwloc_restrict topology);
|
||||
|
||||
|
@ -2108,8 +2167,8 @@ enum hwloc_type_filter_e {
|
|||
*
|
||||
* It is only useful for I/O object types.
|
||||
* For ::HWLOC_OBJ_PCI_DEVICE and ::HWLOC_OBJ_OS_DEVICE, it means that only objects
|
||||
* of major/common kinds are kept (storage, network, OpenFabrics, Intel MICs, CUDA,
|
||||
* OpenCL, NVML, and displays).
|
||||
* of major/common kinds are kept (storage, network, OpenFabrics, CUDA,
|
||||
* OpenCL, RSMI, NVML, and displays).
|
||||
* Also, only OS devices directly attached on PCI (e.g. no USB) are reported.
|
||||
* For ::HWLOC_OBJ_BRIDGE, it means that bridges are kept only if they have children.
|
||||
*
|
||||
|
@ -2371,6 +2430,22 @@ HWLOC_DECLSPEC hwloc_obj_t hwloc_topology_insert_group_object(hwloc_topology_t t
|
|||
*/
|
||||
HWLOC_DECLSPEC int hwloc_obj_add_other_obj_sets(hwloc_obj_t dst, hwloc_obj_t src);
|
||||
|
||||
/** \brief Refresh internal structures after topology modification.
|
||||
*
|
||||
* Modifying the topology (by restricting, adding objects, modifying structures
|
||||
* such as distances or memory attributes, etc.) may cause some internal caches
|
||||
* to become invalid. These caches are automatically refreshed when accessed
|
||||
* but this refreshing is not thread-safe.
|
||||
*
|
||||
* This function is not thread-safe either, but it is a good way to end a
|
||||
* non-thread-safe phase of topology modification. Once this refresh is done,
|
||||
* multiple threads may concurrently consult the topology, objects, distances,
|
||||
* attributes, etc.
|
||||
*
|
||||
* See also \ref threadsafety
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_topology_refresh(hwloc_topology_t topology);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
@ -2386,6 +2461,12 @@ HWLOC_DECLSPEC int hwloc_obj_add_other_obj_sets(hwloc_obj_t dst, hwloc_obj_t src
|
|||
/* inline code of some functions above */
|
||||
#include "hwloc/inlines.h"
|
||||
|
||||
/* memory attributes */
|
||||
#include "hwloc/memattrs.h"
|
||||
|
||||
/* kinds of CPU cores */
|
||||
#include "hwloc/cpukinds.h"
|
||||
|
||||
/* exporting to XML or synthetic */
|
||||
#include "hwloc/export.h"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2019 Inria. All rights reserved.
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009-2012 Université Bordeaux
|
||||
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
|
@ -11,9 +11,9 @@
|
|||
#ifndef HWLOC_CONFIG_H
|
||||
#define HWLOC_CONFIG_H
|
||||
|
||||
#define HWLOC_VERSION "2.2.0"
|
||||
#define HWLOC_VERSION "2.4.0"
|
||||
#define HWLOC_VERSION_MAJOR 2
|
||||
#define HWLOC_VERSION_MINOR 2
|
||||
#define HWLOC_VERSION_MINOR 4
|
||||
#define HWLOC_VERSION_RELEASE 0
|
||||
#define HWLOC_VERSION_GREEK ""
|
||||
|
||||
|
|
4
src/3rdparty/hwloc/include/hwloc/bitmap.h
vendored
4
src/3rdparty/hwloc/include/hwloc/bitmap.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2018 Inria. All rights reserved.
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009-2012 Université Bordeaux
|
||||
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
|
@ -231,7 +231,7 @@ HWLOC_DECLSPEC int hwloc_bitmap_clr_range(hwloc_bitmap_t bitmap, unsigned begin,
|
|||
/** \brief Keep a single index among those set in bitmap \p bitmap
|
||||
*
|
||||
* May be useful before binding so that the process does not
|
||||
* have a chance of migrating between multiple logical CPUs
|
||||
* have a chance of migrating between multiple processors
|
||||
* in the original mask.
|
||||
* Instead of running the task on any PU inside the given CPU set,
|
||||
* the operating system scheduler will be forced to run it on a single
|
||||
|
|
188
src/3rdparty/hwloc/include/hwloc/cpukinds.h
vendored
Normal file
188
src/3rdparty/hwloc/include/hwloc/cpukinds.h
vendored
Normal file
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* Copyright © 2020 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Kinds of CPU cores.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_CPUKINDS_H
|
||||
#define HWLOC_CPUKINDS_H
|
||||
|
||||
#include "hwloc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#elif 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \defgroup hwlocality_cpukinds Kinds of CPU cores
|
||||
*
|
||||
* Platforms with heterogeneous CPUs may have some cores with
|
||||
* different features or frequencies.
|
||||
* This API exposes identical PUs in sets called CPU kinds.
|
||||
* Each PU of the topology may only be in a single kind.
|
||||
*
|
||||
* The number of kinds may be obtained with hwloc_cpukinds_get_nr().
|
||||
* If the platform is homogeneous, there may be a single kind
|
||||
* with all PUs.
|
||||
* If the platform or operating system does not expose any
|
||||
* information about CPU cores, there may be no kind at all.
|
||||
*
|
||||
* The index of the kind that describes a given CPU set
|
||||
* (if any, and not partially)
|
||||
* may be obtained with hwloc_cpukinds_get_by_cpuset().
|
||||
*
|
||||
* From the index of a kind, it is possible to retrieve information
|
||||
* with hwloc_cpukinds_get_info():
|
||||
* an abstracted efficiency value,
|
||||
* and an array of info attributes
|
||||
* (for instance the "CoreType" and "FrequencyMaxMHz",
|
||||
* see \ref topoattrs_cpukinds).
|
||||
*
|
||||
* A higher efficiency value means intrinsic greater performance
|
||||
* (and possibly less performance/power efficiency).
|
||||
* Kinds with lower efficiency are ranked first:
|
||||
* Passing 0 as \p kind_index to hwloc_cpukinds_get_info() will
|
||||
* return information about the less efficient CPU kind.
|
||||
*
|
||||
* When available, efficiency values are gathered from the operating
|
||||
* system (when \p cpukind_efficiency is set in the
|
||||
* struct hwloc_topology_discovery_support array, only on Windows 10 for now).
|
||||
* Otherwise hwloc tries to compute efficiencies
|
||||
* by comparing CPU kinds using frequencies (on ARM),
|
||||
* or core types and frequencies (on other architectures).
|
||||
* The environment variable HWLOC_CPUKINDS_RANKING may be used
|
||||
* to change this heuristics, see \ref envvar.
|
||||
*
|
||||
* If hwloc fails to rank any kind, for instance because the operating
|
||||
* system does not expose efficiencies and core frequencies,
|
||||
* all kinds will have an unknown efficiency (\c -1),
|
||||
* and they are not indexed/ordered in any specific way.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Get the number of different kinds of CPU cores in the topology.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* \return The number of CPU kinds (positive integer) on success.
|
||||
* \return \c 0 if no information about kinds was found.
|
||||
* \return \c -1 with \p errno set to \c EINVAL if \p flags is invalid.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_cpukinds_get_nr(hwloc_topology_t topology,
|
||||
unsigned long flags);
|
||||
|
||||
/** \brief Get the index of the CPU kind that contains CPUs listed in \p cpuset.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* \return The index of the CPU kind (positive integer or 0) on success.
|
||||
* \return \c -1 with \p errno set to \c EXDEV if \p cpuset is
|
||||
* only partially included in the some kind.
|
||||
* \return \c -1 with \p errno set to \c ENOENT if \p cpuset is
|
||||
* not included in any kind, even partially.
|
||||
* \return \c -1 with \p errno set to \c EINVAL if parameters are invalid.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_cpukinds_get_by_cpuset(hwloc_topology_t topology,
|
||||
hwloc_const_bitmap_t cpuset,
|
||||
unsigned long flags);
|
||||
|
||||
/** \brief Get the CPU set and infos about a CPU kind in the topology.
|
||||
*
|
||||
* \p kind_index identifies one kind of CPU between 0 and the number
|
||||
* of kinds returned by hwloc_cpukinds_get_nr() minus 1.
|
||||
*
|
||||
* If not \c NULL, the bitmap \p cpuset will be filled with
|
||||
* the set of PUs of this kind.
|
||||
*
|
||||
* The integer pointed by \p efficiency, if not \c NULL will, be filled
|
||||
* with the ranking of this kind of CPU in term of efficiency (see above).
|
||||
* It ranges from \c 0 to the number of kinds
|
||||
* (as reported by hwloc_cpukinds_get_nr()) minus 1.
|
||||
*
|
||||
* Kinds with lower efficiency are reported first.
|
||||
*
|
||||
* If there is a single kind in the topology, its efficiency \c 0.
|
||||
* If the efficiency of some kinds of cores is unknown,
|
||||
* the efficiency of all kinds is set to \c -1,
|
||||
* and kinds are reported in no specific order.
|
||||
*
|
||||
* The array of info attributes (for instance the "CoreType",
|
||||
* "FrequencyMaxMHz" or "FrequencyBaseMHz", see \ref topoattrs_cpukinds)
|
||||
* and its length are returned in \p infos or \p nr_infos.
|
||||
* The array belongs to the topology, it should not be freed or modified.
|
||||
*
|
||||
* If \p nr_infos or \p infos is \c NULL, no info is returned.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c -1 with \p errno set to \c ENOENT if \p kind_index does not match any CPU kind.
|
||||
* \return \c -1 with \p errno set to \c EINVAL if parameters are invalid.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_cpukinds_get_info(hwloc_topology_t topology,
|
||||
unsigned kind_index,
|
||||
hwloc_bitmap_t cpuset,
|
||||
int *efficiency,
|
||||
unsigned *nr_infos, struct hwloc_info_s **infos,
|
||||
unsigned long flags);
|
||||
|
||||
/** \brief Register a kind of CPU in the topology.
|
||||
*
|
||||
* Mark the PUs listed in \p cpuset as being of the same kind
|
||||
* with respect to the given attributes.
|
||||
*
|
||||
* \p forced_efficiency should be \c -1 if unknown.
|
||||
* Otherwise it is an abstracted efficiency value to enforce
|
||||
* the ranking of all kinds if all of them have valid (and
|
||||
* different) efficiencies.
|
||||
*
|
||||
* The array \p infos of size \p nr_infos may be used to provide
|
||||
* info names and values describing this kind of PUs.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* Parameters \p cpuset and \p infos will be duplicated internally,
|
||||
* the caller is responsible for freeing them.
|
||||
*
|
||||
* If \p cpuset overlaps with some existing kinds, those might get
|
||||
* modified or split. For instance if existing kind A contains
|
||||
* PUs 0 and 1, and one registers another kind for PU 1 and 2,
|
||||
* there will be 3 resulting kinds:
|
||||
* existing kind A is restricted to only PU 0;
|
||||
* new kind B contains only PU 1 and combines information from A
|
||||
* and from the newly-registered kind;
|
||||
* new kind C contains only PU 2 and only gets information from
|
||||
* the newly-registered kind.
|
||||
*
|
||||
* \note The efficiency \p forced_efficiency provided to this function
|
||||
* may be different from the one reported later by hwloc_cpukinds_get_info()
|
||||
* because hwloc will scale efficiency values down to
|
||||
* between 0 and the number of kinds minus 1.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c -1 with \p errno set to \c EINVAL if some parameters are invalid,
|
||||
* for instance if \p cpuset is \c NULL or empty.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_cpukinds_register(hwloc_topology_t topology,
|
||||
hwloc_bitmap_t cpuset,
|
||||
int forced_efficiency,
|
||||
unsigned nr_infos, struct hwloc_info_s *infos,
|
||||
unsigned long flags);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_CPUKINDS_H */
|
4
src/3rdparty/hwloc/include/hwloc/cuda.h
vendored
4
src/3rdparty/hwloc/include/hwloc/cuda.h
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2010-2017 Inria. All rights reserved.
|
||||
* Copyright © 2010-2020 Inria. All rights reserved.
|
||||
* Copyright © 2010-2011 Université Bordeaux
|
||||
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
|
@ -72,7 +72,7 @@ hwloc_cuda_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Get the CPU set of logical processors that are physically
|
||||
/** \brief Get the CPU set of processors that are physically
|
||||
* close to device \p cudevice.
|
||||
*
|
||||
* Return the CPU set describing the locality of the CUDA device \p cudevice.
|
||||
|
|
4
src/3rdparty/hwloc/include/hwloc/cudart.h
vendored
4
src/3rdparty/hwloc/include/hwloc/cudart.h
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2010-2017 Inria. All rights reserved.
|
||||
* Copyright © 2010-2020 Inria. All rights reserved.
|
||||
* Copyright © 2010-2011 Université Bordeaux
|
||||
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
|
@ -69,7 +69,7 @@ hwloc_cudart_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unus
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Get the CPU set of logical processors that are physically
|
||||
/** \brief Get the CPU set of processors that are physically
|
||||
* close to device \p idx.
|
||||
*
|
||||
* Return the CPU set describing the locality of the CUDA device
|
||||
|
|
6
src/3rdparty/hwloc/include/hwloc/diff.h
vendored
6
src/3rdparty/hwloc/include/hwloc/diff.h
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2013-2018 Inria. All rights reserved.
|
||||
* Copyright © 2013-2020 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
|
@ -110,7 +110,7 @@ union hwloc_topology_diff_obj_attr_u {
|
|||
*/
|
||||
typedef enum hwloc_topology_diff_type_e {
|
||||
/** \brief An object attribute was changed.
|
||||
* The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_s.
|
||||
* The union is a hwloc_topology_diff_u::hwloc_topology_diff_obj_attr_s.
|
||||
*/
|
||||
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR,
|
||||
|
||||
|
@ -119,7 +119,7 @@ typedef enum hwloc_topology_diff_type_e {
|
|||
* this object has not been checked.
|
||||
* hwloc_topology_diff_build() will return 1.
|
||||
*
|
||||
* The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_too_complex_s.
|
||||
* The union is a hwloc_topology_diff_u::hwloc_topology_diff_too_complex_s.
|
||||
*/
|
||||
HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX
|
||||
} hwloc_topology_diff_type_t;
|
||||
|
|
5
src/3rdparty/hwloc/include/hwloc/distances.h
vendored
5
src/3rdparty/hwloc/include/hwloc/distances.h
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2010-2019 Inria. All rights reserved.
|
||||
* Copyright © 2010-2020 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
|
@ -34,6 +34,7 @@ extern "C" {
|
|||
* It corresponds to the latency for accessing the memory of one node
|
||||
* from a core in another node.
|
||||
* The corresponding kind is ::HWLOC_DISTANCES_KIND_FROM_OS | ::HWLOC_DISTANCES_KIND_FROM_USER.
|
||||
* The name of this distances structure is "NUMALatency".
|
||||
*
|
||||
* The matrix may also contain bandwidths between random sets of objects,
|
||||
* possibly provided by the user, as specified in the \p kind attribute.
|
||||
|
@ -144,6 +145,8 @@ hwloc_distances_get_by_type(hwloc_topology_t topology, hwloc_obj_type_t type,
|
|||
/** \brief Retrieve a distance matrix with the given name.
|
||||
*
|
||||
* Usually only one distances structure may match a given name.
|
||||
*
|
||||
* The name of the most common structure is "NUMALatency".
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_distances_get_by_name(hwloc_topology_t topology, const char *name,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2013 inria. All rights reserved.
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009-2011 Université Bordeaux
|
||||
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#if !defined _GNU_SOURCE || !defined _SCHED_H || (!defined CPU_SETSIZE && !defined sched_priority)
|
||||
#if !defined _GNU_SOURCE || (!defined _SCHED_H && !defined _SCHED_H_) || (!defined CPU_SETSIZE && !defined sched_priority)
|
||||
#error Please make sure to include sched.h before including glibc-sched.h, and define _GNU_SOURCE before any inclusion of sched.h
|
||||
#endif
|
||||
|
||||
|
|
10
src/3rdparty/hwloc/include/hwloc/helper.h
vendored
10
src/3rdparty/hwloc/include/hwloc/helper.h
vendored
|
@ -872,8 +872,8 @@ hwloc_distrib(hwloc_topology_t topology,
|
|||
unsigned chunk, weight;
|
||||
hwloc_obj_t root = roots[flags & HWLOC_DISTRIB_FLAG_REVERSE ? n_roots-1-i : i];
|
||||
hwloc_cpuset_t cpuset = root->cpuset;
|
||||
if (root->type == HWLOC_OBJ_NUMANODE)
|
||||
/* NUMANodes have same cpuset as their parent, but we need normal objects below */
|
||||
while (!hwloc_obj_type_is_normal(root->type))
|
||||
/* If memory/io/misc, walk up to normal parent */
|
||||
root = root->parent;
|
||||
weight = (unsigned) hwloc_bitmap_weight(cpuset);
|
||||
if (!weight)
|
||||
|
@ -919,7 +919,7 @@ hwloc_distrib(hwloc_topology_t topology,
|
|||
|
||||
/** \brief Get complete CPU set
|
||||
*
|
||||
* \return the complete CPU set of logical processors of the system.
|
||||
* \return the complete CPU set of processors of the system.
|
||||
*
|
||||
* \note The returned cpuset is not newly allocated and should thus not be
|
||||
* changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy.
|
||||
|
@ -931,7 +931,7 @@ hwloc_topology_get_complete_cpuset(hwloc_topology_t topology) __hwloc_attribute_
|
|||
|
||||
/** \brief Get topology CPU set
|
||||
*
|
||||
* \return the CPU set of logical processors of the system for which hwloc
|
||||
* \return the CPU set of processors of the system for which hwloc
|
||||
* provides topology information. This is equivalent to the cpuset of the
|
||||
* system object.
|
||||
*
|
||||
|
@ -945,7 +945,7 @@ hwloc_topology_get_topology_cpuset(hwloc_topology_t topology) __hwloc_attribute_
|
|||
|
||||
/** \brief Get allowed CPU set
|
||||
*
|
||||
* \return the CPU set of allowed logical processors of the system.
|
||||
* \return the CPU set of allowed processors of the system.
|
||||
*
|
||||
* \note If the topology flag ::HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED was not set,
|
||||
* this is identical to hwloc_topology_get_topology_cpuset(), which means
|
||||
|
|
455
src/3rdparty/hwloc/include/hwloc/memattrs.h
vendored
Normal file
455
src/3rdparty/hwloc/include/hwloc/memattrs.h
vendored
Normal file
|
@ -0,0 +1,455 @@
|
|||
/*
|
||||
* Copyright © 2019-2020 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Memory node attributes.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_MEMATTR_H
|
||||
#define HWLOC_MEMATTR_H
|
||||
|
||||
#include "hwloc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#elif 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \defgroup hwlocality_memattrs Comparing memory node attributes for finding where to allocate on
|
||||
*
|
||||
* Platforms with heterogeneous memory require ways to decide whether
|
||||
* a buffer should be allocated on "fast" memory (such as HBM),
|
||||
* "normal" memory (DDR) or even "slow" but large-capacity memory
|
||||
* (non-volatile memory).
|
||||
* These memory nodes are called "Targets" while the CPU accessing them
|
||||
* is called the "Initiator". Access performance depends on their
|
||||
* locality (NUMA platforms) as well as the intrinsic performance
|
||||
* of the targets (heterogeneous platforms).
|
||||
*
|
||||
* The following attributes describe the performance of memory accesses
|
||||
* from an Initiator to a memory Target, for instance their latency
|
||||
* or bandwidth.
|
||||
* Initiators performing these memory accesses are usually some PUs or Cores
|
||||
* (described as a CPU set).
|
||||
* Hence a Core may choose where to allocate a memory buffer by comparing
|
||||
* the attributes of different target memory nodes nearby.
|
||||
*
|
||||
* There are also some attributes that are system-wide.
|
||||
* Their value does not depend on a specific initiator performing
|
||||
* an access.
|
||||
* The memory node Capacity is an example of such attribute without
|
||||
* initiator.
|
||||
*
|
||||
* One way to use this API is to start with a cpuset describing the Cores where
|
||||
* a program is bound. The best target NUMA node for allocating memory in this
|
||||
* program on these Cores may be obtained by passing this cpuset as an initiator
|
||||
* to hwloc_memattr_get_best_target() with the relevant memory attribute.
|
||||
* For instance, if the code is latency limited, use the Latency attribute.
|
||||
*
|
||||
* A more flexible approach consists in getting the list of local NUMA nodes
|
||||
* by passing this cpuset to hwloc_get_local_numanode_objs().
|
||||
* Attribute values for these nodes, if any, may then be obtained with
|
||||
* hwloc_memattr_get_value() and manually compared with the desired criteria.
|
||||
*
|
||||
* \note The API also supports specific objects as initiator,
|
||||
* but it is currently not used internally by hwloc.
|
||||
* Users may for instance use it to provide custom performance
|
||||
* values for host memory accesses performed by GPUs.
|
||||
*
|
||||
* \note The interface actually also accepts targets that are not NUMA nodes.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Memory node attributes. */
|
||||
enum hwloc_memattr_id_e {
|
||||
/** \brief "Capacity".
|
||||
* The capacity is returned in bytes
|
||||
* (local_memory attribute in objects).
|
||||
*
|
||||
* Best capacity nodes are nodes with <b>higher capacity</b>.
|
||||
*
|
||||
* No initiator is involved when looking at this attribute.
|
||||
* The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST.
|
||||
*/
|
||||
HWLOC_MEMATTR_ID_CAPACITY = 0,
|
||||
|
||||
/** \brief "Locality".
|
||||
* The locality is returned as the number of PUs in that locality
|
||||
* (e.g. the weight of its cpuset).
|
||||
*
|
||||
* Best locality nodes are nodes with <b>smaller locality</b>
|
||||
* (nodes that are local to very few PUs).
|
||||
* Poor locality nodes are nodes with larger locality
|
||||
* (nodes that are local to the entire machine).
|
||||
*
|
||||
* No initiator is involved when looking at this attribute.
|
||||
* The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST.
|
||||
*/
|
||||
HWLOC_MEMATTR_ID_LOCALITY = 1,
|
||||
|
||||
/** \brief "Bandwidth".
|
||||
* The bandwidth is returned in MiB/s, as seen from the given initiator location.
|
||||
* Best bandwidth nodes are nodes with <b>higher bandwidth</b>.
|
||||
* The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST
|
||||
* and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
|
||||
*/
|
||||
HWLOC_MEMATTR_ID_BANDWIDTH = 2,
|
||||
|
||||
/** \brief "Latency".
|
||||
* The latency is returned as nanoseconds, as seen from the given initiator location.
|
||||
* Best latency nodes are nodes with <b>smaller latency</b>.
|
||||
* The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_LOWER_FIRST
|
||||
* and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
|
||||
*/
|
||||
HWLOC_MEMATTR_ID_LATENCY = 3
|
||||
|
||||
/* TODO read vs write, persistence? */
|
||||
};
|
||||
|
||||
/** \brief A memory attribute identifier.
|
||||
* May be either one of ::hwloc_memattr_id_e or a new id returned by hwloc_memattr_register().
|
||||
*/
|
||||
typedef unsigned hwloc_memattr_id_t;
|
||||
|
||||
/** \brief Return the identifier of the memory attribute with the given name.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_get_by_name(hwloc_topology_t topology,
|
||||
const char *name,
|
||||
hwloc_memattr_id_t *id);
|
||||
|
||||
|
||||
/** \brief Type of location. */
|
||||
enum hwloc_location_type_e {
|
||||
/** \brief Location is given as a cpuset, in the location cpuset union field. \hideinitializer */
|
||||
HWLOC_LOCATION_TYPE_CPUSET = 1,
|
||||
/** \brief Location is given as an object, in the location object union field. \hideinitializer */
|
||||
HWLOC_LOCATION_TYPE_OBJECT = 0
|
||||
};
|
||||
|
||||
/** \brief Where to measure attributes from. */
|
||||
struct hwloc_location {
|
||||
/** \brief Type of location. */
|
||||
enum hwloc_location_type_e type;
|
||||
/** \brief Actual location. */
|
||||
union hwloc_location_u {
|
||||
/** \brief Location as a cpuset, when the location type is ::HWLOC_LOCATION_TYPE_CPUSET. */
|
||||
hwloc_cpuset_t cpuset;
|
||||
/** \brief Location as an object, when the location type is ::HWLOC_LOCATION_TYPE_OBJECT. */
|
||||
hwloc_obj_t object;
|
||||
} location;
|
||||
};
|
||||
|
||||
|
||||
/** \brief Flags for selecting target NUMA nodes. */
|
||||
enum hwloc_local_numanode_flag_e {
|
||||
/** \brief Select NUMA nodes whose locality is larger than the given cpuset.
|
||||
* For instance, if a single PU (or its cpuset) is given in \p initiator,
|
||||
* select all nodes close to the package that contains this PU.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY = (1UL<<0),
|
||||
|
||||
/** \brief Select NUMA nodes whose locality is smaller than the given cpuset.
|
||||
* For instance, if a package (or its cpuset) is given in \p initiator,
|
||||
* also select nodes that are attached to only a half of that package.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY = (1UL<<1),
|
||||
|
||||
/** \brief Select all NUMA nodes in the topology.
|
||||
* The initiator \p initiator is ignored.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_LOCAL_NUMANODE_FLAG_ALL = (1UL<<2)
|
||||
};
|
||||
|
||||
/** \brief Return an array of local NUMA nodes.
|
||||
*
|
||||
* By default only select the NUMA nodes whose locality is exactly
|
||||
* the given \p location. More nodes may be selected if additional flags
|
||||
* are given as a OR'ed set of ::hwloc_local_numanode_flag_e.
|
||||
*
|
||||
* If \p location is given as an explicit object, its CPU set is used
|
||||
* to find NUMA nodes with the corresponding locality.
|
||||
* If the object does not have a CPU set (e.g. I/O object), the CPU
|
||||
* parent (where the I/O object is attached) is used.
|
||||
*
|
||||
* On input, \p nr points to the number of nodes that may be stored
|
||||
* in the \p nodes array.
|
||||
* On output, \p nr will be changed to the number of stored nodes,
|
||||
* or the number of nodes that would have been stored if there were
|
||||
* enough room.
|
||||
*
|
||||
* \note Some of these NUMA nodes may not have any memory attribute
|
||||
* values and hence not be reported as actual targets in other functions.
|
||||
*
|
||||
* \note The number of NUMA nodes in the topology (obtained by
|
||||
* hwloc_bitmap_weight() on the root object nodeset) may be used
|
||||
* to allocate the \p nodes array.
|
||||
*
|
||||
* \note When an object CPU set is given as locality, for instance a Package,
|
||||
* and when flags contain both ::HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY
|
||||
* and ::HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY,
|
||||
* the returned array corresponds to the nodeset of that object.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_get_local_numanode_objs(hwloc_topology_t topology,
|
||||
struct hwloc_location *location,
|
||||
unsigned *nr,
|
||||
hwloc_obj_t *nodes,
|
||||
unsigned long flags);
|
||||
|
||||
|
||||
|
||||
/** \brief Return an attribute value for a specific target NUMA node.
|
||||
*
|
||||
* If the attribute does not relate to a specific initiator
|
||||
* (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
|
||||
* location \p initiator is ignored and may be \c NULL.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
|
||||
* when refering to accesses performed by CPU cores.
|
||||
* ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
|
||||
* but users may for instance use it to provide custom information about
|
||||
* host memory accesses performed by GPUs.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_get_value(hwloc_topology_t topology,
|
||||
hwloc_memattr_id_t attribute,
|
||||
hwloc_obj_t target_node,
|
||||
struct hwloc_location *initiator,
|
||||
unsigned long flags,
|
||||
hwloc_uint64_t *value);
|
||||
|
||||
/** \brief Return the best target NUMA node for the given attribute and initiator.
|
||||
*
|
||||
* If the attribute does not relate to a specific initiator
|
||||
* (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
|
||||
* location \p initiator is ignored and may be \c NULL.
|
||||
*
|
||||
* If \p value is non \c NULL, the corresponding value is returned there.
|
||||
*
|
||||
* If multiple targets have the same attribute values, only one is
|
||||
* returned (and there is no way to clarify how that one is chosen).
|
||||
* Applications that want to detect targets with identical/similar
|
||||
* values, or that want to look at values for multiple attributes,
|
||||
* should rather get all values using hwloc_memattr_get_value()
|
||||
* and manually select the target they consider the best.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* If there are no matching targets, \c -1 is returned with \p errno set to \c ENOENT;
|
||||
*
|
||||
* \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
|
||||
* when refering to accesses performed by CPU cores.
|
||||
* ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
|
||||
* but users may for instance use it to provide custom information about
|
||||
* host memory accesses performed by GPUs.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_get_best_target(hwloc_topology_t topology,
|
||||
hwloc_memattr_id_t attribute,
|
||||
struct hwloc_location *initiator,
|
||||
unsigned long flags,
|
||||
hwloc_obj_t *best_target, hwloc_uint64_t *value);
|
||||
|
||||
/** \brief Return the best initiator for the given attribute and target NUMA node.
|
||||
*
|
||||
* If the attribute does not relate to a specific initiator
|
||||
* (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
|
||||
* \c -1 is returned and \p errno is set to \c EINVAL.
|
||||
*
|
||||
* If \p value is non \c NULL, the corresponding value is returned there.
|
||||
*
|
||||
* If multiple initiators have the same attribute values, only one is
|
||||
* returned (and there is no way to clarify how that one is chosen).
|
||||
* Applications that want to detect initiators with identical/similar
|
||||
* values, or that want to look at values for multiple attributes,
|
||||
* should rather get all values using hwloc_memattr_get_value()
|
||||
* and manually select the initiator they consider the best.
|
||||
*
|
||||
* The returned initiator should not be modified or freed,
|
||||
* it belongs to the topology.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* If there are no matching initiators, \c -1 is returned with \p errno set to \c ENOENT;
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_get_best_initiator(hwloc_topology_t topology,
|
||||
hwloc_memattr_id_t attribute,
|
||||
hwloc_obj_t target,
|
||||
unsigned long flags,
|
||||
struct hwloc_location *best_initiator, hwloc_uint64_t *value);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/** \defgroup hwlocality_memattrs_manage Managing memory attributes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Return the name of a memory attribute.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_get_name(hwloc_topology_t topology,
|
||||
hwloc_memattr_id_t attribute,
|
||||
const char **name);
|
||||
|
||||
/** \brief Return the flags of the given attribute.
|
||||
*
|
||||
* Flags are a OR'ed set of ::hwloc_memattr_flag_e.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_get_flags(hwloc_topology_t topology,
|
||||
hwloc_memattr_id_t attribute,
|
||||
unsigned long *flags);
|
||||
|
||||
/** \brief Memory attribute flags.
|
||||
* Given to hwloc_memattr_register() and returned by hwloc_memattr_get_flags().
|
||||
*/
|
||||
enum hwloc_memattr_flag_e {
|
||||
/** \brief The best nodes for this memory attribute are those with the higher values.
|
||||
* For instance Bandwidth.
|
||||
*/
|
||||
HWLOC_MEMATTR_FLAG_HIGHER_FIRST = (1UL<<0),
|
||||
/** \brief The best nodes for this memory attribute are those with the lower values.
|
||||
* For instance Latency.
|
||||
*/
|
||||
HWLOC_MEMATTR_FLAG_LOWER_FIRST = (1UL<<1),
|
||||
/** \brief The value returned for this memory attribute depends on the given initiator.
|
||||
* For instance Bandwidth and Latency, but not Capacity.
|
||||
*/
|
||||
HWLOC_MEMATTR_FLAG_NEED_INITIATOR = (1UL<<2)
|
||||
};
|
||||
|
||||
/** \brief Register a new memory attribute.
|
||||
*
|
||||
* Add a specific memory attribute that is not defined in ::hwloc_memattr_id_e.
|
||||
* Flags are a OR'ed set of ::hwloc_memattr_flag_e. It must contain at least
|
||||
* one of ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST or ::HWLOC_MEMATTR_FLAG_LOWER_FIRST.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_register(hwloc_topology_t topology,
|
||||
const char *name,
|
||||
unsigned long flags,
|
||||
hwloc_memattr_id_t *id);
|
||||
|
||||
/** \brief Set an attribute value for a specific target NUMA node.
|
||||
*
|
||||
* If the attribute does not relate to a specific initiator
|
||||
* (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
|
||||
* location \p initiator is ignored and may be \c NULL.
|
||||
*
|
||||
* The initiator will be copied into the topology,
|
||||
* the caller should free anything allocated to store the initiator,
|
||||
* for instance the cpuset.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
|
||||
* when refering to accesses performed by CPU cores.
|
||||
* ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
|
||||
* but users may for instance use it to provide custom information about
|
||||
* host memory accesses performed by GPUs.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_set_value(hwloc_topology_t topology,
|
||||
hwloc_memattr_id_t attribute,
|
||||
hwloc_obj_t target_node,
|
||||
struct hwloc_location *initiator,
|
||||
unsigned long flags,
|
||||
hwloc_uint64_t value);
|
||||
|
||||
/** \brief Return the target NUMA nodes that have some values for a given attribute.
|
||||
*
|
||||
* Return targets for the given attribute in the \p targets array
|
||||
* (for the given initiator if any).
|
||||
* If \p values is not \c NULL, the corresponding attribute values
|
||||
* are stored in the array it points to.
|
||||
*
|
||||
* On input, \p nr points to the number of targets that may be stored
|
||||
* in the array \p targets (and \p values).
|
||||
* On output, \p nr points to the number of targets (and values) that
|
||||
* were actually found, even if some of them couldn't be stored in the array.
|
||||
* Targets that couldn't be stored are ignored, but the function still
|
||||
* returns success (\c 0). The caller may find out by comparing the value pointed
|
||||
* by \p nr before and after the function call.
|
||||
*
|
||||
* The returned targets should not be modified or freed,
|
||||
* they belong to the topology.
|
||||
*
|
||||
* Argument \p initiator is ignored if the attribute does not relate to a specific
|
||||
* initiator (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR).
|
||||
* Otherwise \p initiator may be non \c NULL to report only targets
|
||||
* that have a value for that initiator.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* \note This function is meant for tools and debugging (listing internal information)
|
||||
* rather than for application queries. Applications should rather select useful
|
||||
* NUMA nodes with hwloc_get_local_numanode_objs() and then look at their attribute
|
||||
* values.
|
||||
*
|
||||
* \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
|
||||
* when refering to accesses performed by CPU cores.
|
||||
* ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
|
||||
* but users may for instance use it to provide custom information about
|
||||
* host memory accesses performed by GPUs.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_get_targets(hwloc_topology_t topology,
|
||||
hwloc_memattr_id_t attribute,
|
||||
struct hwloc_location *initiator,
|
||||
unsigned long flags,
|
||||
unsigned *nrp, hwloc_obj_t *targets, hwloc_uint64_t *values);
|
||||
|
||||
/** \brief Return the initiators that have values for a given attribute for a specific target NUMA node.
|
||||
*
|
||||
* Return initiators for the given attribute and target node in the
|
||||
* \p initiators array.
|
||||
* If \p values is not \c NULL, the corresponding attribute values
|
||||
* are stored in the array it points to.
|
||||
*
|
||||
* On input, \p nr points to the number of initiators that may be stored
|
||||
* in the array \p initiators (and \p values).
|
||||
* On output, \p nr points to the number of initiators (and values) that
|
||||
* were actually found, even if some of them couldn't be stored in the array.
|
||||
* Initiators that couldn't be stored are ignored, but the function still
|
||||
* returns success (\c 0). The caller may find out by comparing the value pointed
|
||||
* by \p nr before and after the function call.
|
||||
*
|
||||
* The returned initiators should not be modified or freed,
|
||||
* they belong to the topology.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* If the attribute does not relate to a specific initiator
|
||||
* (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
|
||||
* no initiator is returned.
|
||||
*
|
||||
* \note This function is meant for tools and debugging (listing internal information)
|
||||
* rather than for application queries. Applications should rather select useful
|
||||
* NUMA nodes with hwloc_get_local_numanode_objs() and then look at their attribute
|
||||
* values for some relevant initiators.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_get_initiators(hwloc_topology_t topology,
|
||||
hwloc_memattr_id_t attribute,
|
||||
hwloc_obj_t target_node,
|
||||
unsigned long flags,
|
||||
unsigned *nr, struct hwloc_location *initiators, hwloc_uint64_t *values);
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_MEMATTR_H */
|
4
src/3rdparty/hwloc/include/hwloc/nvml.h
vendored
4
src/3rdparty/hwloc/include/hwloc/nvml.h
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2012-2016 Inria. All rights reserved.
|
||||
* Copyright © 2012-2020 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
|
@ -36,7 +36,7 @@ extern "C" {
|
|||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Get the CPU set of logical processors that are physically
|
||||
/** \brief Get the CPU set of processors that are physically
|
||||
* close to NVML device \p device.
|
||||
*
|
||||
* Return the CPU set describing the locality of the NVML device \p device.
|
||||
|
|
4
src/3rdparty/hwloc/include/hwloc/opencl.h
vendored
4
src/3rdparty/hwloc/include/hwloc/opencl.h
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2012-2019 Inria. All rights reserved.
|
||||
* Copyright © 2012-2020 Inria. All rights reserved.
|
||||
* Copyright © 2013, 2018 Université Bordeaux. All right reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
@ -109,7 +109,7 @@ hwloc_opencl_get_device_pci_busid(cl_device_id device,
|
|||
return -1;
|
||||
}
|
||||
|
||||
/** \brief Get the CPU set of logical processors that are physically
|
||||
/** \brief Get the CPU set of processors that are physically
|
||||
* close to OpenCL device \p device.
|
||||
*
|
||||
* Return the CPU set describing the locality of the OpenCL device \p device.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2016 Inria. All rights reserved.
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009-2010 Université Bordeaux
|
||||
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
|
@ -41,7 +41,7 @@ extern "C" {
|
|||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Get the CPU set of logical processors that are physically
|
||||
/** \brief Get the CPU set of processors that are physically
|
||||
* close to device \p ibdev.
|
||||
*
|
||||
* Return the CPU set describing the locality of the OpenFabrics
|
||||
|
|
30
src/3rdparty/hwloc/include/hwloc/plugins.h
vendored
30
src/3rdparty/hwloc/include/hwloc/plugins.h
vendored
|
@ -313,7 +313,13 @@ struct hwloc_component {
|
|||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Check whether insertion errors are hidden */
|
||||
HWLOC_DECLSPEC int hwloc_hide_errors(void);
|
||||
|
||||
/** \brief Add an object to the topology.
|
||||
*
|
||||
* Insert new object \p obj in the topology starting under existing object \p root
|
||||
* (if \c NULL, the topology root object is used).
|
||||
*
|
||||
* It is sorted along the tree of other objects according to the inclusion of
|
||||
* cpusets, to eventually be added as a child of the smallest object including
|
||||
|
@ -327,32 +333,20 @@ struct hwloc_component {
|
|||
*
|
||||
* This shall only be called before levels are built.
|
||||
*
|
||||
* In case of error, hwloc_report_os_error() is called.
|
||||
*
|
||||
* The caller should check whether the object type is filtered-out before calling this function.
|
||||
*
|
||||
* The topology cpuset/nodesets will be enlarged to include the object sets.
|
||||
*
|
||||
* \p reason is a unique string identifying where and why this insertion call was performed
|
||||
* (it will be displayed in case of internal insertion error).
|
||||
*
|
||||
* Returns the object on success.
|
||||
* Returns NULL and frees obj on error.
|
||||
* Returns another object and frees obj if it was merged with an identical pre-existing object.
|
||||
*/
|
||||
HWLOC_DECLSPEC struct hwloc_obj *hwloc_insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t obj);
|
||||
|
||||
/** \brief Type of error callbacks during object insertion */
|
||||
typedef void (*hwloc_report_error_t)(const char * msg, int line);
|
||||
/** \brief Report an insertion error from a backend */
|
||||
HWLOC_DECLSPEC void hwloc_report_os_error(const char * msg, int line);
|
||||
/** \brief Check whether insertion errors are hidden */
|
||||
HWLOC_DECLSPEC int hwloc_hide_errors(void);
|
||||
|
||||
/** \brief Add an object to the topology and specify which error callback to use.
|
||||
*
|
||||
* This function is similar to hwloc_insert_object_by_cpuset() but it allows specifying
|
||||
* where to start insertion from (if \p root is NULL, the topology root object is used),
|
||||
* and specifying the error callback.
|
||||
*/
|
||||
HWLOC_DECLSPEC struct hwloc_obj *hwloc__insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t root, hwloc_obj_t obj, hwloc_report_error_t report_error);
|
||||
HWLOC_DECLSPEC hwloc_obj_t
|
||||
hwloc__insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t root,
|
||||
hwloc_obj_t obj, const char *reason);
|
||||
|
||||
/** \brief Insert an object somewhere in the topology.
|
||||
*
|
||||
|
|
83
src/3rdparty/hwloc/include/hwloc/rename.h
vendored
83
src/3rdparty/hwloc/include/hwloc/rename.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright © 2010-2019 Inria. All rights reserved.
|
||||
* Copyright © 2010-2020 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
|
@ -119,6 +119,7 @@ extern "C" {
|
|||
#define HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED HWLOC_NAME_CAPS(TOPOLOGY_FLAG_WITH_DISALLOWED)
|
||||
#define HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM HWLOC_NAME_CAPS(TOPOLOGY_FLAG_IS_THISSYSTEM)
|
||||
#define HWLOC_TOPOLOGY_FLAG_THISSYSTEM_ALLOWED_RESOURCES HWLOC_NAME_CAPS(TOPOLOGY_FLAG_THISSYSTEM_ALLOWED_RESOURCES)
|
||||
#define HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT HWLOC_NAME_CAPS(TOPOLOGY_FLAG_IMPORT_SUPPORT)
|
||||
|
||||
#define hwloc_topology_set_pid HWLOC_NAME(topology_set_pid)
|
||||
#define hwloc_topology_set_synthetic HWLOC_NAME(topology_set_synthetic)
|
||||
|
@ -134,6 +135,7 @@ extern "C" {
|
|||
#define hwloc_topology_discovery_support HWLOC_NAME(topology_discovery_support)
|
||||
#define hwloc_topology_cpubind_support HWLOC_NAME(topology_cpubind_support)
|
||||
#define hwloc_topology_membind_support HWLOC_NAME(topology_membind_support)
|
||||
#define hwloc_topology_misc_support HWLOC_NAME(topology_misc_support)
|
||||
#define hwloc_topology_support HWLOC_NAME(topology_support)
|
||||
#define hwloc_topology_get_support HWLOC_NAME(topology_get_support)
|
||||
|
||||
|
@ -170,6 +172,7 @@ extern "C" {
|
|||
#define hwloc_topology_alloc_group_object HWLOC_NAME(topology_alloc_group_object)
|
||||
#define hwloc_topology_insert_group_object HWLOC_NAME(topology_insert_group_object)
|
||||
#define hwloc_obj_add_other_obj_sets HWLOC_NAME(obj_add_other_obj_sets)
|
||||
#define hwloc_topology_refresh HWLOC_NAME(topology_refresh)
|
||||
|
||||
#define hwloc_topology_get_depth HWLOC_NAME(topology_get_depth)
|
||||
#define hwloc_get_type_depth HWLOC_NAME(get_type_depth)
|
||||
|
@ -367,6 +370,51 @@ extern "C" {
|
|||
#define hwloc_cpuset_to_nodeset HWLOC_NAME(cpuset_to_nodeset)
|
||||
#define hwloc_cpuset_from_nodeset HWLOC_NAME(cpuset_from_nodeset)
|
||||
|
||||
/* memattrs.h */
|
||||
|
||||
#define hwloc_memattr_id_e HWLOC_NAME(memattr_id_e)
|
||||
#define HWLOC_MEMATTR_ID_CAPACITY HWLOC_NAME_CAPS(MEMATTR_ID_CAPACITY)
|
||||
#define HWLOC_MEMATTR_ID_LOCALITY HWLOC_NAME_CAPS(MEMATTR_ID_LOCALITY)
|
||||
#define HWLOC_MEMATTR_ID_BANDWIDTH HWLOC_NAME_CAPS(MEMATTR_ID_BANDWIDTH)
|
||||
#define HWLOC_MEMATTR_ID_LATENCY HWLOC_NAME_CAPS(MEMATTR_ID_LATENCY)
|
||||
|
||||
#define hwloc_memattr_id_t HWLOC_NAME(memattr_id_t)
|
||||
#define hwloc_memattr_get_by_name HWLOC_NAME(memattr_get_by_name)
|
||||
|
||||
#define hwloc_location HWLOC_NAME(location)
|
||||
#define hwloc_location_type_e HWLOC_NAME(location_type_e)
|
||||
#define HWLOC_LOCATION_TYPE_OBJECT HWLOC_NAME_CAPS(LOCATION_TYPE_OBJECT)
|
||||
#define HWLOC_LOCATION_TYPE_CPUSET HWLOC_NAME_CAPS(LOCATION_TYPE_CPUSET)
|
||||
#define hwloc_location_u HWLOC_NAME(location_u)
|
||||
|
||||
#define hwloc_memattr_get_value HWLOC_NAME(memattr_get_value)
|
||||
#define hwloc_memattr_get_best_target HWLOC_NAME(memattr_get_best_target)
|
||||
#define hwloc_memattr_get_best_initiator HWLOC_NAME(memattr_get_best_initiator)
|
||||
|
||||
#define hwloc_local_numanode_flag_e HWLOC_NAME(local_numanode_flag_e)
|
||||
#define HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY HWLOC_NAME_CAPS(LOCAL_NUMANODE_FLAG_LARGER_LOCALITY)
|
||||
#define HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY HWLOC_NAME_CAPS(LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY)
|
||||
#define HWLOC_LOCAL_NUMANODE_FLAG_ALL HWLOC_NAME_CAPS(LOCAL_NUMANODE_FLAG_ALL)
|
||||
#define hwloc_get_local_numanode_objs HWLOC_NAME(get_local_numanode_objs)
|
||||
|
||||
#define hwloc_memattr_get_name HWLOC_NAME(memattr_get_name)
|
||||
#define hwloc_memattr_get_flags HWLOC_NAME(memattr_get_flags)
|
||||
#define hwloc_memattr_flag_e HWLOC_NAME(memattr_flag_e)
|
||||
#define HWLOC_MEMATTR_FLAG_HIGHER_FIRST HWLOC_NAME_CAPS(MEMATTR_FLAG_HIGHER_FIRST)
|
||||
#define HWLOC_MEMATTR_FLAG_LOWER_FIRST HWLOC_NAME_CAPS(MEMATTR_FLAG_LOWER_FIRST)
|
||||
#define HWLOC_MEMATTR_FLAG_NEED_INITIATOR HWLOC_NAME_CAPS(MEMATTR_FLAG_NEED_INITIATOR)
|
||||
#define hwloc_memattr_register HWLOC_NAME(memattr_register)
|
||||
#define hwloc_memattr_set_value HWLOC_NAME(memattr_set_value)
|
||||
#define hwloc_memattr_get_targets HWLOC_NAME(memattr_get_targets)
|
||||
#define hwloc_memattr_get_initiators HWLOC_NAME(memattr_get_initiators)
|
||||
|
||||
/* cpukinds.h */
|
||||
|
||||
#define hwloc_cpukinds_get_nr HWLOC_NAME(cpukinds_get_nr)
|
||||
#define hwloc_cpukinds_get_by_cpuset HWLOC_NAME(cpukinds_get_by_cpuset)
|
||||
#define hwloc_cpukinds_get_info HWLOC_NAME(cpukinds_get_info)
|
||||
#define hwloc_cpukinds_register HWLOC_NAME(cpukinds_register)
|
||||
|
||||
/* export.h */
|
||||
|
||||
#define hwloc_topology_export_xml_flags_e HWLOC_NAME(topology_export_xml_flags_e)
|
||||
|
@ -510,6 +558,12 @@ extern "C" {
|
|||
#define hwloc_nvml_get_device_osdev HWLOC_NAME(nvml_get_device_osdev)
|
||||
#define hwloc_nvml_get_device_osdev_by_index HWLOC_NAME(nvml_get_device_osdev_by_index)
|
||||
|
||||
/* rsmi.h */
|
||||
|
||||
#define hwloc_rsmi_get_device_cpuset HWLOC_NAME(rsmi_get_device_cpuset)
|
||||
#define hwloc_rsmi_get_device_osdev HWLOC_NAME(rsmi_get_device_osdev)
|
||||
#define hwloc_rsmi_get_device_osdev_by_index HWLOC_NAME(rsmi_get_device_osdev_by_index)
|
||||
|
||||
/* gl.h */
|
||||
|
||||
#define hwloc_gl_get_display_osdev_by_port_device HWLOC_NAME(gl_get_display_osdev_by_port_device)
|
||||
|
@ -547,9 +601,6 @@ extern "C" {
|
|||
|
||||
#define hwloc_plugin_check_namespace HWLOC_NAME(plugin_check_namespace)
|
||||
|
||||
#define hwloc_insert_object_by_cpuset HWLOC_NAME(insert_object_by_cpuset)
|
||||
#define hwloc_report_error_t HWLOC_NAME(report_error_t)
|
||||
#define hwloc_report_os_error HWLOC_NAME(report_os_error)
|
||||
#define hwloc_hide_errors HWLOC_NAME(hide_errors)
|
||||
#define hwloc__insert_object_by_cpuset HWLOC_NAME(_insert_object_by_cpuset)
|
||||
#define hwloc_insert_object_by_parent HWLOC_NAME(insert_object_by_parent)
|
||||
|
@ -683,6 +734,7 @@ extern "C" {
|
|||
#define hwloc_cuda_component HWLOC_NAME(cuda_component)
|
||||
#define hwloc_gl_component HWLOC_NAME(gl_component)
|
||||
#define hwloc_nvml_component HWLOC_NAME(nvml_component)
|
||||
#define hwloc_rsmi_component HWLOC_NAME(rsmi_component)
|
||||
#define hwloc_opencl_component HWLOC_NAME(opencl_component)
|
||||
#define hwloc_pci_component HWLOC_NAME(pci_component)
|
||||
|
||||
|
@ -691,6 +743,8 @@ extern "C" {
|
|||
|
||||
/* private/private.h */
|
||||
|
||||
#define hwloc_internal_location_s HWLOC_NAME(internal_location_s)
|
||||
|
||||
#define hwloc_special_level_s HWLOC_NAME(special_level_s)
|
||||
|
||||
#define hwloc_pci_forced_locality_s HWLOC_NAME(pci_forced_locality_s)
|
||||
|
@ -713,6 +767,8 @@ extern "C" {
|
|||
|
||||
#define hwloc__attach_memory_object HWLOC_NAME(insert_memory_object)
|
||||
|
||||
#define hwloc_get_obj_by_type_and_gp_index HWLOC_NAME(get_obj_by_type_and_gp_index)
|
||||
|
||||
#define hwloc_pci_discovery_init HWLOC_NAME(pci_discovery_init)
|
||||
#define hwloc_pci_discovery_prepare HWLOC_NAME(pci_discovery_prepare)
|
||||
#define hwloc_pci_discovery_exit HWLOC_NAME(pci_discovery_exit)
|
||||
|
@ -723,6 +779,7 @@ extern "C" {
|
|||
#define hwloc__add_info_nodup HWLOC_NAME(_add_info_nodup)
|
||||
#define hwloc__move_infos HWLOC_NAME(_move_infos)
|
||||
#define hwloc__free_infos HWLOC_NAME(_free_infos)
|
||||
#define hwloc__tma_dup_infos HWLOC_NAME(_tma_dup_infos)
|
||||
|
||||
#define hwloc_binding_hooks HWLOC_NAME(binding_hooks)
|
||||
#define hwloc_set_native_binding_hooks HWLOC_NAME(set_native_binding_hooks)
|
||||
|
@ -764,6 +821,24 @@ extern "C" {
|
|||
#define hwloc_internal_distances_add_by_index HWLOC_NAME(internal_distances_add_by_index)
|
||||
#define hwloc_internal_distances_invalidate_cached_objs HWLOC_NAME(hwloc_internal_distances_invalidate_cached_objs)
|
||||
|
||||
#define hwloc_internal_memattr_s HWLOC_NAME(internal_memattr_s)
|
||||
#define hwloc_internal_memattr_target_s HWLOC_NAME(internal_memattr_target_s)
|
||||
#define hwloc_internal_memattr_initiator_s HWLOC_NAME(internal_memattr_initiator_s)
|
||||
#define hwloc_internal_memattrs_init HWLOC_NAME(internal_memattrs_init)
|
||||
#define hwloc_internal_memattrs_prepare HWLOC_NAME(internal_memattrs_prepare)
|
||||
#define hwloc_internal_memattrs_dup HWLOC_NAME(internal_memattrs_dup)
|
||||
#define hwloc_internal_memattrs_destroy HWLOC_NAME(internal_memattrs_destroy)
|
||||
#define hwloc_internal_memattrs_need_refresh HWLOC_NAME(internal_memattrs_need_refresh)
|
||||
#define hwloc_internal_memattrs_refresh HWLOC_NAME(internal_memattrs_refresh)
|
||||
|
||||
#define hwloc_internal_cpukind_s HWLOC_NAME(internal_cpukind_s)
|
||||
#define hwloc_internal_cpukinds_init HWLOC_NAME(internal_cpukinds_init)
|
||||
#define hwloc_internal_cpukinds_destroy HWLOC_NAME(internal_cpukinds_destroy)
|
||||
#define hwloc_internal_cpukinds_dup HWLOC_NAME(internal_cpukinds_dup)
|
||||
#define hwloc_internal_cpukinds_register HWLOC_NAME(internal_cpukinds_register)
|
||||
#define hwloc_internal_cpukinds_rank HWLOC_NAME(internal_cpukinds_rank)
|
||||
#define hwloc_internal_cpukinds_restrict HWLOC_NAME(internal_cpukinds_restrict)
|
||||
|
||||
#define hwloc_encode_to_base64 HWLOC_NAME(encode_to_base64)
|
||||
#define hwloc_decode_from_base64 HWLOC_NAME(decode_from_base64)
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* Copyright © 2009, 2011, 2012 CNRS. All rights reserved.
|
||||
* Copyright © 2009-2018 Inria. All rights reserved.
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009, 2011, 2012, 2015 Université Bordeaux. All rights reserved.
|
||||
* Copyright © 2009 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright © 2009-2020 Cisco Systems, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
|
@ -575,7 +575,7 @@
|
|||
#define PACKAGE "hwloc"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "http://www.open-mpi.org/projects/hwloc/"
|
||||
#define PACKAGE_BUGREPORT "https://www.open-mpi.org/projects/hwloc/"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "hwloc"
|
||||
|
@ -668,5 +668,9 @@
|
|||
/* Define this to the thread ID type */
|
||||
#define hwloc_thread_t HANDLE
|
||||
|
||||
/* Define to 1 if you have the declaration of `GetModuleFileName', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_GETMODULEFILENAME 1
|
||||
|
||||
|
||||
#endif /* HWLOC_CONFIGURE_H */
|
||||
|
|
20
src/3rdparty/hwloc/include/private/debug.h
vendored
20
src/3rdparty/hwloc/include/private/debug.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2017 Inria. All rights reserved.
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009, 2011 Université Bordeaux
|
||||
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
|
@ -19,6 +19,10 @@
|
|||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID
|
||||
extern void JNIDebug(char *text);
|
||||
#endif
|
||||
|
||||
/* Compile-time assertion */
|
||||
#define HWLOC_BUILD_ASSERT(condition) ((void)sizeof(char[1 - 2*!(condition)]))
|
||||
|
||||
|
@ -44,9 +48,17 @@ static __hwloc_inline void hwloc_debug(const char *s __hwloc_attribute_unused, .
|
|||
{
|
||||
#ifdef HWLOC_DEBUG
|
||||
if (hwloc_debug_enabled()) {
|
||||
#ifdef ANDROID
|
||||
char buffer[256];
|
||||
#endif
|
||||
va_list ap;
|
||||
va_start(ap, s);
|
||||
#ifdef ANDROID
|
||||
vsprintf(buffer, s, ap);
|
||||
JNIDebug(buffer);
|
||||
#else
|
||||
vfprintf(stderr, s, ap);
|
||||
#endif
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
|
@ -57,21 +69,21 @@ static __hwloc_inline void hwloc_debug(const char *s __hwloc_attribute_unused, .
|
|||
if (hwloc_debug_enabled()) { \
|
||||
char *s; \
|
||||
hwloc_bitmap_asprintf(&s, bitmap); \
|
||||
fprintf(stderr, fmt, s); \
|
||||
hwloc_debug(fmt, s); \
|
||||
free(s); \
|
||||
} } while (0)
|
||||
#define hwloc_debug_1arg_bitmap(fmt, arg1, bitmap) do { \
|
||||
if (hwloc_debug_enabled()) { \
|
||||
char *s; \
|
||||
hwloc_bitmap_asprintf(&s, bitmap); \
|
||||
fprintf(stderr, fmt, arg1, s); \
|
||||
hwloc_debug(fmt, arg1, s); \
|
||||
free(s); \
|
||||
} } while (0)
|
||||
#define hwloc_debug_2args_bitmap(fmt, arg1, arg2, bitmap) do { \
|
||||
if (hwloc_debug_enabled()) { \
|
||||
char *s; \
|
||||
hwloc_bitmap_asprintf(&s, bitmap); \
|
||||
fprintf(stderr, fmt, arg1, arg2, s); \
|
||||
hwloc_debug(fmt, arg1, arg2, s); \
|
||||
free(s); \
|
||||
} } while (0)
|
||||
#else
|
||||
|
|
|
@ -30,6 +30,7 @@ HWLOC_DECLSPEC extern const struct hwloc_component hwloc_x86_component;
|
|||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_cuda_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_gl_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_nvml_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_rsmi_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_opencl_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_pci_component;
|
||||
|
||||
|
|
82
src/3rdparty/hwloc/include/private/private.h
vendored
82
src/3rdparty/hwloc/include/private/private.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2019 Inria. All rights reserved.
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009-2012, 2020 Université Bordeaux
|
||||
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
*
|
||||
|
@ -40,7 +40,19 @@
|
|||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#define HWLOC_TOPOLOGY_ABI 0x20100 /* version of the layout of struct topology */
|
||||
#define HWLOC_TOPOLOGY_ABI 0x20400 /* version of the layout of struct topology */
|
||||
|
||||
struct hwloc_internal_location_s {
|
||||
enum hwloc_location_type_e type;
|
||||
union {
|
||||
struct {
|
||||
hwloc_obj_t obj; /* cached between refreshes */
|
||||
uint64_t gp_index;
|
||||
hwloc_obj_type_t type;
|
||||
} object; /* if type == HWLOC_LOCATION_TYPE_OBJECT */
|
||||
hwloc_cpuset_t cpuset; /* if type == HWLOC_LOCATION_TYPE_CPUSET */
|
||||
} location;
|
||||
};
|
||||
|
||||
/*****************************************************
|
||||
* WARNING:
|
||||
|
@ -163,6 +175,50 @@ struct hwloc_topology {
|
|||
} *first_dist, *last_dist;
|
||||
unsigned next_dist_id;
|
||||
|
||||
/* memory attributes */
|
||||
unsigned nr_memattrs;
|
||||
struct hwloc_internal_memattr_s {
|
||||
/* memattr info */
|
||||
char *name; /* TODO unit is implicit, in the documentation of standard attributes, or in the name? */
|
||||
unsigned long flags;
|
||||
#define HWLOC_IMATTR_FLAG_STATIC_NAME (1U<<0) /* no need to free name */
|
||||
#define HWLOC_IMATTR_FLAG_CACHE_VALID (1U<<1) /* target and initiator are valid */
|
||||
#define HWLOC_IMATTR_FLAG_CONVENIENCE (1U<<2) /* convenience attribute reporting values from non-memattr attributes (R/O and no actual targets stored) */
|
||||
unsigned iflags;
|
||||
|
||||
/* array of values */
|
||||
unsigned nr_targets;
|
||||
struct hwloc_internal_memattr_target_s {
|
||||
/* target object */
|
||||
hwloc_obj_t obj; /* cached between refreshes */
|
||||
hwloc_obj_type_t type;
|
||||
unsigned os_index; /* only used temporarily during discovery when there's no obj/gp_index yet */
|
||||
hwloc_uint64_t gp_index;
|
||||
|
||||
/* value if there are no initiator for this attr */
|
||||
hwloc_uint64_t noinitiator_value;
|
||||
/* initiators otherwise */
|
||||
unsigned nr_initiators;
|
||||
struct hwloc_internal_memattr_initiator_s {
|
||||
struct hwloc_internal_location_s initiator;
|
||||
hwloc_uint64_t value;
|
||||
} *initiators;
|
||||
} *targets;
|
||||
} *memattrs;
|
||||
|
||||
/* hybridcpus */
|
||||
unsigned nr_cpukinds;
|
||||
unsigned nr_cpukinds_allocated;
|
||||
struct hwloc_internal_cpukind_s {
|
||||
hwloc_cpuset_t cpuset;
|
||||
#define HWLOC_CPUKIND_EFFICIENCY_UNKNOWN -1
|
||||
int efficiency;
|
||||
int forced_efficiency; /* returned by the hardware or OS if any */
|
||||
hwloc_uint64_t ranking_value; /* internal value for ranking */
|
||||
unsigned nr_infos;
|
||||
struct hwloc_info_s *infos;
|
||||
} *cpukinds;
|
||||
|
||||
int grouping;
|
||||
int grouping_verbose;
|
||||
unsigned grouping_nbaccuracies;
|
||||
|
@ -240,8 +296,9 @@ extern void hwloc_topology_clear(struct hwloc_topology *topology);
|
|||
|
||||
/* insert memory object as memory child of normal parent */
|
||||
extern struct hwloc_obj * hwloc__attach_memory_object(struct hwloc_topology *topology, hwloc_obj_t parent,
|
||||
hwloc_obj_t obj,
|
||||
hwloc_report_error_t report_error);
|
||||
hwloc_obj_t obj, const char *reason);
|
||||
|
||||
extern hwloc_obj_t hwloc_get_obj_by_type_and_gp_index(hwloc_topology_t topology, hwloc_obj_type_t type, uint64_t gp_index);
|
||||
|
||||
extern void hwloc_pci_discovery_init(struct hwloc_topology *topology);
|
||||
extern void hwloc_pci_discovery_prepare(struct hwloc_topology *topology);
|
||||
|
@ -261,6 +318,7 @@ extern hwloc_obj_t hwloc_find_insert_io_parent_by_complete_cpuset(struct hwloc_t
|
|||
extern int hwloc__add_info(struct hwloc_info_s **infosp, unsigned *countp, const char *name, const char *value);
|
||||
extern int hwloc__add_info_nodup(struct hwloc_info_s **infosp, unsigned *countp, const char *name, const char *value, int replace);
|
||||
extern int hwloc__move_infos(struct hwloc_info_s **dst_infosp, unsigned *dst_countp, struct hwloc_info_s **src_infosp, unsigned *src_countp);
|
||||
extern int hwloc__tma_dup_infos(struct hwloc_tma *tma, struct hwloc_info_s **dst_infosp, unsigned *dst_countp, struct hwloc_info_s *src_infos, unsigned src_count);
|
||||
extern void hwloc__free_infos(struct hwloc_info_s *infos, unsigned count);
|
||||
|
||||
/* set native OS binding hooks */
|
||||
|
@ -354,6 +412,22 @@ extern int hwloc_internal_distances_add(hwloc_topology_t topology, const char *n
|
|||
extern int hwloc_internal_distances_add_by_index(hwloc_topology_t topology, const char *name, hwloc_obj_type_t unique_type, hwloc_obj_type_t *different_types, unsigned nbobjs, uint64_t *indexes, uint64_t *values, unsigned long kind, unsigned long flags);
|
||||
extern void hwloc_internal_distances_invalidate_cached_objs(hwloc_topology_t topology);
|
||||
|
||||
extern void hwloc_internal_memattrs_init(hwloc_topology_t topology);
|
||||
extern void hwloc_internal_memattrs_prepare(hwloc_topology_t topology);
|
||||
extern void hwloc_internal_memattrs_destroy(hwloc_topology_t topology);
|
||||
extern void hwloc_internal_memattrs_need_refresh(hwloc_topology_t topology);
|
||||
extern void hwloc_internal_memattrs_refresh(hwloc_topology_t topology);
|
||||
extern int hwloc_internal_memattrs_dup(hwloc_topology_t new, hwloc_topology_t old);
|
||||
extern int hwloc_internal_memattr_set_value(hwloc_topology_t topology, hwloc_memattr_id_t id, hwloc_obj_type_t target_type, hwloc_uint64_t target_gp_index, unsigned target_os_index, struct hwloc_internal_location_s *initiator, hwloc_uint64_t value);
|
||||
|
||||
extern void hwloc_internal_cpukinds_init(hwloc_topology_t topology);
|
||||
extern int hwloc_internal_cpukinds_rank(hwloc_topology_t topology);
|
||||
extern void hwloc_internal_cpukinds_destroy(hwloc_topology_t topology);
|
||||
extern int hwloc_internal_cpukinds_dup(hwloc_topology_t new, hwloc_topology_t old);
|
||||
#define HWLOC_CPUKINDS_REGISTER_FLAG_OVERWRITE_FORCED_EFFICIENCY (1<<0)
|
||||
extern int hwloc_internal_cpukinds_register(hwloc_topology_t topology, hwloc_cpuset_t cpuset, int forced_efficiency, const struct hwloc_info_s *infos, unsigned nr_infos, unsigned long flags);
|
||||
extern void hwloc_internal_cpukinds_restrict(hwloc_topology_t topology);
|
||||
|
||||
/* encode src buffer into target buffer.
|
||||
* targsize must be at least 4*((srclength+2)/3)+1.
|
||||
* target will be 0-terminated.
|
||||
|
|
2
src/3rdparty/hwloc/include/private/xml.h
vendored
2
src/3rdparty/hwloc/include/private/xml.h
vendored
|
@ -46,7 +46,7 @@ struct hwloc_xml_backend_data_s {
|
|||
int (*find_child)(struct hwloc__xml_import_state_s * state, struct hwloc__xml_import_state_s * childstate, char **tagp);
|
||||
int (*close_tag)(struct hwloc__xml_import_state_s * state); /* look for an explicit closing tag </name> */
|
||||
void (*close_child)(struct hwloc__xml_import_state_s * state);
|
||||
int (*get_content)(struct hwloc__xml_import_state_s * state, char **beginp, size_t expected_length); /* return 0 on empty content (and sets beginp to empty string), 1 on actual content, -1 on error or unexpected content length */
|
||||
int (*get_content)(struct hwloc__xml_import_state_s * state, const char **beginp, size_t expected_length); /* return 0 on empty content (and sets beginp to empty string), 1 on actual content, -1 on error or unexpected content length */
|
||||
void (*close_content)(struct hwloc__xml_import_state_s * state);
|
||||
char * msgprefix;
|
||||
void *data; /* libxml2 doc, or nolibxml buffer */
|
||||
|
|
3
src/3rdparty/hwloc/src/bind.c
vendored
3
src/3rdparty/hwloc/src/bind.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2019 Inria. All rights reserved.
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009-2010, 2012 Université Bordeaux
|
||||
* Copyright © 2011-2015 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
|
@ -921,5 +921,6 @@ hwloc_set_binding_hooks(struct hwloc_topology *topology)
|
|||
DO(mem,get_area_membind);
|
||||
DO(mem,get_area_memlocation);
|
||||
DO(mem,alloc_membind);
|
||||
#undef DO
|
||||
}
|
||||
}
|
||||
|
|
4
src/3rdparty/hwloc/src/bitmap.c
vendored
4
src/3rdparty/hwloc/src/bitmap.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2018 Inria. All rights reserved.
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009-2011 Université Bordeaux
|
||||
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
|
@ -818,7 +818,7 @@ int hwloc_bitmap_nr_ulongs(const struct hwloc_bitmap_s *set)
|
|||
return -1;
|
||||
|
||||
last = hwloc_bitmap_last(set);
|
||||
return (last + HWLOC_BITS_PER_LONG-1)/HWLOC_BITS_PER_LONG;
|
||||
return (last + HWLOC_BITS_PER_LONG)/HWLOC_BITS_PER_LONG;
|
||||
}
|
||||
|
||||
int hwloc_bitmap_only(struct hwloc_bitmap_s * set, unsigned cpu)
|
||||
|
|
649
src/3rdparty/hwloc/src/cpukinds.c
vendored
Normal file
649
src/3rdparty/hwloc/src/cpukinds.c
vendored
Normal file
|
@ -0,0 +1,649 @@
|
|||
/*
|
||||
* Copyright © 2020 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include "private/autogen/config.h"
|
||||
#include "hwloc.h"
|
||||
#include "private/private.h"
|
||||
#include "private/debug.h"
|
||||
|
||||
|
||||
/*****************
|
||||
* Basics
|
||||
*/
|
||||
|
||||
void
|
||||
hwloc_internal_cpukinds_init(struct hwloc_topology *topology)
|
||||
{
|
||||
topology->cpukinds = NULL;
|
||||
topology->nr_cpukinds = 0;
|
||||
topology->nr_cpukinds_allocated = 0;
|
||||
}
|
||||
|
||||
void
|
||||
hwloc_internal_cpukinds_destroy(struct hwloc_topology *topology)
|
||||
{
|
||||
unsigned i;
|
||||
for(i=0; i<topology->nr_cpukinds; i++) {
|
||||
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
|
||||
hwloc_bitmap_free(kind->cpuset);
|
||||
hwloc__free_infos(kind->infos, kind->nr_infos);
|
||||
}
|
||||
free(topology->cpukinds);
|
||||
topology->cpukinds = NULL;
|
||||
topology->nr_cpukinds = 0;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_internal_cpukinds_dup(hwloc_topology_t new, hwloc_topology_t old)
|
||||
{
|
||||
struct hwloc_tma *tma = new->tma;
|
||||
struct hwloc_internal_cpukind_s *kinds;
|
||||
unsigned i;
|
||||
|
||||
kinds = hwloc_tma_malloc(tma, old->nr_cpukinds * sizeof(*kinds));
|
||||
if (!kinds)
|
||||
return -1;
|
||||
new->cpukinds = kinds;
|
||||
new->nr_cpukinds = old->nr_cpukinds;
|
||||
memcpy(kinds, old->cpukinds, old->nr_cpukinds * sizeof(*kinds));
|
||||
|
||||
for(i=0;i<old->nr_cpukinds; i++) {
|
||||
kinds[i].cpuset = hwloc_bitmap_tma_dup(tma, old->cpukinds[i].cpuset);
|
||||
if (!kinds[i].cpuset) {
|
||||
new->nr_cpukinds = i;
|
||||
goto failed;
|
||||
}
|
||||
if (hwloc__tma_dup_infos(tma,
|
||||
&kinds[i].infos, &kinds[i].nr_infos,
|
||||
old->cpukinds[i].infos, old->cpukinds[i].nr_infos) < 0) {
|
||||
assert(!tma || !tma->dontfree); /* this tma cannot fail to allocate */
|
||||
hwloc_bitmap_free(kinds[i].cpuset);
|
||||
new->nr_cpukinds = i;
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
hwloc_internal_cpukinds_destroy(new);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
hwloc_internal_cpukinds_restrict(hwloc_topology_t topology)
|
||||
{
|
||||
unsigned i;
|
||||
int removed = 0;
|
||||
for(i=0; i<topology->nr_cpukinds; i++) {
|
||||
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
|
||||
hwloc_bitmap_and(kind->cpuset, kind->cpuset, hwloc_get_root_obj(topology)->cpuset);
|
||||
if (hwloc_bitmap_iszero(kind->cpuset)) {
|
||||
hwloc_bitmap_free(kind->cpuset);
|
||||
hwloc__free_infos(kind->infos, kind->nr_infos);
|
||||
memmove(kind, kind+1, (topology->nr_cpukinds - i - 1)*sizeof(*kind));
|
||||
i--;
|
||||
topology->nr_cpukinds--;
|
||||
removed = 1;
|
||||
}
|
||||
}
|
||||
if (removed)
|
||||
hwloc_internal_cpukinds_rank(topology);
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
* Registering
|
||||
*/
|
||||
|
||||
static __hwloc_inline int
|
||||
hwloc__cpukind_check_duplicate_info(struct hwloc_internal_cpukind_s *kind,
|
||||
const char *name, const char *value)
|
||||
{
|
||||
unsigned i;
|
||||
for(i=0; i<kind->nr_infos; i++)
|
||||
if (!strcmp(kind->infos[i].name, name)
|
||||
&& !strcmp(kind->infos[i].value, value))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __hwloc_inline void
|
||||
hwloc__cpukind_add_infos(struct hwloc_internal_cpukind_s *kind,
|
||||
const struct hwloc_info_s *infos, unsigned nr_infos)
|
||||
{
|
||||
unsigned i;
|
||||
for(i=0; i<nr_infos; i++) {
|
||||
if (hwloc__cpukind_check_duplicate_info(kind, infos[i].name, infos[i].value))
|
||||
continue;
|
||||
hwloc__add_info(&kind->infos, &kind->nr_infos, infos[i].name, infos[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_internal_cpukinds_register(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
|
||||
int forced_efficiency,
|
||||
const struct hwloc_info_s *infos, unsigned nr_infos,
|
||||
unsigned long flags)
|
||||
{
|
||||
struct hwloc_internal_cpukind_s *kinds;
|
||||
unsigned i, max, bits, oldnr, newnr;
|
||||
|
||||
if (hwloc_bitmap_iszero(cpuset)) {
|
||||
hwloc_bitmap_free(cpuset);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags & ~HWLOC_CPUKINDS_REGISTER_FLAG_OVERWRITE_FORCED_EFFICIENCY) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TODO: for now, only windows provides a forced efficiency.
|
||||
* if another backend ever provides a conflicting value, the first backend value will be kept.
|
||||
* (user-provided values are not an issue, they are meant to overwrite)
|
||||
*/
|
||||
|
||||
/* If we have N kinds currently, we may need 2N+1 kinds after inserting the new one:
|
||||
* - each existing kind may get split into which PUs are in the new kind and which aren't.
|
||||
* - some PUs might not have been in any kind yet.
|
||||
*/
|
||||
max = 2 * topology->nr_cpukinds + 1;
|
||||
/* Allocate the power-of-two above 2N+1. */
|
||||
bits = hwloc_flsl(max-1) + 1;
|
||||
max = 1U<<bits;
|
||||
/* Allocate 8 minimum to avoid multiple reallocs */
|
||||
if (max < 8)
|
||||
max = 8;
|
||||
|
||||
/* Create or enlarge the array of kinds if needed */
|
||||
kinds = topology->cpukinds;
|
||||
if (max > topology->nr_cpukinds_allocated) {
|
||||
kinds = realloc(kinds, max * sizeof(*kinds));
|
||||
if (!kinds) {
|
||||
hwloc_bitmap_free(cpuset);
|
||||
return -1;
|
||||
}
|
||||
memset(&kinds[topology->nr_cpukinds_allocated], 0, (max - topology->nr_cpukinds_allocated) * sizeof(*kinds));
|
||||
topology->nr_cpukinds_allocated = max;
|
||||
topology->cpukinds = kinds;
|
||||
}
|
||||
|
||||
newnr = oldnr = topology->nr_cpukinds;
|
||||
for(i=0; i<oldnr; i++) {
|
||||
int res = hwloc_bitmap_compare_inclusion(cpuset, kinds[i].cpuset);
|
||||
if (res == HWLOC_BITMAP_INTERSECTS || res == HWLOC_BITMAP_INCLUDED) {
|
||||
/* new kind with intersection of cpusets and union of infos */
|
||||
kinds[newnr].cpuset = hwloc_bitmap_alloc();
|
||||
kinds[newnr].efficiency = HWLOC_CPUKIND_EFFICIENCY_UNKNOWN;
|
||||
kinds[newnr].forced_efficiency = forced_efficiency;
|
||||
hwloc_bitmap_and(kinds[newnr].cpuset, cpuset, kinds[i].cpuset);
|
||||
hwloc__cpukind_add_infos(&kinds[newnr], kinds[i].infos, kinds[i].nr_infos);
|
||||
hwloc__cpukind_add_infos(&kinds[newnr], infos, nr_infos);
|
||||
/* remove cpuset PUs from the existing kind that we just split */
|
||||
hwloc_bitmap_andnot(kinds[i].cpuset, kinds[i].cpuset, kinds[newnr].cpuset);
|
||||
/* clear cpuset PUs that were taken care of */
|
||||
hwloc_bitmap_andnot(cpuset, cpuset, kinds[newnr].cpuset);
|
||||
|
||||
newnr++;
|
||||
|
||||
} else if (res == HWLOC_BITMAP_CONTAINS
|
||||
|| res == HWLOC_BITMAP_EQUAL) {
|
||||
/* append new info to existing smaller (or equal) kind */
|
||||
hwloc__cpukind_add_infos(&kinds[i], infos, nr_infos);
|
||||
if ((flags & HWLOC_CPUKINDS_REGISTER_FLAG_OVERWRITE_FORCED_EFFICIENCY)
|
||||
|| kinds[i].forced_efficiency == HWLOC_CPUKIND_EFFICIENCY_UNKNOWN)
|
||||
kinds[i].forced_efficiency = forced_efficiency;
|
||||
/* clear cpuset PUs that were taken care of */
|
||||
hwloc_bitmap_andnot(cpuset, cpuset, kinds[i].cpuset);
|
||||
|
||||
} else {
|
||||
assert(res == HWLOC_BITMAP_DIFFERENT);
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
/* don't compare with anything else if already empty */
|
||||
if (hwloc_bitmap_iszero(cpuset))
|
||||
break;
|
||||
}
|
||||
|
||||
/* add a final kind with remaining PUs if any */
|
||||
if (!hwloc_bitmap_iszero(cpuset)) {
|
||||
kinds[newnr].cpuset = cpuset;
|
||||
kinds[newnr].efficiency = HWLOC_CPUKIND_EFFICIENCY_UNKNOWN;
|
||||
kinds[newnr].forced_efficiency = forced_efficiency;
|
||||
hwloc__cpukind_add_infos(&kinds[newnr], infos, nr_infos);
|
||||
newnr++;
|
||||
} else {
|
||||
hwloc_bitmap_free(cpuset);
|
||||
}
|
||||
|
||||
topology->nr_cpukinds = newnr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_cpukinds_register(hwloc_topology_t topology, hwloc_cpuset_t _cpuset,
|
||||
int forced_efficiency,
|
||||
unsigned nr_infos, struct hwloc_info_s *infos,
|
||||
unsigned long flags)
|
||||
{
|
||||
hwloc_bitmap_t cpuset;
|
||||
int err;
|
||||
|
||||
if (flags) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!_cpuset || hwloc_bitmap_iszero(_cpuset)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
cpuset = hwloc_bitmap_dup(_cpuset);
|
||||
if (!cpuset)
|
||||
return -1;
|
||||
|
||||
if (forced_efficiency < 0)
|
||||
forced_efficiency = HWLOC_CPUKIND_EFFICIENCY_UNKNOWN;
|
||||
|
||||
err = hwloc_internal_cpukinds_register(topology, cpuset, forced_efficiency, infos, nr_infos, HWLOC_CPUKINDS_REGISTER_FLAG_OVERWRITE_FORCED_EFFICIENCY);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
hwloc_internal_cpukinds_rank(topology);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*********************
|
||||
* Ranking
|
||||
*/
|
||||
|
||||
static int
|
||||
hwloc__cpukinds_check_duplicate_rankings(struct hwloc_topology *topology)
|
||||
{
|
||||
unsigned i,j;
|
||||
for(i=0; i<topology->nr_cpukinds; i++)
|
||||
for(j=i+1; j<topology->nr_cpukinds; j++)
|
||||
if (topology->cpukinds[i].forced_efficiency == topology->cpukinds[j].forced_efficiency)
|
||||
/* if any duplicate, fail */
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc__cpukinds_try_rank_by_forced_efficiency(struct hwloc_topology *topology)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
hwloc_debug("Trying to rank cpukinds by forced efficiency...\n");
|
||||
for(i=0; i<topology->nr_cpukinds; i++) {
|
||||
if (topology->cpukinds[i].forced_efficiency == HWLOC_CPUKIND_EFFICIENCY_UNKNOWN)
|
||||
/* if any unknown, fail */
|
||||
return -1;
|
||||
topology->cpukinds[i].ranking_value = topology->cpukinds[i].forced_efficiency;
|
||||
}
|
||||
|
||||
return hwloc__cpukinds_check_duplicate_rankings(topology);
|
||||
}
|
||||
|
||||
struct hwloc_cpukinds_info_summary {
|
||||
int have_max_freq;
|
||||
int have_base_freq;
|
||||
int have_intel_core_type;
|
||||
struct hwloc_cpukind_info_summary {
|
||||
unsigned intel_core_type; /* 1 for atom, 2 for core */
|
||||
unsigned max_freq, base_freq; /* MHz, hence < 100000 */
|
||||
} * summaries;
|
||||
};
|
||||
|
||||
static void
|
||||
hwloc__cpukinds_summarize_info(struct hwloc_topology *topology,
|
||||
struct hwloc_cpukinds_info_summary *summary)
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
summary->have_max_freq = 1;
|
||||
summary->have_base_freq = 1;
|
||||
summary->have_intel_core_type = 1;
|
||||
|
||||
for(i=0; i<topology->nr_cpukinds; i++) {
|
||||
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
|
||||
for(j=0; j<kind->nr_infos; j++) {
|
||||
struct hwloc_info_s *info = &kind->infos[j];
|
||||
if (!strcmp(info->name, "FrequencyMaxMHz")) {
|
||||
summary->summaries[i].max_freq = atoi(info->value);
|
||||
} else if (!strcmp(info->name, "FrequencyBaseMHz")) {
|
||||
summary->summaries[i].base_freq = atoi(info->value);
|
||||
} else if (!strcmp(info->name, "CoreType")) {
|
||||
if (!strcmp(info->value, "IntelAtom"))
|
||||
summary->summaries[i].intel_core_type = 1;
|
||||
else if (!strcmp(info->value, "IntelCore"))
|
||||
summary->summaries[i].intel_core_type = 2;
|
||||
}
|
||||
}
|
||||
hwloc_debug("cpukind #%u has intel_core_type %u max_freq %u base_freq %u\n",
|
||||
i, summary->summaries[i].intel_core_type,
|
||||
summary->summaries[i].max_freq, summary->summaries[i].base_freq);
|
||||
if (!summary->summaries[i].base_freq)
|
||||
summary->have_base_freq = 0;
|
||||
if (!summary->summaries[i].max_freq)
|
||||
summary->have_max_freq = 0;
|
||||
if (!summary->summaries[i].intel_core_type)
|
||||
summary->have_intel_core_type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
enum hwloc_cpukinds_ranking {
|
||||
HWLOC_CPUKINDS_RANKING_DEFAULT, /* forced + frequency on ARM, forced + coretype_frequency otherwise */
|
||||
HWLOC_CPUKINDS_RANKING_NO_FORCED_EFFICIENCY, /* default without forced */
|
||||
HWLOC_CPUKINDS_RANKING_FORCED_EFFICIENCY,
|
||||
HWLOC_CPUKINDS_RANKING_CORETYPE_FREQUENCY,
|
||||
HWLOC_CPUKINDS_RANKING_CORETYPE,
|
||||
HWLOC_CPUKINDS_RANKING_FREQUENCY,
|
||||
HWLOC_CPUKINDS_RANKING_FREQUENCY_MAX,
|
||||
HWLOC_CPUKINDS_RANKING_FREQUENCY_BASE,
|
||||
HWLOC_CPUKINDS_RANKING_NONE
|
||||
};
|
||||
|
||||
static int
|
||||
hwloc__cpukinds_try_rank_by_info(struct hwloc_topology *topology,
|
||||
enum hwloc_cpukinds_ranking heuristics,
|
||||
struct hwloc_cpukinds_info_summary *summary)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (HWLOC_CPUKINDS_RANKING_CORETYPE_FREQUENCY == heuristics) {
|
||||
hwloc_debug("Trying to rank cpukinds by coretype+frequency...\n");
|
||||
/* we need intel_core_type + (base or max freq) for all kinds */
|
||||
if (!summary->have_intel_core_type
|
||||
|| (!summary->have_max_freq && !summary->have_base_freq))
|
||||
return -1;
|
||||
/* rank first by coretype (Core>>Atom) then by frequency, base if available, max otherwise */
|
||||
for(i=0; i<topology->nr_cpukinds; i++) {
|
||||
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
|
||||
if (summary->have_base_freq)
|
||||
kind->ranking_value = (summary->summaries[i].intel_core_type << 20) + summary->summaries[i].base_freq;
|
||||
else
|
||||
kind->ranking_value = (summary->summaries[i].intel_core_type << 20) + summary->summaries[i].max_freq;
|
||||
}
|
||||
|
||||
} else if (HWLOC_CPUKINDS_RANKING_CORETYPE == heuristics) {
|
||||
hwloc_debug("Trying to rank cpukinds by coretype...\n");
|
||||
/* we need intel_core_type */
|
||||
if (!summary->have_intel_core_type)
|
||||
return -1;
|
||||
/* rank by coretype (Core>>Atom) */
|
||||
for(i=0; i<topology->nr_cpukinds; i++) {
|
||||
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
|
||||
kind->ranking_value = (summary->summaries[i].intel_core_type << 20);
|
||||
}
|
||||
|
||||
} else if (HWLOC_CPUKINDS_RANKING_FREQUENCY == heuristics) {
|
||||
hwloc_debug("Trying to rank cpukinds by frequency...\n");
|
||||
/* we need base or max freq for all kinds */
|
||||
if (!summary->have_max_freq && !summary->have_base_freq)
|
||||
return -1;
|
||||
/* rank first by frequency, base if available, max otherwise */
|
||||
for(i=0; i<topology->nr_cpukinds; i++) {
|
||||
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
|
||||
if (summary->have_base_freq)
|
||||
kind->ranking_value = summary->summaries[i].base_freq;
|
||||
else
|
||||
kind->ranking_value = summary->summaries[i].max_freq;
|
||||
}
|
||||
|
||||
} else if (HWLOC_CPUKINDS_RANKING_FREQUENCY_MAX == heuristics) {
|
||||
hwloc_debug("Trying to rank cpukinds by frequency max...\n");
|
||||
/* we need max freq for all kinds */
|
||||
if (!summary->have_max_freq)
|
||||
return -1;
|
||||
/* rank first by frequency, base if available, max otherwise */
|
||||
for(i=0; i<topology->nr_cpukinds; i++) {
|
||||
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
|
||||
kind->ranking_value = summary->summaries[i].max_freq;
|
||||
}
|
||||
|
||||
} else if (HWLOC_CPUKINDS_RANKING_FREQUENCY_BASE == heuristics) {
|
||||
hwloc_debug("Trying to rank cpukinds by frequency base...\n");
|
||||
/* we need max freq for all kinds */
|
||||
if (!summary->have_base_freq)
|
||||
return -1;
|
||||
/* rank first by frequency, base if available, max otherwise */
|
||||
for(i=0; i<topology->nr_cpukinds; i++) {
|
||||
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
|
||||
kind->ranking_value = summary->summaries[i].base_freq;
|
||||
}
|
||||
|
||||
} else assert(0);
|
||||
|
||||
return hwloc__cpukinds_check_duplicate_rankings(topology);
|
||||
}
|
||||
|
||||
static int hwloc__cpukinds_compare_ranking_values(const void *_a, const void *_b)
|
||||
{
|
||||
const struct hwloc_internal_cpukind_s *a = _a;
|
||||
const struct hwloc_internal_cpukind_s *b = _b;
|
||||
return a->ranking_value - b->ranking_value;
|
||||
}
|
||||
|
||||
/* this function requires ranking values to be unique */
|
||||
static void
|
||||
hwloc__cpukinds_finalize_ranking(struct hwloc_topology *topology)
|
||||
{
|
||||
unsigned i;
|
||||
/* sort */
|
||||
qsort(topology->cpukinds, topology->nr_cpukinds, sizeof(*topology->cpukinds), hwloc__cpukinds_compare_ranking_values);
|
||||
/* define our own efficiency between 0 and N-1 */
|
||||
for(i=0; i<topology->nr_cpukinds; i++)
|
||||
topology->cpukinds[i].efficiency = i;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_internal_cpukinds_rank(struct hwloc_topology *topology)
|
||||
{
|
||||
enum hwloc_cpukinds_ranking heuristics;
|
||||
char *env;
|
||||
unsigned i;
|
||||
int err;
|
||||
|
||||
if (!topology->nr_cpukinds)
|
||||
return 0;
|
||||
|
||||
if (topology->nr_cpukinds == 1) {
|
||||
topology->cpukinds[0].efficiency = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_DEFAULT;
|
||||
env = getenv("HWLOC_CPUKINDS_RANKING");
|
||||
if (env) {
|
||||
if (!strcmp(env, "default"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_DEFAULT;
|
||||
else if (!strcmp(env, "none"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_NONE;
|
||||
else if (!strcmp(env, "coretype+frequency"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_CORETYPE_FREQUENCY;
|
||||
else if (!strcmp(env, "coretype"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_CORETYPE;
|
||||
else if (!strcmp(env, "frequency"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_FREQUENCY;
|
||||
else if (!strcmp(env, "frequency_max"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_FREQUENCY_MAX;
|
||||
else if (!strcmp(env, "frequency_base"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_FREQUENCY_BASE;
|
||||
else if (!strcmp(env, "forced_efficiency"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_FORCED_EFFICIENCY;
|
||||
else if (!strcmp(env, "no_forced_efficiency"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_NO_FORCED_EFFICIENCY;
|
||||
else if (!hwloc_hide_errors())
|
||||
fprintf(stderr, "Failed to recognize HWLOC_CPUKINDS_RANKING value %s\n", env);
|
||||
}
|
||||
|
||||
if (heuristics == HWLOC_CPUKINDS_RANKING_DEFAULT
|
||||
|| heuristics == HWLOC_CPUKINDS_RANKING_NO_FORCED_EFFICIENCY) {
|
||||
/* default is forced_efficiency first */
|
||||
struct hwloc_cpukinds_info_summary summary;
|
||||
enum hwloc_cpukinds_ranking subheuristics;
|
||||
const char *arch;
|
||||
|
||||
if (heuristics == HWLOC_CPUKINDS_RANKING_DEFAULT)
|
||||
hwloc_debug("Using default ranking strategy...\n");
|
||||
else
|
||||
hwloc_debug("Using custom ranking strategy from HWLOC_CPUKINDS_RANKING=%s\n", env);
|
||||
|
||||
if (heuristics != HWLOC_CPUKINDS_RANKING_NO_FORCED_EFFICIENCY) {
|
||||
err = hwloc__cpukinds_try_rank_by_forced_efficiency(topology);
|
||||
if (!err)
|
||||
goto ready;
|
||||
}
|
||||
|
||||
summary.summaries = calloc(topology->nr_cpukinds, sizeof(*summary.summaries));
|
||||
if (!summary.summaries)
|
||||
goto failed;
|
||||
hwloc__cpukinds_summarize_info(topology, &summary);
|
||||
|
||||
arch = hwloc_obj_get_info_by_name(topology->levels[0][0], "Architecture");
|
||||
/* TODO: rather coretype_frequency only on x86/Intel? */
|
||||
if (arch && (!strncmp(arch, "arm", 3) || !strncmp(arch, "aarch", 5)))
|
||||
/* then frequency on ARM */
|
||||
subheuristics = HWLOC_CPUKINDS_RANKING_FREQUENCY;
|
||||
else
|
||||
/* or coretype+frequency otherwise */
|
||||
subheuristics = HWLOC_CPUKINDS_RANKING_CORETYPE_FREQUENCY;
|
||||
|
||||
err = hwloc__cpukinds_try_rank_by_info(topology, subheuristics, &summary);
|
||||
free(summary.summaries);
|
||||
if (!err)
|
||||
goto ready;
|
||||
|
||||
} else if (heuristics == HWLOC_CPUKINDS_RANKING_FORCED_EFFICIENCY) {
|
||||
hwloc_debug("Using custom ranking strategy from HWLOC_CPUKINDS_RANKING=%s\n", env);
|
||||
|
||||
err = hwloc__cpukinds_try_rank_by_forced_efficiency(topology);
|
||||
if (!err)
|
||||
goto ready;
|
||||
|
||||
} else if (heuristics != HWLOC_CPUKINDS_RANKING_NONE) {
|
||||
/* custom heuristics */
|
||||
struct hwloc_cpukinds_info_summary summary;
|
||||
|
||||
hwloc_debug("Using custom ranking strategy from HWLOC_CPUKINDS_RANKING=%s\n", env);
|
||||
|
||||
summary.summaries = calloc(topology->nr_cpukinds, sizeof(*summary.summaries));
|
||||
if (!summary.summaries)
|
||||
goto failed;
|
||||
hwloc__cpukinds_summarize_info(topology, &summary);
|
||||
|
||||
err = hwloc__cpukinds_try_rank_by_info(topology, heuristics, &summary);
|
||||
free(summary.summaries);
|
||||
if (!err)
|
||||
goto ready;
|
||||
}
|
||||
|
||||
failed:
|
||||
/* failed to rank, clear efficiencies */
|
||||
for(i=0; i<topology->nr_cpukinds; i++)
|
||||
topology->cpukinds[i].efficiency = HWLOC_CPUKIND_EFFICIENCY_UNKNOWN;
|
||||
hwloc_debug("Failed to rank cpukinds.\n\n");
|
||||
return 0;
|
||||
|
||||
ready:
|
||||
for(i=0; i<topology->nr_cpukinds; i++)
|
||||
hwloc_debug("cpukind #%u got ranking value %llu\n", i, (unsigned long long) topology->cpukinds[i].ranking_value);
|
||||
hwloc__cpukinds_finalize_ranking(topology);
|
||||
#ifdef HWLOC_DEBUG
|
||||
for(i=0; i<topology->nr_cpukinds; i++)
|
||||
assert(topology->cpukinds[i].efficiency == (int) i);
|
||||
#endif
|
||||
hwloc_debug("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
* Consulting
|
||||
*/
|
||||
|
||||
int
|
||||
hwloc_cpukinds_get_nr(hwloc_topology_t topology, unsigned long flags)
|
||||
{
|
||||
if (flags) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return topology->nr_cpukinds;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_cpukinds_get_info(hwloc_topology_t topology,
|
||||
unsigned id,
|
||||
hwloc_bitmap_t cpuset,
|
||||
int *efficiencyp,
|
||||
unsigned *nr_infosp, struct hwloc_info_s **infosp,
|
||||
unsigned long flags)
|
||||
{
|
||||
struct hwloc_internal_cpukind_s *kind;
|
||||
|
||||
if (flags) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (id >= topology->nr_cpukinds) {
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
kind = &topology->cpukinds[id];
|
||||
|
||||
if (cpuset)
|
||||
hwloc_bitmap_copy(cpuset, kind->cpuset);
|
||||
|
||||
if (efficiencyp)
|
||||
*efficiencyp = kind->efficiency;
|
||||
|
||||
if (nr_infosp && infosp) {
|
||||
*nr_infosp = kind->nr_infos;
|
||||
*infosp = kind->infos;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_cpukinds_get_by_cpuset(hwloc_topology_t topology,
|
||||
hwloc_const_bitmap_t cpuset,
|
||||
unsigned long flags)
|
||||
{
|
||||
unsigned id;
|
||||
|
||||
if (flags) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!cpuset || hwloc_bitmap_iszero(cpuset)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(id=0; id<topology->nr_cpukinds; id++) {
|
||||
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[id];
|
||||
int res = hwloc_bitmap_compare_inclusion(cpuset, kind->cpuset);
|
||||
if (res == HWLOC_BITMAP_EQUAL || res == HWLOC_BITMAP_INCLUDED) {
|
||||
return (int) id;
|
||||
} else if (res == HWLOC_BITMAP_INTERSECTS || res == HWLOC_BITMAP_CONTAINS) {
|
||||
errno = EXDEV;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
83
src/3rdparty/hwloc/src/diff.c
vendored
83
src/3rdparty/hwloc/src/diff.c
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2013-2019 Inria. All rights reserved.
|
||||
* Copyright © 2013-2020 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
|
@ -333,10 +333,8 @@ int hwloc_topology_diff_build(hwloc_topology_t topo1,
|
|||
|
||||
if (!err) {
|
||||
if (SETS_DIFFERENT(allowed_cpuset, topo1, topo2)
|
||||
|| SETS_DIFFERENT(allowed_nodeset, topo1, topo2)) {
|
||||
hwloc_append_diff_too_complex(hwloc_get_root_obj(topo1), diffp, &lastdiff);
|
||||
err = 1;
|
||||
}
|
||||
|| SETS_DIFFERENT(allowed_nodeset, topo1, topo2))
|
||||
goto roottoocomplex;
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
|
@ -346,33 +344,78 @@ int hwloc_topology_diff_build(hwloc_topology_t topo1,
|
|||
dist1 = topo1->first_dist;
|
||||
dist2 = topo2->first_dist;
|
||||
while (dist1 || dist2) {
|
||||
if (!!dist1 != !!dist2) {
|
||||
hwloc_append_diff_too_complex(hwloc_get_root_obj(topo1), diffp, &lastdiff);
|
||||
err = 1;
|
||||
break;
|
||||
}
|
||||
if (!!dist1 != !!dist2)
|
||||
goto roottoocomplex;
|
||||
if (dist1->unique_type != dist2->unique_type
|
||||
|| dist1->different_types || dist2->different_types /* too lazy to support this case */
|
||||
|| dist1->nbobjs != dist2->nbobjs
|
||||
|| dist1->kind != dist2->kind
|
||||
|| memcmp(dist1->values, dist2->values, dist1->nbobjs * dist1->nbobjs * sizeof(*dist1->values))) {
|
||||
hwloc_append_diff_too_complex(hwloc_get_root_obj(topo1), diffp, &lastdiff);
|
||||
err = 1;
|
||||
break;
|
||||
}
|
||||
|| memcmp(dist1->values, dist2->values, dist1->nbobjs * dist1->nbobjs * sizeof(*dist1->values)))
|
||||
goto roottoocomplex;
|
||||
for(i=0; i<dist1->nbobjs; i++)
|
||||
/* gp_index isn't enforced above. so compare logical_index instead, which is enforced. requires distances refresh() above */
|
||||
if (dist1->objs[i]->logical_index != dist2->objs[i]->logical_index) {
|
||||
hwloc_append_diff_too_complex(hwloc_get_root_obj(topo1), diffp, &lastdiff);
|
||||
err = 1;
|
||||
break;
|
||||
}
|
||||
if (dist1->objs[i]->logical_index != dist2->objs[i]->logical_index)
|
||||
goto roottoocomplex;
|
||||
dist1 = dist1->next;
|
||||
dist2 = dist2->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
/* memattrs */
|
||||
hwloc_internal_memattrs_refresh(topo1);
|
||||
hwloc_internal_memattrs_refresh(topo2);
|
||||
if (topo1->nr_memattrs != topo2->nr_memattrs)
|
||||
goto roottoocomplex;
|
||||
for(i=0; i<topo1->nr_memattrs; i++) {
|
||||
struct hwloc_internal_memattr_s *imattr1 = &topo1->memattrs[i], *imattr2 = &topo2->memattrs[i];
|
||||
unsigned j;
|
||||
if (strcmp(imattr1->name, imattr2->name)
|
||||
|| imattr1->flags != imattr2->flags
|
||||
|| imattr1->nr_targets != imattr2->nr_targets)
|
||||
goto roottoocomplex;
|
||||
if (i == HWLOC_MEMATTR_ID_CAPACITY
|
||||
|| i == HWLOC_MEMATTR_ID_LOCALITY)
|
||||
/* no need to check virtual attributes, there were refreshed from other topology attributes, checked above */
|
||||
continue;
|
||||
for(j=0; j<imattr1->nr_targets; j++) {
|
||||
struct hwloc_internal_memattr_target_s *imtg1 = &imattr1->targets[j], *imtg2 = &imattr2->targets[j];
|
||||
if (imtg1->type != imtg2->type)
|
||||
goto roottoocomplex;
|
||||
if (imtg1->obj->logical_index != imtg2->obj->logical_index)
|
||||
goto roottoocomplex;
|
||||
if (imattr1->flags & HWLOC_MEMATTR_FLAG_NEED_INITIATOR) {
|
||||
unsigned k;
|
||||
for(k=0; k<imtg1->nr_initiators; k++) {
|
||||
struct hwloc_internal_memattr_initiator_s *imi1 = &imtg1->initiators[k], *imi2 = &imtg2->initiators[k];
|
||||
if (imi1->value != imi2->value
|
||||
|| imi1->initiator.type != imi2->initiator.type)
|
||||
goto roottoocomplex;
|
||||
if (imi1->initiator.type == HWLOC_LOCATION_TYPE_CPUSET) {
|
||||
if (!hwloc_bitmap_isequal(imi1->initiator.location.cpuset, imi2->initiator.location.cpuset))
|
||||
goto roottoocomplex;
|
||||
} else if (imi1->initiator.type == HWLOC_LOCATION_TYPE_OBJECT) {
|
||||
if (imi1->initiator.location.object.type != imi2->initiator.location.object.type)
|
||||
goto roottoocomplex;
|
||||
if (imi1->initiator.location.object.obj->logical_index != imi2->initiator.location.object.obj->logical_index)
|
||||
goto roottoocomplex;
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (imtg1->noinitiator_value != imtg2->noinitiator_value)
|
||||
goto roottoocomplex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
|
||||
roottoocomplex:
|
||||
hwloc_append_diff_too_complex(hwloc_get_root_obj(topo1), diffp, &lastdiff);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/********************
|
||||
|
|
56
src/3rdparty/hwloc/src/distances.c
vendored
56
src/3rdparty/hwloc/src/distances.c
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2010-2019 Inria. All rights reserved.
|
||||
* Copyright © 2010-2020 Inria. All rights reserved.
|
||||
* Copyright © 2011-2012 Université Bordeaux
|
||||
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
|
@ -526,36 +526,6 @@ int hwloc_distances_add(hwloc_topology_t topology,
|
|||
* Refresh objects in distances
|
||||
*/
|
||||
|
||||
static hwloc_obj_t hwloc_find_obj_by_depth_and_gp_index(hwloc_topology_t topology, unsigned depth, uint64_t gp_index)
|
||||
{
|
||||
hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, 0);
|
||||
while (obj) {
|
||||
if (obj->gp_index == gp_index)
|
||||
return obj;
|
||||
obj = obj->next_cousin;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static hwloc_obj_t hwloc_find_obj_by_type_and_gp_index(hwloc_topology_t topology, hwloc_obj_type_t type, uint64_t gp_index)
|
||||
{
|
||||
int depth = hwloc_get_type_depth(topology, type);
|
||||
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
|
||||
return NULL;
|
||||
if (depth == HWLOC_TYPE_DEPTH_MULTIPLE) {
|
||||
int topodepth = hwloc_topology_get_depth(topology);
|
||||
for(depth=0; depth<topodepth; depth++) {
|
||||
if (hwloc_get_depth_type(topology, depth) == type) {
|
||||
hwloc_obj_t obj = hwloc_find_obj_by_depth_and_gp_index(topology, depth, gp_index);
|
||||
if (obj)
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
return hwloc_find_obj_by_depth_and_gp_index(topology, depth, gp_index);
|
||||
}
|
||||
|
||||
static void
|
||||
hwloc_internal_distances_restrict(hwloc_obj_t *objs,
|
||||
uint64_t *indexes,
|
||||
|
@ -612,7 +582,7 @@ hwloc_internal_distances_refresh_one(hwloc_topology_t topology,
|
|||
else
|
||||
abort();
|
||||
} else {
|
||||
obj = hwloc_find_obj_by_type_and_gp_index(topology, different_types ? different_types[i] : unique_type, indexes[i]);
|
||||
obj = hwloc_get_obj_by_type_and_gp_index(topology, different_types ? different_types[i] : unique_type, indexes[i]);
|
||||
}
|
||||
objs[i] = obj;
|
||||
if (!obj)
|
||||
|
@ -874,26 +844,6 @@ hwloc_distances_get_by_type(hwloc_topology_t topology, hwloc_obj_type_t type,
|
|||
* Grouping objects according to distances
|
||||
*/
|
||||
|
||||
static void hwloc_report_user_distance_error(const char *msg, int line)
|
||||
{
|
||||
static int reported = 0;
|
||||
|
||||
if (!reported && !hwloc_hide_errors()) {
|
||||
fprintf(stderr, "****************************************************************************\n");
|
||||
fprintf(stderr, "* hwloc %s was given invalid distances by the user.\n", HWLOC_VERSION);
|
||||
fprintf(stderr, "*\n");
|
||||
fprintf(stderr, "* %s\n", msg);
|
||||
fprintf(stderr, "* Error occurred in topology.c line %d\n", line);
|
||||
fprintf(stderr, "*\n");
|
||||
fprintf(stderr, "* Please make sure that distances given through the programming API\n");
|
||||
fprintf(stderr, "* do not contradict any other topology information.\n");
|
||||
fprintf(stderr, "* \n");
|
||||
fprintf(stderr, "* hwloc will now ignore this invalid topology information and continue.\n");
|
||||
fprintf(stderr, "****************************************************************************\n");
|
||||
reported = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int hwloc_compare_values(uint64_t a, uint64_t b, float accuracy)
|
||||
{
|
||||
if (accuracy != 0.0f && fabsf((float)a-(float)b) < (float)a * accuracy)
|
||||
|
@ -1086,7 +1036,7 @@ hwloc__groups_by_distances(struct hwloc_topology *topology,
|
|||
hwloc_debug_1arg_bitmap("adding Group object with %u objects and cpuset %s\n",
|
||||
groupsizes[i], group_obj->cpuset);
|
||||
res_obj = hwloc__insert_object_by_cpuset(topology, NULL, group_obj,
|
||||
(kind & HWLOC_DISTANCES_KIND_FROM_USER) ? hwloc_report_user_distance_error : hwloc_report_os_error);
|
||||
(kind & HWLOC_DISTANCES_KIND_FROM_USER) ? "distances:fromuser:group" : "distances:group");
|
||||
/* res_obj may be NULL on failure to insert. */
|
||||
if (!res_obj)
|
||||
failed++;
|
||||
|
|
1197
src/3rdparty/hwloc/src/memattrs.c
vendored
Normal file
1197
src/3rdparty/hwloc/src/memattrs.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
4
src/3rdparty/hwloc/src/misc.c
vendored
4
src/3rdparty/hwloc/src/misc.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2018 Inria. All rights reserved.
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009-2010 Université Bordeaux
|
||||
* Copyright © 2009-2018 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
|
@ -114,7 +114,7 @@ void hwloc_add_uname_info(struct hwloc_topology *topology __hwloc_attribute_unus
|
|||
char *
|
||||
hwloc_progname(struct hwloc_topology *topology __hwloc_attribute_unused)
|
||||
{
|
||||
#if HAVE_DECL_GETMODULEFILENAME
|
||||
#if (defined HAVE_DECL_GETMODULEFILENAME) && HAVE_DECL_GETMODULEFILENAME
|
||||
char name[256], *local_basename;
|
||||
unsigned res = GetModuleFileName(NULL, name, sizeof(name));
|
||||
if (res == sizeof(name) || !res)
|
||||
|
|
62
src/3rdparty/hwloc/src/pci-common.c
vendored
62
src/3rdparty/hwloc/src/pci-common.c
vendored
|
@ -232,7 +232,8 @@ enum hwloc_pci_busid_comparison_e {
|
|||
HWLOC_PCI_BUSID_LOWER,
|
||||
HWLOC_PCI_BUSID_HIGHER,
|
||||
HWLOC_PCI_BUSID_INCLUDED,
|
||||
HWLOC_PCI_BUSID_SUPERSET
|
||||
HWLOC_PCI_BUSID_SUPERSET,
|
||||
HWLOC_PCI_BUSID_EQUAL
|
||||
};
|
||||
|
||||
static enum hwloc_pci_busid_comparison_e
|
||||
|
@ -274,11 +275,8 @@ hwloc_pci_compare_busids(struct hwloc_obj *a, struct hwloc_obj *b)
|
|||
if (a->attr->pcidev.func > b->attr->pcidev.func)
|
||||
return HWLOC_PCI_BUSID_HIGHER;
|
||||
|
||||
/* Should never reach here. Abort on both debug builds and
|
||||
non-debug builds */
|
||||
assert(0);
|
||||
fprintf(stderr, "Bad assertion in hwloc %s:%d (aborting)\n", __FILE__, __LINE__);
|
||||
exit(1);
|
||||
/* Should never reach here. */
|
||||
return HWLOC_PCI_BUSID_EQUAL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -329,6 +327,23 @@ hwloc_pci_add_object(struct hwloc_obj *parent, struct hwloc_obj **parent_io_firs
|
|||
}
|
||||
return;
|
||||
}
|
||||
case HWLOC_PCI_BUSID_EQUAL: {
|
||||
static int reported = 0;
|
||||
if (!reported && !hwloc_hide_errors()) {
|
||||
fprintf(stderr, "*********************************************************\n");
|
||||
fprintf(stderr, "* hwloc %s received invalid PCI information.\n", HWLOC_VERSION);
|
||||
fprintf(stderr, "*\n");
|
||||
fprintf(stderr, "* Trying to insert PCI object %04x:%02x:%02x.%01x at %04x:%02x:%02x.%01x\n",
|
||||
new->attr->pcidev.domain, new->attr->pcidev.bus, new->attr->pcidev.dev, new->attr->pcidev.func,
|
||||
(*curp)->attr->pcidev.domain, (*curp)->attr->pcidev.bus, (*curp)->attr->pcidev.dev, (*curp)->attr->pcidev.func);
|
||||
fprintf(stderr, "*\n");
|
||||
fprintf(stderr, "* hwloc will now ignore this object and continue.\n");
|
||||
fprintf(stderr, "*********************************************************\n");
|
||||
reported = 1;
|
||||
}
|
||||
hwloc_free_unlinked_object(new);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* add to the end of the list if higher than everybody */
|
||||
|
@ -425,39 +440,10 @@ hwloc_pcidisc_add_hostbridges(struct hwloc_topology *topology,
|
|||
|
||||
static struct hwloc_obj *
|
||||
hwloc_pci_fixup_busid_parent(struct hwloc_topology *topology __hwloc_attribute_unused,
|
||||
struct hwloc_pcidev_attr_s *busid,
|
||||
struct hwloc_obj *parent)
|
||||
struct hwloc_pcidev_attr_s *busid __hwloc_attribute_unused,
|
||||
struct hwloc_obj *parent __hwloc_attribute_unused)
|
||||
{
|
||||
/* Xeon E5v3 in cluster-on-die mode only have PCI on the first NUMA node of each package.
|
||||
* but many dual-processor host report the second PCI hierarchy on 2nd NUMA of first package.
|
||||
*/
|
||||
if (parent->depth >= 2
|
||||
&& parent->type == HWLOC_OBJ_NUMANODE
|
||||
&& parent->sibling_rank == 1 && parent->parent->arity == 2
|
||||
&& parent->parent->type == HWLOC_OBJ_PACKAGE
|
||||
&& parent->parent->sibling_rank == 0 && parent->parent->parent->arity == 2) {
|
||||
const char *cpumodel = hwloc_obj_get_info_by_name(parent->parent, "CPUModel");
|
||||
if (cpumodel && strstr(cpumodel, "Xeon")) {
|
||||
if (!hwloc_hide_errors()) {
|
||||
fprintf(stderr, "****************************************************************************\n");
|
||||
fprintf(stderr, "* hwloc %s has encountered an incorrect PCI locality information.\n", HWLOC_VERSION);
|
||||
fprintf(stderr, "* PCI bus %04x:%02x is supposedly close to 2nd NUMA node of 1st package,\n",
|
||||
busid->domain, busid->bus);
|
||||
fprintf(stderr, "* however hwloc believes this is impossible on this architecture.\n");
|
||||
fprintf(stderr, "* Therefore the PCI bus will be moved to 1st NUMA node of 2nd package.\n");
|
||||
fprintf(stderr, "*\n");
|
||||
fprintf(stderr, "* If you feel this fixup is wrong, disable it by setting in your environment\n");
|
||||
fprintf(stderr, "* HWLOC_PCI_%04x_%02x_LOCALCPUS= (empty value), and report the problem\n",
|
||||
busid->domain, busid->bus);
|
||||
fprintf(stderr, "* to the hwloc's user mailing list together with the XML output of lstopo.\n");
|
||||
fprintf(stderr, "*\n");
|
||||
fprintf(stderr, "* You may silence this message by setting HWLOC_HIDE_ERRORS=1 in your environment.\n");
|
||||
fprintf(stderr, "****************************************************************************\n");
|
||||
}
|
||||
return parent->parent->next_sibling->first_child;
|
||||
}
|
||||
}
|
||||
|
||||
/* no quirk for now */
|
||||
return parent;
|
||||
}
|
||||
|
||||
|
|
12
src/3rdparty/hwloc/src/shmem.c
vendored
12
src/3rdparty/hwloc/src/shmem.c
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2017-2019 Inria. All rights reserved.
|
||||
* Copyright © 2017-2020 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
|
@ -97,6 +97,7 @@ hwloc_shmem_topology_write(hwloc_topology_t topology,
|
|||
* without being able to free() them.
|
||||
*/
|
||||
hwloc_internal_distances_refresh(topology);
|
||||
hwloc_internal_memattrs_refresh(topology);
|
||||
|
||||
header.header_version = HWLOC_SHMEM_HEADER_VERSION;
|
||||
header.header_length = sizeof(header);
|
||||
|
@ -134,8 +135,9 @@ hwloc_shmem_topology_write(hwloc_topology_t topology,
|
|||
|
||||
assert((char *)mmap_res <= (char *)mmap_address + length);
|
||||
|
||||
/* now refresh the new distances so that adopters can use them without refreshing the R/O shmem mapping */
|
||||
/* now refresh the new distances/memattrs so that adopters can use them without refreshing the R/O shmem mapping */
|
||||
hwloc_internal_distances_refresh(new);
|
||||
hwloc_internal_memattrs_refresh(topology);
|
||||
|
||||
/* topology is saved, release resources now */
|
||||
munmap(mmap_address, length);
|
||||
|
@ -214,11 +216,13 @@ hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp,
|
|||
new->support.discovery = malloc(sizeof(*new->support.discovery));
|
||||
new->support.cpubind = malloc(sizeof(*new->support.cpubind));
|
||||
new->support.membind = malloc(sizeof(*new->support.membind));
|
||||
if (!new->support.discovery || !new->support.cpubind || !new->support.membind)
|
||||
new->support.misc = malloc(sizeof(*new->support.misc));
|
||||
if (!new->support.discovery || !new->support.cpubind || !new->support.membind || !new->support.misc)
|
||||
goto out_with_support;
|
||||
memcpy(new->support.discovery, old->support.discovery, sizeof(*new->support.discovery));
|
||||
memcpy(new->support.cpubind, old->support.cpubind, sizeof(*new->support.cpubind));
|
||||
memcpy(new->support.membind, old->support.membind, sizeof(*new->support.membind));
|
||||
memcpy(new->support.misc, old->support.misc, sizeof(*new->support.misc));
|
||||
hwloc_set_binding_hooks(new);
|
||||
/* clear userdata callbacks pointing to the writer process' functions */
|
||||
new->userdata_export_cb = NULL;
|
||||
|
@ -236,6 +240,7 @@ hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp,
|
|||
free(new->support.discovery);
|
||||
free(new->support.cpubind);
|
||||
free(new->support.membind);
|
||||
free(new->support.misc);
|
||||
free(new);
|
||||
out_with_components:
|
||||
hwloc_components_fini();
|
||||
|
@ -252,6 +257,7 @@ hwloc__topology_disadopt(hwloc_topology_t topology)
|
|||
free(topology->support.discovery);
|
||||
free(topology->support.cpubind);
|
||||
free(topology->support.membind);
|
||||
free(topology->support.misc);
|
||||
free(topology);
|
||||
}
|
||||
|
||||
|
|
7
src/3rdparty/hwloc/src/static-components.h
vendored
7
src/3rdparty/hwloc/src/static-components.h
vendored
|
@ -1,9 +1,4 @@
|
|||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_noos_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_synthetic_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_nolibxml_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_windows_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_x86_component;
|
||||
#include <private/internal-components.h>
|
||||
static const struct hwloc_component * hwloc_static_components[] = {
|
||||
&hwloc_noos_component,
|
||||
&hwloc_xml_component,
|
||||
|
|
8
src/3rdparty/hwloc/src/topology-synthetic.c
vendored
8
src/3rdparty/hwloc/src/topology-synthetic.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2019 Inria. All rights reserved.
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009-2010 Université Bordeaux
|
||||
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
|
@ -471,7 +471,7 @@ hwloc_backend_synthetic_init(struct hwloc_synthetic_backend_data_s *data,
|
|||
/* initialize parent arity to 0 so that the levels are not infinite */
|
||||
data->level[count-1].arity = 0;
|
||||
|
||||
while (*pos == ' ')
|
||||
while (*pos == ' ' || *pos == '\n')
|
||||
pos++;
|
||||
|
||||
if (!*pos)
|
||||
|
@ -912,7 +912,7 @@ hwloc_synthetic_insert_attached(struct hwloc_topology *topology,
|
|||
|
||||
hwloc_synthetic_set_attr(&attached->attr, child);
|
||||
|
||||
hwloc_insert_object_by_cpuset(topology, child);
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, child, "synthetic:attached");
|
||||
|
||||
hwloc_synthetic_insert_attached(topology, data, attached->next, set);
|
||||
}
|
||||
|
@ -964,7 +964,7 @@ hwloc__look_synthetic(struct hwloc_topology *topology,
|
|||
|
||||
hwloc_synthetic_set_attr(&curlevel->attr, obj);
|
||||
|
||||
hwloc_insert_object_by_cpuset(topology, obj);
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, obj, "synthetic");
|
||||
}
|
||||
|
||||
hwloc_synthetic_insert_attached(topology, data, curlevel->attached, set);
|
||||
|
|
208
src/3rdparty/hwloc/src/topology-windows.c
vendored
208
src/3rdparty/hwloc/src/topology-windows.c
vendored
|
@ -93,9 +93,10 @@ typedef struct _GROUP_AFFINITY {
|
|||
#endif
|
||||
|
||||
#ifndef HAVE_PROCESSOR_RELATIONSHIP
|
||||
typedef struct _PROCESSOR_RELATIONSHIP {
|
||||
typedef struct HWLOC_PROCESSOR_RELATIONSHIP {
|
||||
BYTE Flags;
|
||||
BYTE Reserved[21];
|
||||
BYTE EfficiencyClass; /* for RelationProcessorCore, higher means greater performance but less efficiency, only available in Win10+ */
|
||||
BYTE Reserved[20];
|
||||
WORD GroupCount;
|
||||
GROUP_AFFINITY GroupMask[ANYSIZE_ARRAY];
|
||||
} PROCESSOR_RELATIONSHIP, *PPROCESSOR_RELATIONSHIP;
|
||||
|
@ -228,9 +229,12 @@ static PFN_VIRTUALFREEEX VirtualFreeExProc;
|
|||
typedef BOOL (WINAPI *PFN_QUERYWORKINGSETEX)(HANDLE hProcess, PVOID pv, DWORD cb);
|
||||
static PFN_QUERYWORKINGSETEX QueryWorkingSetExProc;
|
||||
|
||||
typedef NTSTATUS (WINAPI *PFN_RTLGETVERSION)(OSVERSIONINFOEX*);
|
||||
PFN_RTLGETVERSION RtlGetVersionProc;
|
||||
|
||||
static void hwloc_win_get_function_ptrs(void)
|
||||
{
|
||||
HMODULE kernel32;
|
||||
HMODULE kernel32, ntdll;
|
||||
|
||||
#if HWLOC_HAVE_GCC_W_CAST_FUNCTION_TYPE
|
||||
#pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
|
@ -275,6 +279,9 @@ static void hwloc_win_get_function_ptrs(void)
|
|||
QueryWorkingSetExProc = (PFN_QUERYWORKINGSETEX) GetProcAddress(psapi, "QueryWorkingSetEx");
|
||||
}
|
||||
|
||||
ntdll = GetModuleHandle("ntdll");
|
||||
RtlGetVersionProc = (PFN_RTLGETVERSION) GetProcAddress(ntdll, "RtlGetVersion");
|
||||
|
||||
#if HWLOC_HAVE_GCC_W_CAST_FUNCTION_TYPE
|
||||
#pragma GCC diagnostic warning "-Wcast-function-type"
|
||||
#endif
|
||||
|
@ -734,6 +741,88 @@ hwloc_win_get_area_memlocation(hwloc_topology_t topology __hwloc_attribute_unuse
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*************************
|
||||
* Efficiency classes
|
||||
*/
|
||||
|
||||
struct hwloc_win_efficiency_classes {
|
||||
unsigned nr_classes;
|
||||
unsigned nr_classes_allocated;
|
||||
struct hwloc_win_efficiency_class {
|
||||
unsigned value;
|
||||
hwloc_bitmap_t cpuset;
|
||||
} *classes;
|
||||
};
|
||||
|
||||
static void
|
||||
hwloc_win_efficiency_classes_init(struct hwloc_win_efficiency_classes *classes)
|
||||
{
|
||||
classes->classes = NULL;
|
||||
classes->nr_classes_allocated = 0;
|
||||
classes->nr_classes = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_win_efficiency_classes_add(struct hwloc_win_efficiency_classes *classes,
|
||||
hwloc_const_bitmap_t cpuset,
|
||||
unsigned value)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* look for existing class with that efficiency value */
|
||||
for(i=0; i<classes->nr_classes; i++) {
|
||||
if (classes->classes[i].value == value) {
|
||||
hwloc_bitmap_or(classes->classes[i].cpuset, classes->classes[i].cpuset, cpuset);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* extend the array if needed */
|
||||
if (classes->nr_classes == classes->nr_classes_allocated) {
|
||||
struct hwloc_win_efficiency_class *tmp;
|
||||
unsigned new_nr_allocated = 2*classes->nr_classes_allocated;
|
||||
if (!new_nr_allocated) {
|
||||
#define HWLOC_WIN_EFFICIENCY_CLASSES_DEFAULT_MAX 4 /* 2 should be enough is most cases */
|
||||
new_nr_allocated = HWLOC_WIN_EFFICIENCY_CLASSES_DEFAULT_MAX;
|
||||
}
|
||||
tmp = realloc(classes->classes, new_nr_allocated * sizeof(*classes->classes));
|
||||
if (!tmp)
|
||||
return -1;
|
||||
classes->classes = tmp;
|
||||
classes->nr_classes_allocated = new_nr_allocated;
|
||||
}
|
||||
|
||||
/* add new class */
|
||||
classes->classes[classes->nr_classes].cpuset = hwloc_bitmap_alloc();
|
||||
if (!classes->classes[classes->nr_classes].cpuset)
|
||||
return -1;
|
||||
classes->classes[classes->nr_classes].value = value;
|
||||
hwloc_bitmap_copy(classes->classes[classes->nr_classes].cpuset, cpuset);
|
||||
classes->nr_classes++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
hwloc_win_efficiency_classes_register(hwloc_topology_t topology,
|
||||
struct hwloc_win_efficiency_classes *classes)
|
||||
{
|
||||
unsigned i;
|
||||
for(i=0; i<classes->nr_classes; i++) {
|
||||
hwloc_internal_cpukinds_register(topology, classes->classes[i].cpuset, classes->classes[i].value, NULL, 0, 0);
|
||||
classes->classes[i].cpuset = NULL; /* given to cpukinds */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hwloc_win_efficiency_classes_destroy(struct hwloc_win_efficiency_classes *classes)
|
||||
{
|
||||
unsigned i;
|
||||
for(i=0; i<classes->nr_classes; i++)
|
||||
hwloc_bitmap_free(classes->classes[i].cpuset);
|
||||
free(classes->classes);
|
||||
}
|
||||
|
||||
/*************************
|
||||
* discovery
|
||||
*/
|
||||
|
@ -753,6 +842,12 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
|
|||
DWORD length;
|
||||
int gotnuma = 0;
|
||||
int gotnumamemory = 0;
|
||||
OSVERSIONINFOEX osvi;
|
||||
char versionstr[20];
|
||||
char hostname[122] = "";
|
||||
unsigned hostname_size = sizeof(hostname);
|
||||
int has_efficiencyclass = 0;
|
||||
struct hwloc_win_efficiency_classes eclasses;
|
||||
|
||||
assert(dstatus->phase == HWLOC_DISC_PHASE_CPU);
|
||||
|
||||
|
@ -760,6 +855,25 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
|
|||
/* somebody discovered things */
|
||||
return -1;
|
||||
|
||||
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
|
||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||
|
||||
if (RtlGetVersionProc) {
|
||||
/* RtlGetVersion() returns the currently-running Windows version */
|
||||
RtlGetVersionProc(&osvi);
|
||||
} else {
|
||||
/* GetVersionEx() and isWindows10OrGreater() depend on what the manifest says
|
||||
* (manifest of the program, not of libhwloc.dll), they may return old versions
|
||||
* if the currently-running Windows is not listed in the manifest.
|
||||
*/
|
||||
GetVersionEx((LPOSVERSIONINFO)&osvi);
|
||||
}
|
||||
|
||||
if (osvi.dwMajorVersion >= 10) {
|
||||
has_efficiencyclass = 1;
|
||||
hwloc_win_efficiency_classes_init(&eclasses);
|
||||
}
|
||||
|
||||
hwloc_alloc_root_sets(topology->levels[0][0]);
|
||||
|
||||
GetSystemInfo(&SystemInfo);
|
||||
|
@ -887,7 +1001,7 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
|
|||
default:
|
||||
break;
|
||||
}
|
||||
hwloc_insert_object_by_cpuset(topology, obj);
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, obj, "windows:GetLogicalProcessorInformation");
|
||||
}
|
||||
|
||||
free(procInfo);
|
||||
|
@ -919,6 +1033,7 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
|
|||
(void*) procInfo < (void*) ((uintptr_t) procInfoTotal + length);
|
||||
procInfo = (void*) ((uintptr_t) procInfo + procInfo->Size)) {
|
||||
unsigned num, i;
|
||||
unsigned efficiency_class = 0;
|
||||
GROUP_AFFINITY *GroupMask;
|
||||
|
||||
/* Ignore unknown caches */
|
||||
|
@ -953,6 +1068,11 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
|
|||
type = HWLOC_OBJ_CORE;
|
||||
num = procInfo->Processor.GroupCount;
|
||||
GroupMask = procInfo->Processor.GroupMask;
|
||||
if (has_efficiencyclass)
|
||||
/* the EfficiencyClass field didn't exist before Windows10 and recent MSVC headers,
|
||||
* so just access it manually instead of trying to detect it.
|
||||
*/
|
||||
efficiency_class = * ((&procInfo->Processor.Flags) + 1);
|
||||
break;
|
||||
case RelationGroup:
|
||||
/* So strange an interface... */
|
||||
|
@ -981,7 +1101,7 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
|
|||
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_GROUP, id);
|
||||
obj->cpuset = set;
|
||||
obj->attr->group.kind = HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP;
|
||||
hwloc_insert_object_by_cpuset(topology, obj);
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, obj, "windows:GetLogicalProcessorInformation:ProcessorGroup");
|
||||
} else
|
||||
hwloc_bitmap_free(set);
|
||||
}
|
||||
|
@ -1005,6 +1125,11 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
|
|||
}
|
||||
hwloc_debug_2args_bitmap("%s#%u bitmap %s\n", hwloc_obj_type_string(type), id, obj->cpuset);
|
||||
switch (type) {
|
||||
case HWLOC_OBJ_CORE: {
|
||||
if (has_efficiencyclass)
|
||||
hwloc_win_efficiency_classes_add(&eclasses, obj->cpuset, efficiency_class);
|
||||
break;
|
||||
}
|
||||
case HWLOC_OBJ_NUMANODE:
|
||||
{
|
||||
ULONGLONG avail;
|
||||
|
@ -1055,7 +1180,7 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
|
|||
default:
|
||||
break;
|
||||
}
|
||||
hwloc_insert_object_by_cpuset(topology, obj);
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, obj, "windows:GetLogicalProcessorInformationEx");
|
||||
}
|
||||
free(procInfoTotal);
|
||||
}
|
||||
|
@ -1076,29 +1201,88 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
|
|||
hwloc_bitmap_only(obj->cpuset, idx);
|
||||
hwloc_debug_1arg_bitmap("cpu %u has cpuset %s\n",
|
||||
idx, obj->cpuset);
|
||||
hwloc_insert_object_by_cpuset(topology, obj);
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, obj, "windows:ProcessorGroup:pu");
|
||||
} hwloc_bitmap_foreach_end();
|
||||
hwloc_bitmap_free(groups_pu_set);
|
||||
} else {
|
||||
/* no processor groups */
|
||||
SYSTEM_INFO sysinfo;
|
||||
hwloc_obj_t obj;
|
||||
unsigned idx;
|
||||
GetSystemInfo(&sysinfo);
|
||||
for(idx=0; idx<32; idx++)
|
||||
if (sysinfo.dwActiveProcessorMask & (((DWORD_PTR)1)<<idx)) {
|
||||
if (SystemInfo.dwActiveProcessorMask & (((DWORD_PTR)1)<<idx)) {
|
||||
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_PU, idx);
|
||||
obj->cpuset = hwloc_bitmap_alloc();
|
||||
hwloc_bitmap_only(obj->cpuset, idx);
|
||||
hwloc_debug_1arg_bitmap("cpu %u has cpuset %s\n",
|
||||
idx, obj->cpuset);
|
||||
hwloc_insert_object_by_cpuset(topology, obj);
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, obj, "windows:pu");
|
||||
}
|
||||
}
|
||||
|
||||
if (has_efficiencyclass) {
|
||||
topology->support.discovery->cpukind_efficiency = 1;
|
||||
hwloc_win_efficiency_classes_register(topology, &eclasses);
|
||||
}
|
||||
|
||||
out:
|
||||
if (has_efficiencyclass)
|
||||
hwloc_win_efficiency_classes_destroy(&eclasses);
|
||||
|
||||
/* emulate uname instead of calling hwloc_add_uname_info() */
|
||||
hwloc_obj_add_info(topology->levels[0][0], "Backend", "Windows");
|
||||
hwloc_add_uname_info(topology, NULL);
|
||||
hwloc_obj_add_info(topology->levels[0][0], "OSName", "Windows");
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
hwloc_obj_add_info(topology->levels[0][0], "WindowsBuildEnvironment", "Cygwin");
|
||||
#elif defined(__MINGW32__)
|
||||
hwloc_obj_add_info(topology->levels[0][0], "WindowsBuildEnvironment", "MinGW");
|
||||
#endif
|
||||
|
||||
/* see https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexa */
|
||||
if (osvi.dwMajorVersion == 10) {
|
||||
if (osvi.dwMinorVersion == 0)
|
||||
hwloc_obj_add_info(topology->levels[0][0], "OSRelease", "10");
|
||||
} else if (osvi.dwMajorVersion == 6) {
|
||||
if (osvi.dwMinorVersion == 3)
|
||||
hwloc_obj_add_info(topology->levels[0][0], "OSRelease", "8.1"); /* or "Server 2012 R2" */
|
||||
else if (osvi.dwMinorVersion == 2)
|
||||
hwloc_obj_add_info(topology->levels[0][0], "OSRelease", "8"); /* or "Server 2012" */
|
||||
else if (osvi.dwMinorVersion == 1)
|
||||
hwloc_obj_add_info(topology->levels[0][0], "OSRelease", "7"); /* or "Server 2008 R2" */
|
||||
else if (osvi.dwMinorVersion == 0)
|
||||
hwloc_obj_add_info(topology->levels[0][0], "OSRelease", "Vista"); /* or "Server 2008" */
|
||||
} /* earlier versions are ignored */
|
||||
|
||||
snprintf(versionstr, sizeof(versionstr), "%u.%u.%u", osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber);
|
||||
hwloc_obj_add_info(topology->levels[0][0], "OSVersion", versionstr);
|
||||
|
||||
#if !defined(__CYGWIN__)
|
||||
GetComputerName(hostname, &hostname_size);
|
||||
#else
|
||||
gethostname(hostname, hostname_size);
|
||||
#endif
|
||||
if (*hostname)
|
||||
hwloc_obj_add_info(topology->levels[0][0], "Hostname", hostname);
|
||||
|
||||
/* convert to unix-like architecture strings */
|
||||
switch (SystemInfo.wProcessorArchitecture) {
|
||||
case 0:
|
||||
hwloc_obj_add_info(topology->levels[0][0], "Architecture", "i686");
|
||||
break;
|
||||
case 9:
|
||||
hwloc_obj_add_info(topology->levels[0][0], "Architecture", "x86_64");
|
||||
break;
|
||||
case 5:
|
||||
hwloc_obj_add_info(topology->levels[0][0], "Architecture", "arm");
|
||||
break;
|
||||
case 12:
|
||||
hwloc_obj_add_info(topology->levels[0][0], "Architecture", "arm64");
|
||||
break;
|
||||
case 6:
|
||||
hwloc_obj_add_info(topology->levels[0][0], "Architecture", "ia64");
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
80
src/3rdparty/hwloc/src/topology-x86.c
vendored
80
src/3rdparty/hwloc/src/topology-x86.c
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2010-2019 Inria. All rights reserved.
|
||||
* Copyright © 2010-2020 Inria. All rights reserved.
|
||||
* Copyright © 2010-2013 Université Bordeaux
|
||||
* Copyright © 2010-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
|
@ -181,6 +181,7 @@ enum hwloc_x86_disc_flags {
|
|||
|
||||
#define has_topoext(features) ((features)[6] & (1 << 22))
|
||||
#define has_x2apic(features) ((features)[4] & (1 << 21))
|
||||
#define has_hybrid(features) ((features)[18] & (1 << 15))
|
||||
|
||||
struct cacheinfo {
|
||||
hwloc_obj_cache_type_t type;
|
||||
|
@ -217,6 +218,9 @@ struct procinfo {
|
|||
unsigned cpustepping;
|
||||
unsigned cpumodelnumber;
|
||||
unsigned cpufamilynumber;
|
||||
|
||||
unsigned hybridcoretype;
|
||||
unsigned hybridnativemodel;
|
||||
};
|
||||
|
||||
enum cpuid_type {
|
||||
|
@ -681,6 +685,15 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
|
|||
}
|
||||
}
|
||||
|
||||
if (highest_cpuid >= 0x1a && has_hybrid(features)) {
|
||||
/* Get hybrid cpu information from cpuid 0x1a */
|
||||
eax = 0x1a;
|
||||
ecx = 0;
|
||||
cpuid_or_from_dump(&eax, &ebx, &ecx, &edx, src_cpuiddump);
|
||||
infos->hybridcoretype = eax >> 24;
|
||||
infos->hybridnativemodel = eax & 0xffffff;
|
||||
}
|
||||
|
||||
/*********************************************************************************
|
||||
* Get the hierarchy of thread, core, die, package, etc. from CPU-specific leaves
|
||||
*/
|
||||
|
@ -751,7 +764,13 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
|
|||
/* default cacheid value */
|
||||
cache->cacheid = infos->apicid / cache->nbthreads_sharing;
|
||||
|
||||
if (cpuid_type == amd) {
|
||||
if (cpuid_type == intel) {
|
||||
/* round nbthreads_sharing to nearest power of two to build a mask (for clearing lower bits) */
|
||||
unsigned bits = hwloc_flsl(cache->nbthreads_sharing-1);
|
||||
unsigned mask = ~((1U<<bits) - 1);
|
||||
cache->cacheid = infos->apicid & mask;
|
||||
|
||||
} else if (cpuid_type == amd) {
|
||||
/* AMD quirks */
|
||||
if (infos->cpufamilynumber == 0x17
|
||||
&& cache->level == 3 && cache->nbthreads_sharing == 6) {
|
||||
|
@ -872,7 +891,7 @@ hwloc_x86_add_groups(hwloc_topology_t topology,
|
|||
obj->attr->group.dont_merge = dont_merge;
|
||||
hwloc_debug_2args_bitmap("os %s %u has cpuset %s\n",
|
||||
subtype, id, obj_cpuset);
|
||||
hwloc_insert_object_by_cpuset(topology, obj);
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, obj, "x86:group");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -930,7 +949,7 @@ static void summarize(struct hwloc_backend *backend, struct procinfo *infos, uns
|
|||
|
||||
hwloc_debug_1arg_bitmap("os package %u has cpuset %s\n",
|
||||
packageid, package_cpuset);
|
||||
hwloc_insert_object_by_cpuset(topology, package);
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, package, "x86:package");
|
||||
|
||||
} else {
|
||||
/* Annotate packages previously-existing packages */
|
||||
|
@ -986,7 +1005,7 @@ static void summarize(struct hwloc_backend *backend, struct procinfo *infos, uns
|
|||
hwloc_bitmap_set(node->nodeset, nodeid);
|
||||
hwloc_debug_1arg_bitmap("os node %u has cpuset %s\n",
|
||||
nodeid, node_cpuset);
|
||||
hwloc_insert_object_by_cpuset(topology, node);
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, node, "x86:numa");
|
||||
gotnuma++;
|
||||
}
|
||||
}
|
||||
|
@ -1033,7 +1052,7 @@ static void summarize(struct hwloc_backend *backend, struct procinfo *infos, uns
|
|||
unknown_obj->attr->group.subkind = level;
|
||||
hwloc_debug_2args_bitmap("os unknown%u %u has cpuset %s\n",
|
||||
level, unknownid, unknown_cpuset);
|
||||
hwloc_insert_object_by_cpuset(topology, unknown_obj);
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, unknown_obj, "x86:group:unknown");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1073,7 +1092,7 @@ static void summarize(struct hwloc_backend *backend, struct procinfo *infos, uns
|
|||
die->cpuset = die_cpuset;
|
||||
hwloc_debug_1arg_bitmap("os die %u has cpuset %s\n",
|
||||
dieid, die_cpuset);
|
||||
hwloc_insert_object_by_cpuset(topology, die);
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, die, "x86:die");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1111,7 +1130,7 @@ static void summarize(struct hwloc_backend *backend, struct procinfo *infos, uns
|
|||
core->cpuset = core_cpuset;
|
||||
hwloc_debug_1arg_bitmap("os core %u has cpuset %s\n",
|
||||
coreid, core_cpuset);
|
||||
hwloc_insert_object_by_cpuset(topology, core);
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, core, "x86:core");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1125,7 +1144,7 @@ static void summarize(struct hwloc_backend *backend, struct procinfo *infos, uns
|
|||
obj->cpuset = hwloc_bitmap_alloc();
|
||||
hwloc_bitmap_only(obj->cpuset, i);
|
||||
hwloc_debug_1arg_bitmap("PU %u has cpuset %s\n", i, obj->cpuset);
|
||||
hwloc_insert_object_by_cpuset(topology, obj);
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, obj, "x86:pu");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1208,7 +1227,7 @@ static void summarize(struct hwloc_backend *backend, struct procinfo *infos, uns
|
|||
hwloc_obj_add_info(cache, "Inclusive", infos[i].cache[l].inclusive ? "1" : "0");
|
||||
hwloc_debug_2args_bitmap("os L%u cache %u has cpuset %s\n",
|
||||
level, cacheid, cache_cpuset);
|
||||
hwloc_insert_object_by_cpuset(topology, cache);
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, cache, "x86:cache");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1274,8 +1293,41 @@ look_procs(struct hwloc_backend *backend, struct procinfo *infos, unsigned long
|
|||
hwloc_bitmap_free(orig_cpuset);
|
||||
}
|
||||
|
||||
if (data->apicid_unique)
|
||||
if (data->apicid_unique) {
|
||||
summarize(backend, infos, flags);
|
||||
|
||||
if (has_hybrid(features)) {
|
||||
/* use hybrid info for cpukinds */
|
||||
hwloc_bitmap_t atomset = hwloc_bitmap_alloc();
|
||||
hwloc_bitmap_t coreset = hwloc_bitmap_alloc();
|
||||
for(i=0; i<nbprocs; i++) {
|
||||
if (infos[i].hybridcoretype == 0x20)
|
||||
hwloc_bitmap_set(atomset, i);
|
||||
else if (infos[i].hybridcoretype == 0x40)
|
||||
hwloc_bitmap_set(coreset, i);
|
||||
}
|
||||
/* register IntelAtom set if any */
|
||||
if (!hwloc_bitmap_iszero(atomset)) {
|
||||
struct hwloc_info_s infoattr;
|
||||
infoattr.name = (char *) "CoreType";
|
||||
infoattr.value = (char *) "IntelAtom";
|
||||
hwloc_internal_cpukinds_register(topology, atomset, HWLOC_CPUKIND_EFFICIENCY_UNKNOWN, &infoattr, 1, 0);
|
||||
/* the cpuset is given to the callee */
|
||||
} else {
|
||||
hwloc_bitmap_free(atomset);
|
||||
}
|
||||
/* register IntelCore set if any */
|
||||
if (!hwloc_bitmap_iszero(coreset)) {
|
||||
struct hwloc_info_s infoattr;
|
||||
infoattr.name = (char *) "CoreType";
|
||||
infoattr.value = (char *) "IntelCore";
|
||||
hwloc_internal_cpukinds_register(topology, coreset, HWLOC_CPUKIND_EFFICIENCY_UNKNOWN, &infoattr, 1, 0);
|
||||
/* the cpuset is given to the callee */
|
||||
} else {
|
||||
hwloc_bitmap_free(coreset);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* if !data->apicid_unique, do nothing and return success, so that the caller does nothing either */
|
||||
|
||||
return 0;
|
||||
|
@ -1354,7 +1406,7 @@ int hwloc_look_x86(struct hwloc_backend *backend, unsigned long flags)
|
|||
unsigned highest_cpuid;
|
||||
unsigned highest_ext_cpuid;
|
||||
/* This stores cpuid features with the same indexing as Linux */
|
||||
unsigned features[10] = { 0 };
|
||||
unsigned features[19] = { 0 };
|
||||
struct procinfo *infos = NULL;
|
||||
enum cpuid_type cpuid_type = unknown;
|
||||
hwloc_x86_os_state_t os_state;
|
||||
|
@ -1381,6 +1433,9 @@ int hwloc_look_x86(struct hwloc_backend *backend, unsigned long flags)
|
|||
/* check if binding works */
|
||||
memset(&hooks, 0, sizeof(hooks));
|
||||
support.membind = &memsupport;
|
||||
/* We could just copy the main hooks (except in some corner cases),
|
||||
* but the current overhead is negligible, so just always reget them.
|
||||
*/
|
||||
hwloc_set_native_binding_hooks(&hooks, &support);
|
||||
if (hooks.get_thisthread_cpubind && hooks.set_thisthread_cpubind) {
|
||||
get_cpubind = hooks.get_thisthread_cpubind;
|
||||
|
@ -1451,6 +1506,7 @@ int hwloc_look_x86(struct hwloc_backend *backend, unsigned long flags)
|
|||
ecx = 0;
|
||||
cpuid_or_from_dump(&eax, &ebx, &ecx, &edx, src_cpuiddump);
|
||||
features[9] = ebx;
|
||||
features[18] = edx;
|
||||
}
|
||||
|
||||
if (cpuid_type != intel && highest_ext_cpuid >= 0x80000001) {
|
||||
|
|
|
@ -213,7 +213,7 @@ hwloc__nolibxml_import_close_child(hwloc__xml_import_state_t state)
|
|||
|
||||
static int
|
||||
hwloc__nolibxml_import_get_content(hwloc__xml_import_state_t state,
|
||||
char **beginp, size_t expected_length)
|
||||
const char **beginp, size_t expected_length)
|
||||
{
|
||||
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
|
||||
char *buffer = nstate->tagbuffer;
|
||||
|
@ -224,7 +224,7 @@ hwloc__nolibxml_import_get_content(hwloc__xml_import_state_t state,
|
|||
if (nstate->closed) {
|
||||
if (expected_length)
|
||||
return -1;
|
||||
*beginp = (char *) "";
|
||||
*beginp = "";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
595
src/3rdparty/hwloc/src/topology-xml.c
vendored
595
src/3rdparty/hwloc/src/topology-xml.c
vendored
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009-2011 Université Bordeaux
|
||||
* Copyright © 2009-2011, 2020 Université Bordeaux
|
||||
* Copyright © 2009-2018 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
@ -481,11 +481,9 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
hwloc__xml_import_info(struct hwloc_xml_backend_data_s *data,
|
||||
hwloc_obj_t obj,
|
||||
hwloc__xml_import_state_t state)
|
||||
hwloc___xml_import_info(char **infonamep, char **infovaluep,
|
||||
hwloc__xml_import_state_t state)
|
||||
{
|
||||
char *infoname = NULL;
|
||||
char *infovalue = NULL;
|
||||
|
@ -502,6 +500,25 @@ hwloc__xml_import_info(struct hwloc_xml_backend_data_s *data,
|
|||
return -1;
|
||||
}
|
||||
|
||||
*infonamep = infoname;
|
||||
*infovaluep = infovalue;
|
||||
|
||||
return state->global->close_tag(state);
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc__xml_import_obj_info(struct hwloc_xml_backend_data_s *data,
|
||||
hwloc_obj_t obj,
|
||||
hwloc__xml_import_state_t state)
|
||||
{
|
||||
char *infoname = NULL;
|
||||
char *infovalue = NULL;
|
||||
int err;
|
||||
|
||||
err = hwloc___xml_import_info(&infoname, &infovalue, state);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (infoname) {
|
||||
/* empty strings are ignored by libxml */
|
||||
if (data->version_major < 2 &&
|
||||
|
@ -518,7 +535,7 @@ hwloc__xml_import_info(struct hwloc_xml_backend_data_s *data,
|
|||
}
|
||||
}
|
||||
|
||||
return state->global->close_tag(state);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -694,14 +711,15 @@ hwloc__xml_import_userdata(hwloc_topology_t topology __hwloc_attribute_unused, h
|
|||
}
|
||||
|
||||
if (!topology->userdata_import_cb) {
|
||||
char *buffer;
|
||||
const char *buffer;
|
||||
size_t reallength = encoded ? BASE64_ENCODED_LENGTH(length) : length;
|
||||
ret = state->global->get_content(state, &buffer, reallength);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
} else if (topology->userdata_not_decoded) {
|
||||
char *buffer, *fakename;
|
||||
const char *buffer;
|
||||
char *fakename;
|
||||
size_t reallength = encoded ? BASE64_ENCODED_LENGTH(length) : length;
|
||||
ret = state->global->get_content(state, &buffer, reallength);
|
||||
if (ret < 0)
|
||||
|
@ -714,7 +732,7 @@ hwloc__xml_import_userdata(hwloc_topology_t topology __hwloc_attribute_unused, h
|
|||
free(fakename);
|
||||
|
||||
} else if (encoded && length) {
|
||||
char *encoded_buffer;
|
||||
const char *encoded_buffer;
|
||||
size_t encoded_length = BASE64_ENCODED_LENGTH(length);
|
||||
ret = state->global->get_content(state, &encoded_buffer, encoded_length);
|
||||
if (ret < 0)
|
||||
|
@ -734,7 +752,7 @@ hwloc__xml_import_userdata(hwloc_topology_t topology __hwloc_attribute_unused, h
|
|||
}
|
||||
|
||||
} else { /* always handle length==0 in the non-encoded case */
|
||||
char *buffer = (char *) "";
|
||||
const char *buffer = "";
|
||||
if (length) {
|
||||
ret = state->global->get_content(state, &buffer, length);
|
||||
if (ret < 0)
|
||||
|
@ -888,7 +906,7 @@ hwloc__xml_import_object(hwloc_topology_t topology,
|
|||
}
|
||||
|
||||
} else if (!strcmp(tag, "info")) {
|
||||
ret = hwloc__xml_import_info(data, obj, &childstate);
|
||||
ret = hwloc__xml_import_obj_info(data, obj, &childstate);
|
||||
} else if (data->version_major < 2 && !strcmp(tag, "distances")) {
|
||||
ret = hwloc__xml_v1import_distances(data, obj, &childstate);
|
||||
} else if (!strcmp(tag, "userdata")) {
|
||||
|
@ -1238,6 +1256,80 @@ hwloc__xml_import_object(hwloc_topology_t topology,
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc__xml_v2import_support(hwloc_topology_t topology,
|
||||
hwloc__xml_import_state_t state)
|
||||
{
|
||||
char *name = NULL;
|
||||
int value = 1; /* value is optional */
|
||||
while (1) {
|
||||
char *attrname, *attrvalue;
|
||||
if (state->global->next_attr(state, &attrname, &attrvalue) < 0)
|
||||
break;
|
||||
if (!strcmp(attrname, "name"))
|
||||
name = attrvalue;
|
||||
else if (!strcmp(attrname, "value"))
|
||||
value = atoi(attrvalue);
|
||||
else {
|
||||
if (hwloc__xml_verbose())
|
||||
fprintf(stderr, "%s: ignoring unknown support attribute %s\n",
|
||||
state->global->msgprefix, attrname);
|
||||
}
|
||||
}
|
||||
|
||||
if (name && topology->flags & HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT) {
|
||||
#ifdef HWLOC_DEBUG
|
||||
HWLOC_BUILD_ASSERT(sizeof(struct hwloc_topology_support) == 4*sizeof(void*));
|
||||
HWLOC_BUILD_ASSERT(sizeof(struct hwloc_topology_discovery_support) == 6);
|
||||
HWLOC_BUILD_ASSERT(sizeof(struct hwloc_topology_cpubind_support) == 11);
|
||||
HWLOC_BUILD_ASSERT(sizeof(struct hwloc_topology_membind_support) == 15);
|
||||
HWLOC_BUILD_ASSERT(sizeof(struct hwloc_topology_misc_support) == 1);
|
||||
#endif
|
||||
|
||||
#define DO(_cat,_name) if (!strcmp(#_cat "." #_name, name)) topology->support._cat->_name = value
|
||||
DO(discovery,pu);
|
||||
else DO(discovery,numa);
|
||||
else DO(discovery,numa_memory);
|
||||
else DO(discovery,disallowed_pu);
|
||||
else DO(discovery,disallowed_numa);
|
||||
else DO(discovery,cpukind_efficiency);
|
||||
else DO(cpubind,set_thisproc_cpubind);
|
||||
else DO(cpubind,get_thisproc_cpubind);
|
||||
else DO(cpubind,set_proc_cpubind);
|
||||
else DO(cpubind,get_proc_cpubind);
|
||||
else DO(cpubind,set_thisthread_cpubind);
|
||||
else DO(cpubind,get_thisthread_cpubind);
|
||||
else DO(cpubind,set_thread_cpubind);
|
||||
else DO(cpubind,get_thread_cpubind);
|
||||
else DO(cpubind,get_thisproc_last_cpu_location);
|
||||
else DO(cpubind,get_proc_last_cpu_location);
|
||||
else DO(cpubind,get_thisthread_last_cpu_location);
|
||||
else DO(membind,set_thisproc_membind);
|
||||
else DO(membind,get_thisproc_membind);
|
||||
else DO(membind,set_proc_membind);
|
||||
else DO(membind,get_proc_membind);
|
||||
else DO(membind,set_thisthread_membind);
|
||||
else DO(membind,get_thisthread_membind);
|
||||
else DO(membind,set_area_membind);
|
||||
else DO(membind,get_area_membind);
|
||||
else DO(membind,alloc_membind);
|
||||
else DO(membind,firsttouch_membind);
|
||||
else DO(membind,bind_membind);
|
||||
else DO(membind,interleave_membind);
|
||||
else DO(membind,nexttouch_membind);
|
||||
else DO(membind,migrate_membind);
|
||||
else DO(membind,get_area_memlocation);
|
||||
|
||||
else if (!strcmp("custom.exported_support", name))
|
||||
/* support was exported in a custom/fake field, mark it as imported here */
|
||||
topology->support.misc->imported_support = 1;
|
||||
|
||||
#undef DO
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc__xml_v2import_distances(hwloc_topology_t topology,
|
||||
hwloc__xml_import_state_t state,
|
||||
|
@ -1317,7 +1409,8 @@ hwloc__xml_v2import_distances(hwloc_topology_t topology,
|
|||
nr_u64values = 0;
|
||||
while (1) {
|
||||
struct hwloc__xml_import_state_s childstate;
|
||||
char *attrname, *attrvalue, *tag, *buffer;
|
||||
char *attrname, *attrvalue, *tag;
|
||||
const char *buffer;
|
||||
int length;
|
||||
int is_index = 0;
|
||||
int is_u64values = 0;
|
||||
|
@ -1356,7 +1449,7 @@ hwloc__xml_v2import_distances(hwloc_topology_t topology,
|
|||
|
||||
if (is_index) {
|
||||
/* get indexes */
|
||||
char *tmp, *tmp2;
|
||||
const char *tmp, *tmp2;
|
||||
if (nr_indexes >= nbobjs) {
|
||||
if (hwloc__xml_verbose())
|
||||
fprintf(stderr, "%s: %s with more than %u indexes\n",
|
||||
|
@ -1398,7 +1491,7 @@ hwloc__xml_v2import_distances(hwloc_topology_t topology,
|
|||
|
||||
} else if (is_u64values) {
|
||||
/* get uint64_t values */
|
||||
char *tmp;
|
||||
const char *tmp;
|
||||
if (nr_u64values >= nbobjs*nbobjs) {
|
||||
if (hwloc__xml_verbose())
|
||||
fprintf(stderr, "%s: %s with more than %u u64values\n",
|
||||
|
@ -1491,6 +1584,259 @@ hwloc__xml_v2import_distances(hwloc_topology_t topology,
|
|||
#undef _TAG_NAME
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc__xml_import_memattr_value(hwloc_topology_t topology,
|
||||
hwloc_memattr_id_t id,
|
||||
unsigned long flags,
|
||||
hwloc__xml_import_state_t state)
|
||||
{
|
||||
char *target_obj_gp_index_s = NULL;
|
||||
char *target_obj_type_s = NULL;
|
||||
hwloc_uint64_t target_obj_gp_index;
|
||||
char *value_s = NULL;
|
||||
hwloc_uint64_t value;
|
||||
char *initiator_cpuset_s = NULL;
|
||||
char *initiator_obj_gp_index_s = NULL;
|
||||
char *initiator_obj_type_s = NULL;
|
||||
hwloc_obj_type_t target_obj_type = HWLOC_OBJ_TYPE_NONE;
|
||||
|
||||
while (1) {
|
||||
char *attrname, *attrvalue;
|
||||
if (state->global->next_attr(state, &attrname, &attrvalue) < 0)
|
||||
break;
|
||||
if (!strcmp(attrname, "target_obj_gp_index"))
|
||||
target_obj_gp_index_s = attrvalue;
|
||||
else if (!strcmp(attrname, "target_obj_type"))
|
||||
target_obj_type_s = attrvalue;
|
||||
else if (!strcmp(attrname, "value"))
|
||||
value_s = attrvalue;
|
||||
else if (!strcmp(attrname, "initiator_cpuset"))
|
||||
initiator_cpuset_s = attrvalue;
|
||||
else if (!strcmp(attrname, "initiator_obj_gp_index"))
|
||||
initiator_obj_gp_index_s = attrvalue;
|
||||
else if (!strcmp(attrname, "initiator_obj_type"))
|
||||
initiator_obj_type_s = attrvalue;
|
||||
else {
|
||||
if (hwloc__xml_verbose())
|
||||
fprintf(stderr, "%s: ignoring unknown memattr_value attribute %s\n",
|
||||
state->global->msgprefix, attrname);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!target_obj_type_s) {
|
||||
if (hwloc__xml_verbose())
|
||||
fprintf(stderr, "%s: ignoring memattr_value without target_obj_type.\n",
|
||||
state->global->msgprefix);
|
||||
return -1;
|
||||
}
|
||||
if (hwloc_type_sscanf(target_obj_type_s, &target_obj_type, NULL, 0) < 0) {
|
||||
if (hwloc__xml_verbose())
|
||||
fprintf(stderr, "%s: failed to identify memattr_value target object type %s\n",
|
||||
state->global->msgprefix, target_obj_type_s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!value_s || !target_obj_gp_index_s) {
|
||||
if (hwloc__xml_verbose())
|
||||
fprintf(stderr, "%s: ignoring memattr_value without value and target_obj_gp_index\n",
|
||||
state->global->msgprefix);
|
||||
return -1;
|
||||
}
|
||||
target_obj_gp_index = strtoull(target_obj_gp_index_s, NULL, 10);
|
||||
value = strtoull(value_s, NULL, 10);
|
||||
|
||||
if (flags & HWLOC_MEMATTR_FLAG_NEED_INITIATOR) {
|
||||
/* add a value with initiator */
|
||||
struct hwloc_internal_location_s loc;
|
||||
if (!initiator_cpuset_s && (!initiator_obj_gp_index_s || !initiator_obj_type_s)) {
|
||||
if (hwloc__xml_verbose())
|
||||
fprintf(stderr, "%s: ignoring memattr_value without initiator attributes\n",
|
||||
state->global->msgprefix);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* setup the initiator */
|
||||
if (initiator_cpuset_s) {
|
||||
loc.type = HWLOC_LOCATION_TYPE_CPUSET;
|
||||
loc.location.cpuset = hwloc_bitmap_alloc();
|
||||
if (!loc.location.cpuset) {
|
||||
if (hwloc__xml_verbose())
|
||||
fprintf(stderr, "%s: failed to allocated memattr_value initiator cpuset\n",
|
||||
state->global->msgprefix);
|
||||
return -1;
|
||||
}
|
||||
hwloc_bitmap_sscanf(loc.location.cpuset, initiator_cpuset_s);
|
||||
} else {
|
||||
loc.type = HWLOC_LOCATION_TYPE_OBJECT;
|
||||
loc.location.object.gp_index = strtoull(initiator_obj_gp_index_s, NULL, 10);
|
||||
if (hwloc_type_sscanf(initiator_obj_type_s, &loc.location.object.type, NULL, 0) < 0) {
|
||||
if (hwloc__xml_verbose())
|
||||
fprintf(stderr, "%s: failed to identify memattr_value initiator object type %s\n",
|
||||
state->global->msgprefix, initiator_obj_type_s);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
hwloc_internal_memattr_set_value(topology, id, target_obj_type, target_obj_gp_index, (unsigned)-1, &loc, value);
|
||||
|
||||
if (loc.type == HWLOC_LOCATION_TYPE_CPUSET)
|
||||
hwloc_bitmap_free(loc.location.cpuset);
|
||||
|
||||
} else {
|
||||
/* add a value without initiator */
|
||||
hwloc_internal_memattr_set_value(topology, id, target_obj_type, target_obj_gp_index, (unsigned)-1, NULL, value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc__xml_import_memattr(hwloc_topology_t topology,
|
||||
hwloc__xml_import_state_t state)
|
||||
{
|
||||
char *name = NULL;
|
||||
unsigned long flags = (unsigned long) -1;
|
||||
hwloc_memattr_id_t id = (hwloc_memattr_id_t) -1;
|
||||
int ret;
|
||||
|
||||
while (1) {
|
||||
char *attrname, *attrvalue;
|
||||
if (state->global->next_attr(state, &attrname, &attrvalue) < 0)
|
||||
break;
|
||||
if (!strcmp(attrname, "name"))
|
||||
name = attrvalue;
|
||||
else if (!strcmp(attrname, "flags"))
|
||||
flags = strtoul(attrvalue, NULL, 10);
|
||||
else {
|
||||
if (hwloc__xml_verbose())
|
||||
fprintf(stderr, "%s: ignoring unknown memattr attribute %s\n",
|
||||
state->global->msgprefix, attrname);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (name && flags != (unsigned long) -1) {
|
||||
hwloc_memattr_id_t _id;
|
||||
|
||||
ret = hwloc_memattr_get_by_name(topology, name, &_id);
|
||||
if (ret < 0) {
|
||||
/* register a new attribute */
|
||||
ret = hwloc_memattr_register(topology, name, flags, &_id);
|
||||
if (!ret)
|
||||
id = _id;
|
||||
} else {
|
||||
/* check the flags of the existing attribute */
|
||||
unsigned long mflags;
|
||||
ret = hwloc_memattr_get_flags(topology, _id, &mflags);
|
||||
if (!ret && mflags == flags)
|
||||
id = _id;
|
||||
}
|
||||
/* if there's no matching attribute, id is -1 and values will be ignored below */
|
||||
}
|
||||
|
||||
while (1) {
|
||||
struct hwloc__xml_import_state_s childstate;
|
||||
char *tag;
|
||||
|
||||
ret = state->global->find_child(state, &childstate, &tag);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
|
||||
if (!strcmp(tag, "memattr_value")) {
|
||||
ret = hwloc__xml_import_memattr_value(topology, id, flags, &childstate);
|
||||
} else {
|
||||
if (hwloc__xml_verbose())
|
||||
fprintf(stderr, "%s: memattr with unrecognized child %s\n",
|
||||
state->global->msgprefix, tag);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
state->global->close_child(&childstate);
|
||||
}
|
||||
|
||||
return state->global->close_tag(state);
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc__xml_import_cpukind(hwloc_topology_t topology,
|
||||
hwloc__xml_import_state_t state)
|
||||
{
|
||||
hwloc_bitmap_t cpuset = NULL;
|
||||
int forced_efficiency = HWLOC_CPUKIND_EFFICIENCY_UNKNOWN;
|
||||
unsigned nr_infos = 0;
|
||||
struct hwloc_info_s *infos = NULL;
|
||||
int ret;
|
||||
|
||||
while (1) {
|
||||
char *attrname, *attrvalue;
|
||||
if (state->global->next_attr(state, &attrname, &attrvalue) < 0)
|
||||
break;
|
||||
if (!strcmp(attrname, "cpuset")) {
|
||||
if (!cpuset)
|
||||
cpuset = hwloc_bitmap_alloc();
|
||||
hwloc_bitmap_sscanf(cpuset, attrvalue);
|
||||
} else if (!strcmp(attrname, "forced_efficiency")) {
|
||||
forced_efficiency = atoi(attrvalue);
|
||||
} else {
|
||||
if (hwloc__xml_verbose())
|
||||
fprintf(stderr, "%s: ignoring unknown cpukind attribute %s\n",
|
||||
state->global->msgprefix, attrname);
|
||||
hwloc_bitmap_free(cpuset);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
struct hwloc__xml_import_state_s childstate;
|
||||
char *tag;
|
||||
|
||||
ret = state->global->find_child(state, &childstate, &tag);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
|
||||
if (!strcmp(tag, "info")) {
|
||||
char *infoname = NULL;
|
||||
char *infovalue = NULL;
|
||||
ret = hwloc___xml_import_info(&infoname, &infovalue, &childstate);
|
||||
if (!ret && infoname && infovalue)
|
||||
hwloc__add_info(&infos, &nr_infos, infoname, infovalue);
|
||||
} else {
|
||||
if (hwloc__xml_verbose())
|
||||
fprintf(stderr, "%s: cpukind with unrecognized child %s\n",
|
||||
state->global->msgprefix, tag);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
state->global->close_child(&childstate);
|
||||
}
|
||||
|
||||
if (!cpuset) {
|
||||
if (hwloc__xml_verbose())
|
||||
fprintf(stderr, "%s: ignoring cpukind without cpuset\n",
|
||||
state->global->msgprefix);
|
||||
goto error;
|
||||
}
|
||||
|
||||
hwloc_internal_cpukinds_register(topology, cpuset, forced_efficiency, infos, nr_infos, HWLOC_CPUKINDS_REGISTER_FLAG_OVERWRITE_FORCED_EFFICIENCY);
|
||||
|
||||
return state->global->close_tag(state);
|
||||
|
||||
error:
|
||||
hwloc__free_infos(infos, nr_infos);
|
||||
hwloc_bitmap_free(cpuset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc__xml_import_diff_one(hwloc__xml_import_state_t state,
|
||||
hwloc_topology_diff_t *firstdiffp,
|
||||
|
@ -1759,6 +2105,18 @@ hwloc_look_xml(struct hwloc_backend *backend, struct hwloc_disc_status *dstatus)
|
|||
ret = hwloc__xml_v2import_distances(topology, &childstate, 1);
|
||||
if (ret < 0)
|
||||
goto failed;
|
||||
} else if (!strcmp(tag, "support")) {
|
||||
ret = hwloc__xml_v2import_support(topology, &childstate);
|
||||
if (ret < 0)
|
||||
goto failed;
|
||||
} else if (!strcmp(tag, "memattr")) {
|
||||
ret = hwloc__xml_import_memattr(topology, &childstate);
|
||||
if (ret < 0)
|
||||
goto failed;
|
||||
} else if (!strcmp(tag, "cpukind")) {
|
||||
ret = hwloc__xml_import_cpukind(topology, &childstate);
|
||||
if (ret < 0)
|
||||
goto failed;
|
||||
} else {
|
||||
if (hwloc__xml_verbose())
|
||||
fprintf(stderr, "%s: ignoring unknown tag `%s' after root object.\n",
|
||||
|
@ -1864,12 +2222,14 @@ done:
|
|||
/* keep the "Backend" information intact */
|
||||
/* we could add "BackendSource=XML" to notify that XML was used between the actual backend and here */
|
||||
|
||||
topology->support.discovery->pu = 1;
|
||||
topology->support.discovery->disallowed_pu = 1;
|
||||
if (data->nbnumanodes) {
|
||||
topology->support.discovery->numa = 1;
|
||||
topology->support.discovery->numa_memory = 1; // FIXME
|
||||
topology->support.discovery->disallowed_numa = 1;
|
||||
if (!(topology->flags & HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT)) {
|
||||
topology->support.discovery->pu = 1;
|
||||
topology->support.discovery->disallowed_pu = 1;
|
||||
if (data->nbnumanodes) {
|
||||
topology->support.discovery->numa = 1;
|
||||
topology->support.discovery->numa_memory = 1; // FIXME
|
||||
topology->support.discovery->disallowed_numa = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (data->look_done)
|
||||
|
@ -2620,9 +2980,199 @@ hwloc__xml_v2export_distances(hwloc__xml_export_state_t parentstate, hwloc_topol
|
|||
hwloc___xml_v2export_distances(parentstate, dist);
|
||||
}
|
||||
|
||||
static void
|
||||
hwloc__xml_v2export_support(hwloc__xml_export_state_t parentstate, hwloc_topology_t topology)
|
||||
{
|
||||
struct hwloc__xml_export_state_s state;
|
||||
char tmp[11];
|
||||
|
||||
#ifdef HWLOC_DEBUG
|
||||
HWLOC_BUILD_ASSERT(sizeof(struct hwloc_topology_support) == 4*sizeof(void*));
|
||||
HWLOC_BUILD_ASSERT(sizeof(struct hwloc_topology_discovery_support) == 6);
|
||||
HWLOC_BUILD_ASSERT(sizeof(struct hwloc_topology_cpubind_support) == 11);
|
||||
HWLOC_BUILD_ASSERT(sizeof(struct hwloc_topology_membind_support) == 15);
|
||||
HWLOC_BUILD_ASSERT(sizeof(struct hwloc_topology_misc_support) == 1);
|
||||
#endif
|
||||
|
||||
#define DO(_cat,_name) do { \
|
||||
if (topology->support._cat->_name) { \
|
||||
parentstate->new_child(parentstate, &state, "support"); \
|
||||
state.new_prop(&state, "name", #_cat "." #_name); \
|
||||
if (topology->support._cat->_name != 1) { \
|
||||
sprintf(tmp, "%u", topology->support._cat->_name); \
|
||||
state.new_prop(&state, "value", tmp); \
|
||||
} \
|
||||
state.end_object(&state, "support"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
DO(discovery,pu);
|
||||
DO(discovery,numa);
|
||||
DO(discovery,numa_memory);
|
||||
DO(discovery,disallowed_pu);
|
||||
DO(discovery,disallowed_numa);
|
||||
DO(discovery,cpukind_efficiency);
|
||||
DO(cpubind,set_thisproc_cpubind);
|
||||
DO(cpubind,get_thisproc_cpubind);
|
||||
DO(cpubind,set_proc_cpubind);
|
||||
DO(cpubind,get_proc_cpubind);
|
||||
DO(cpubind,set_thisthread_cpubind);
|
||||
DO(cpubind,get_thisthread_cpubind);
|
||||
DO(cpubind,set_thread_cpubind);
|
||||
DO(cpubind,get_thread_cpubind);
|
||||
DO(cpubind,get_thisproc_last_cpu_location);
|
||||
DO(cpubind,get_proc_last_cpu_location);
|
||||
DO(cpubind,get_thisthread_last_cpu_location);
|
||||
DO(membind,set_thisproc_membind);
|
||||
DO(membind,get_thisproc_membind);
|
||||
DO(membind,set_proc_membind);
|
||||
DO(membind,get_proc_membind);
|
||||
DO(membind,set_thisthread_membind);
|
||||
DO(membind,get_thisthread_membind);
|
||||
DO(membind,set_area_membind);
|
||||
DO(membind,get_area_membind);
|
||||
DO(membind,alloc_membind);
|
||||
DO(membind,firsttouch_membind);
|
||||
DO(membind,bind_membind);
|
||||
DO(membind,interleave_membind);
|
||||
DO(membind,nexttouch_membind);
|
||||
DO(membind,migrate_membind);
|
||||
DO(membind,get_area_memlocation);
|
||||
|
||||
/* misc.imported_support would be meaningless in the remote importer,
|
||||
* but the importer needs to know whether we exported support or not
|
||||
* (in case there are no support bit set at all),
|
||||
* use a custom/fake field to do so.
|
||||
*/
|
||||
parentstate->new_child(parentstate, &state, "support");
|
||||
state.new_prop(&state, "name", "custom.exported_support");
|
||||
state.end_object(&state, "support");
|
||||
|
||||
#undef DO
|
||||
}
|
||||
|
||||
static void
|
||||
hwloc__xml_export_memattr_target(hwloc__xml_export_state_t state,
|
||||
struct hwloc_internal_memattr_s *imattr,
|
||||
struct hwloc_internal_memattr_target_s *imtg)
|
||||
{
|
||||
struct hwloc__xml_export_state_s vstate;
|
||||
char tmp[255];
|
||||
|
||||
if (imattr->flags & HWLOC_MEMATTR_FLAG_NEED_INITIATOR) {
|
||||
/* export all initiators */
|
||||
unsigned k;
|
||||
for(k=0; k<imtg->nr_initiators; k++) {
|
||||
struct hwloc_internal_memattr_initiator_s *imi = &imtg->initiators[k];
|
||||
state->new_child(state, &vstate, "memattr_value");
|
||||
vstate.new_prop(&vstate, "target_obj_type", hwloc_obj_type_string(imtg->type));
|
||||
snprintf(tmp, sizeof(tmp), "%llu", (unsigned long long) imtg->gp_index);
|
||||
vstate.new_prop(&vstate, "target_obj_gp_index", tmp);
|
||||
snprintf(tmp, sizeof(tmp), "%llu", (unsigned long long) imi->value);
|
||||
vstate.new_prop(&vstate, "value", tmp);
|
||||
switch (imi->initiator.type) {
|
||||
case HWLOC_LOCATION_TYPE_OBJECT:
|
||||
snprintf(tmp, sizeof(tmp), "%llu", (unsigned long long) imi->initiator.location.object.gp_index);
|
||||
vstate.new_prop(&vstate, "initiator_obj_gp_index", tmp);
|
||||
vstate.new_prop(&vstate, "initiator_obj_type", hwloc_obj_type_string(imi->initiator.location.object.type));
|
||||
break;
|
||||
case HWLOC_LOCATION_TYPE_CPUSET: {
|
||||
char *setstring;
|
||||
hwloc_bitmap_asprintf(&setstring, imi->initiator.location.cpuset);
|
||||
if (setstring)
|
||||
vstate.new_prop(&vstate, "initiator_cpuset", setstring);
|
||||
free(setstring);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
vstate.end_object(&vstate, "memattr_value");
|
||||
}
|
||||
} else {
|
||||
/* just export the global value */
|
||||
state->new_child(state, &vstate, "memattr_value");
|
||||
vstate.new_prop(&vstate, "target_obj_type", hwloc_obj_type_string(imtg->type));
|
||||
snprintf(tmp, sizeof(tmp), "%llu", (unsigned long long) imtg->gp_index);
|
||||
vstate.new_prop(&vstate, "target_obj_gp_index", tmp);
|
||||
snprintf(tmp, sizeof(tmp), "%llu", (unsigned long long) imtg->noinitiator_value);
|
||||
vstate.new_prop(&vstate, "value", tmp);
|
||||
vstate.end_object(&vstate, "memattr_value");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hwloc__xml_export_memattrs(hwloc__xml_export_state_t state, hwloc_topology_t topology)
|
||||
{
|
||||
unsigned id;
|
||||
for(id=0; id<topology->nr_memattrs; id++) {
|
||||
struct hwloc_internal_memattr_s *imattr;
|
||||
struct hwloc__xml_export_state_s mstate;
|
||||
char tmp[255];
|
||||
unsigned j;
|
||||
|
||||
if (id == HWLOC_MEMATTR_ID_CAPACITY || id == HWLOC_MEMATTR_ID_LOCALITY)
|
||||
/* no need to export virtual memattrs */
|
||||
continue;
|
||||
|
||||
imattr = &topology->memattrs[id];
|
||||
if ((id == HWLOC_MEMATTR_ID_LATENCY || id == HWLOC_MEMATTR_ID_BANDWIDTH)
|
||||
&& !imattr->nr_targets)
|
||||
/* no need to export target-less attributes for initial attributes, no release support attributes without those definitions */
|
||||
continue;
|
||||
|
||||
state->new_child(state, &mstate, "memattr");
|
||||
mstate.new_prop(&mstate, "name", imattr->name);
|
||||
snprintf(tmp, sizeof(tmp), "%lu", imattr->flags);
|
||||
mstate.new_prop(&mstate, "flags", tmp);
|
||||
|
||||
for(j=0; j<imattr->nr_targets; j++)
|
||||
hwloc__xml_export_memattr_target(&mstate, imattr, &imattr->targets[j]);
|
||||
|
||||
mstate.end_object(&mstate, "memattr");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hwloc__xml_export_cpukinds(hwloc__xml_export_state_t state, hwloc_topology_t topology)
|
||||
{
|
||||
unsigned i;
|
||||
for(i=0; i<topology->nr_cpukinds; i++) {
|
||||
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
|
||||
struct hwloc__xml_export_state_s cstate;
|
||||
char *setstring;
|
||||
unsigned j;
|
||||
|
||||
state->new_child(state, &cstate, "cpukind");
|
||||
hwloc_bitmap_asprintf(&setstring, kind->cpuset);
|
||||
cstate.new_prop(&cstate, "cpuset", setstring);
|
||||
free(setstring);
|
||||
if (kind->forced_efficiency != HWLOC_CPUKIND_EFFICIENCY_UNKNOWN) {
|
||||
char tmp[11];
|
||||
snprintf(tmp, sizeof(tmp), "%d", kind->forced_efficiency);
|
||||
cstate.new_prop(&cstate, "forced_efficiency", tmp);
|
||||
}
|
||||
|
||||
for(j=0; j<kind->nr_infos; j++) {
|
||||
char *name = hwloc__xml_export_safestrdup(kind->infos[j].name);
|
||||
char *value = hwloc__xml_export_safestrdup(kind->infos[j].value);
|
||||
struct hwloc__xml_export_state_s istate;
|
||||
cstate.new_child(&cstate, &istate, "info");
|
||||
istate.new_prop(&istate, "name", name);
|
||||
istate.new_prop(&istate, "value", value);
|
||||
istate.end_object(&istate, "info");
|
||||
free(name);
|
||||
free(value);
|
||||
}
|
||||
|
||||
cstate.end_object(&cstate, "cpukind");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
hwloc__xml_export_topology(hwloc__xml_export_state_t state, hwloc_topology_t topology, unsigned long flags)
|
||||
{
|
||||
char *env;
|
||||
hwloc_obj_t root = hwloc_get_root_obj(topology);
|
||||
|
||||
if (flags & HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1) {
|
||||
|
@ -2665,6 +3215,11 @@ hwloc__xml_export_topology(hwloc__xml_export_state_t state, hwloc_topology_t top
|
|||
} else {
|
||||
hwloc__xml_v2export_object (state, topology, root, flags);
|
||||
hwloc__xml_v2export_distances (state, topology);
|
||||
env = getenv("HWLOC_XML_EXPORT_SUPPORT");
|
||||
if (!env || atoi(env))
|
||||
hwloc__xml_v2export_support(state, topology);
|
||||
hwloc__xml_export_memattrs(state, topology);
|
||||
hwloc__xml_export_cpukinds(state, topology);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
234
src/3rdparty/hwloc/src/topology.c
vendored
234
src/3rdparty/hwloc/src/topology.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2019 Inria. All rights reserved.
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009-2012, 2020 Université Bordeaux
|
||||
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
|
@ -75,16 +75,49 @@ int hwloc_hide_errors(void)
|
|||
return hide;
|
||||
}
|
||||
|
||||
void hwloc_report_os_error(const char *msg, int line)
|
||||
|
||||
/* format the obj info to print in error messages */
|
||||
static void
|
||||
report_insert_error_format_obj(char *buf, size_t buflen, hwloc_obj_t obj)
|
||||
{
|
||||
char typestr[64];
|
||||
char *cpusetstr;
|
||||
char *nodesetstr = NULL;
|
||||
|
||||
hwloc_obj_type_snprintf(typestr, sizeof(typestr), obj, 0);
|
||||
hwloc_bitmap_asprintf(&cpusetstr, obj->cpuset);
|
||||
if (obj->nodeset) /* may be missing during insert */
|
||||
hwloc_bitmap_asprintf(&nodesetstr, obj->nodeset);
|
||||
if (obj->os_index != HWLOC_UNKNOWN_INDEX)
|
||||
snprintf(buf, buflen, "%s (P#%u cpuset %s%s%s)",
|
||||
typestr, obj->os_index, cpusetstr,
|
||||
nodesetstr ? " nodeset " : "",
|
||||
nodesetstr ? nodesetstr : "");
|
||||
else
|
||||
snprintf(buf, buflen, "%s (cpuset %s%s%s)",
|
||||
typestr, cpusetstr,
|
||||
nodesetstr ? " nodeset " : "",
|
||||
nodesetstr ? nodesetstr : "");
|
||||
free(cpusetstr);
|
||||
free(nodesetstr);
|
||||
}
|
||||
|
||||
static void report_insert_error(hwloc_obj_t new, hwloc_obj_t old, const char *msg, const char *reason)
|
||||
{
|
||||
static int reported = 0;
|
||||
|
||||
if (!reported && !hwloc_hide_errors()) {
|
||||
if (reason && !reported && !hwloc_hide_errors()) {
|
||||
char newstr[512];
|
||||
char oldstr[512];
|
||||
report_insert_error_format_obj(newstr, sizeof(newstr), new);
|
||||
report_insert_error_format_obj(oldstr, sizeof(oldstr), old);
|
||||
|
||||
fprintf(stderr, "****************************************************************************\n");
|
||||
fprintf(stderr, "* hwloc %s received invalid information from the operating system.\n", HWLOC_VERSION);
|
||||
fprintf(stderr, "*\n");
|
||||
fprintf(stderr, "* %s\n", msg);
|
||||
fprintf(stderr, "* Error occurred in topology.c line %d\n", line);
|
||||
fprintf(stderr, "* Failed with: %s\n", msg);
|
||||
fprintf(stderr, "* while inserting %s at %s\n", newstr, oldstr);
|
||||
fprintf(stderr, "* coming from: %s\n", reason);
|
||||
fprintf(stderr, "*\n");
|
||||
fprintf(stderr, "* The following FAQ entry in the hwloc documentation may help:\n");
|
||||
fprintf(stderr, "* What should I do when hwloc reports \"operating system\" warnings?\n");
|
||||
|
@ -264,7 +297,7 @@ hwloc_setup_pu_level(struct hwloc_topology *topology,
|
|||
|
||||
hwloc_debug_2args_bitmap("cpu %u (os %u) has cpuset %s\n",
|
||||
cpu, oscpu, obj->cpuset);
|
||||
hwloc_insert_object_by_cpuset(topology, obj);
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, obj, "core:pulevel");
|
||||
|
||||
cpu++;
|
||||
}
|
||||
|
@ -347,16 +380,18 @@ hwloc_debug_print_object(int indent __hwloc_attribute_unused, hwloc_obj_t obj)
|
|||
static void
|
||||
hwloc_debug_print_objects(int indent __hwloc_attribute_unused, hwloc_obj_t obj)
|
||||
{
|
||||
hwloc_obj_t child;
|
||||
hwloc_debug_print_object(indent, obj);
|
||||
for_each_child (child, obj)
|
||||
hwloc_debug_print_objects(indent + 1, child);
|
||||
for_each_memory_child (child, obj)
|
||||
hwloc_debug_print_objects(indent + 1, child);
|
||||
for_each_io_child (child, obj)
|
||||
hwloc_debug_print_objects(indent + 1, child);
|
||||
for_each_misc_child (child, obj)
|
||||
hwloc_debug_print_objects(indent + 1, child);
|
||||
if (hwloc_debug_enabled() >= 2) {
|
||||
hwloc_obj_t child;
|
||||
hwloc_debug_print_object(indent, obj);
|
||||
for_each_child (child, obj)
|
||||
hwloc_debug_print_objects(indent + 1, child);
|
||||
for_each_memory_child (child, obj)
|
||||
hwloc_debug_print_objects(indent + 1, child);
|
||||
for_each_io_child (child, obj)
|
||||
hwloc_debug_print_objects(indent + 1, child);
|
||||
for_each_misc_child (child, obj)
|
||||
hwloc_debug_print_objects(indent + 1, child);
|
||||
}
|
||||
}
|
||||
#else /* !HWLOC_DEBUG */
|
||||
#define hwloc_debug_print_object(indent, obj) do { /* nothing */ } while (0)
|
||||
|
@ -472,29 +507,33 @@ int hwloc_obj_add_info(hwloc_obj_t obj, const char *name, const char *value)
|
|||
}
|
||||
|
||||
/* This function may be called with topology->tma set, it cannot free() or realloc() */
|
||||
static int hwloc__tma_dup_infos(struct hwloc_tma *tma, hwloc_obj_t new, hwloc_obj_t src)
|
||||
int hwloc__tma_dup_infos(struct hwloc_tma *tma,
|
||||
struct hwloc_info_s **newip, unsigned *newcp,
|
||||
struct hwloc_info_s *oldi, unsigned oldc)
|
||||
{
|
||||
struct hwloc_info_s *newi;
|
||||
unsigned i, j;
|
||||
new->infos = hwloc_tma_calloc(tma, src->infos_count * sizeof(*src->infos));
|
||||
if (!new->infos)
|
||||
newi = hwloc_tma_calloc(tma, oldc * sizeof(*newi));
|
||||
if (!newi)
|
||||
return -1;
|
||||
for(i=0; i<src->infos_count; i++) {
|
||||
new->infos[i].name = hwloc_tma_strdup(tma, src->infos[i].name);
|
||||
new->infos[i].value = hwloc_tma_strdup(tma, src->infos[i].value);
|
||||
if (!new->infos[i].name || !new->infos[i].value)
|
||||
for(i=0; i<oldc; i++) {
|
||||
newi[i].name = hwloc_tma_strdup(tma, oldi[i].name);
|
||||
newi[i].value = hwloc_tma_strdup(tma, oldi[i].value);
|
||||
if (!newi[i].name || !newi[i].value)
|
||||
goto failed;
|
||||
}
|
||||
new->infos_count = src->infos_count;
|
||||
*newip = newi;
|
||||
*newcp = oldc;
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
assert(!tma || !tma->dontfree); /* this tma cannot fail to allocate */
|
||||
for(j=0; j<=i; j++) {
|
||||
free(new->infos[i].name);
|
||||
free(new->infos[i].value);
|
||||
free(newi[i].name);
|
||||
free(newi[i].value);
|
||||
}
|
||||
free(new->infos);
|
||||
new->infos = NULL;
|
||||
free(newi);
|
||||
*newip = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -812,7 +851,7 @@ hwloc__duplicate_object(struct hwloc_topology *newtopology,
|
|||
newobj->nodeset = hwloc_bitmap_tma_dup(tma, src->nodeset);
|
||||
newobj->complete_nodeset = hwloc_bitmap_tma_dup(tma, src->complete_nodeset);
|
||||
|
||||
hwloc__tma_dup_infos(tma, newobj, src);
|
||||
hwloc__tma_dup_infos(tma, &newobj->infos, &newobj->infos_count, src->infos, src->infos_count);
|
||||
|
||||
/* find our level */
|
||||
if (src->depth < 0) {
|
||||
|
@ -970,6 +1009,7 @@ hwloc__topology_dup(hwloc_topology_t *newp,
|
|||
memcpy(new->support.discovery, old->support.discovery, sizeof(*old->support.discovery));
|
||||
memcpy(new->support.cpubind, old->support.cpubind, sizeof(*old->support.cpubind));
|
||||
memcpy(new->support.membind, old->support.membind, sizeof(*old->support.membind));
|
||||
memcpy(new->support.misc, old->support.misc, sizeof(*old->support.misc));
|
||||
|
||||
new->allowed_cpuset = hwloc_bitmap_tma_dup(tma, old->allowed_cpuset);
|
||||
new->allowed_nodeset = hwloc_bitmap_tma_dup(tma, old->allowed_nodeset);
|
||||
|
@ -1008,6 +1048,14 @@ hwloc__topology_dup(hwloc_topology_t *newp,
|
|||
if (err < 0)
|
||||
goto out_with_topology;
|
||||
|
||||
err = hwloc_internal_memattrs_dup(new, old);
|
||||
if (err < 0)
|
||||
goto out_with_topology;
|
||||
|
||||
err = hwloc_internal_cpukinds_dup(new, old);
|
||||
if (err < 0)
|
||||
goto out_with_topology;
|
||||
|
||||
/* we connected everything during duplication */
|
||||
new->modified = 0;
|
||||
|
||||
|
@ -1229,31 +1277,6 @@ hwloc__object_cpusets_compare_first(hwloc_obj_t obj1, hwloc_obj_t obj2)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* format the obj info to print in error messages */
|
||||
static void
|
||||
hwloc__report_error_format_obj(char *buf, size_t buflen, hwloc_obj_t obj)
|
||||
{
|
||||
char typestr[64];
|
||||
char *cpusetstr;
|
||||
char *nodesetstr = NULL;
|
||||
hwloc_obj_type_snprintf(typestr, sizeof(typestr), obj, 0);
|
||||
hwloc_bitmap_asprintf(&cpusetstr, obj->cpuset);
|
||||
if (obj->nodeset) /* may be missing during insert */
|
||||
hwloc_bitmap_asprintf(&nodesetstr, obj->nodeset);
|
||||
if (obj->os_index != HWLOC_UNKNOWN_INDEX)
|
||||
snprintf(buf, buflen, "%s (P#%u cpuset %s%s%s)",
|
||||
typestr, obj->os_index, cpusetstr,
|
||||
nodesetstr ? " nodeset " : "",
|
||||
nodesetstr ? nodesetstr : "");
|
||||
else
|
||||
snprintf(buf, buflen, "%s (cpuset %s%s%s)",
|
||||
typestr, cpusetstr,
|
||||
nodesetstr ? " nodeset " : "",
|
||||
nodesetstr ? nodesetstr : "");
|
||||
free(cpusetstr);
|
||||
free(nodesetstr);
|
||||
}
|
||||
|
||||
/*
|
||||
* How to insert objects into the topology.
|
||||
*
|
||||
|
@ -1390,9 +1413,9 @@ hwloc__insert_try_merge_group(hwloc_obj_t old, hwloc_obj_t new)
|
|||
*/
|
||||
static struct hwloc_obj *
|
||||
hwloc___insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t cur, hwloc_obj_t obj,
|
||||
hwloc_report_error_t report_error)
|
||||
const char *reason)
|
||||
{
|
||||
hwloc_obj_t child, next_child = NULL;
|
||||
hwloc_obj_t child, next_child = NULL, tmp;
|
||||
/* These will always point to the pointer to their next last child. */
|
||||
hwloc_obj_t *cur_children = &cur->first_child;
|
||||
hwloc_obj_t *obj_children = &obj->first_child;
|
||||
|
@ -1430,18 +1453,10 @@ hwloc___insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t cur
|
|||
|
||||
case HWLOC_OBJ_INCLUDED:
|
||||
/* OBJ is strictly contained is some child of CUR, go deeper. */
|
||||
return hwloc___insert_object_by_cpuset(topology, child, obj, report_error);
|
||||
return hwloc___insert_object_by_cpuset(topology, child, obj, reason);
|
||||
|
||||
case HWLOC_OBJ_INTERSECTS:
|
||||
if (report_error) {
|
||||
char childstr[512];
|
||||
char objstr[512];
|
||||
char msg[1100];
|
||||
hwloc__report_error_format_obj(objstr, sizeof(objstr), obj);
|
||||
hwloc__report_error_format_obj(childstr, sizeof(childstr), child);
|
||||
snprintf(msg, sizeof(msg), "%s intersects with %s without inclusion!", objstr, childstr);
|
||||
report_error(msg, __LINE__);
|
||||
}
|
||||
report_insert_error(obj, child, "intersection without inclusion", reason);
|
||||
goto putback;
|
||||
|
||||
case HWLOC_OBJ_DIFFERENT:
|
||||
|
@ -1464,6 +1479,8 @@ hwloc___insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t cur
|
|||
if (setres == HWLOC_OBJ_EQUAL) {
|
||||
obj->memory_first_child = child->memory_first_child;
|
||||
child->memory_first_child = NULL;
|
||||
for(tmp=obj->memory_first_child; tmp; tmp = tmp->next_sibling)
|
||||
tmp->parent = obj;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1483,7 +1500,9 @@ hwloc___insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t cur
|
|||
return obj;
|
||||
|
||||
putback:
|
||||
/* Put-back OBJ children in CUR and return an error. */
|
||||
/* OBJ cannot be inserted.
|
||||
* Put-back OBJ children in CUR and return an error.
|
||||
*/
|
||||
if (putp)
|
||||
cur_children = putp; /* No need to try to insert before where OBJ was supposed to go */
|
||||
else
|
||||
|
@ -1492,12 +1511,12 @@ hwloc___insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t cur
|
|||
while ((child = obj->first_child) != NULL) {
|
||||
/* Remove from OBJ */
|
||||
obj->first_child = child->next_sibling;
|
||||
obj->parent = cur;
|
||||
/* Find child position in CUR, and insert. */
|
||||
/* Find child position in CUR, and reinsert it. */
|
||||
while (*cur_children && hwloc__object_cpusets_compare_first(*cur_children, child) < 0)
|
||||
cur_children = &(*cur_children)->next_sibling;
|
||||
child->next_sibling = *cur_children;
|
||||
*cur_children = child;
|
||||
child->parent = cur;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1521,7 +1540,7 @@ hwloc__find_obj_covering_memory_cpuset(struct hwloc_topology *topology, hwloc_ob
|
|||
|
||||
static struct hwloc_obj *
|
||||
hwloc__find_insert_memory_parent(struct hwloc_topology *topology, hwloc_obj_t obj,
|
||||
hwloc_report_error_t report_error)
|
||||
const char *reason)
|
||||
{
|
||||
hwloc_obj_t parent, group, result;
|
||||
|
||||
|
@ -1573,7 +1592,7 @@ hwloc__find_insert_memory_parent(struct hwloc_topology *topology, hwloc_obj_t ob
|
|||
return parent;
|
||||
}
|
||||
|
||||
result = hwloc__insert_object_by_cpuset(topology, parent, group, report_error);
|
||||
result = hwloc__insert_object_by_cpuset(topology, parent, group, reason);
|
||||
if (!result) {
|
||||
/* failed to insert, fallback to larger parent */
|
||||
return parent;
|
||||
|
@ -1586,8 +1605,7 @@ hwloc__find_insert_memory_parent(struct hwloc_topology *topology, hwloc_obj_t ob
|
|||
/* only works for MEMCACHE and NUMAnode with a single bit in nodeset */
|
||||
static hwloc_obj_t
|
||||
hwloc___attach_memory_object_by_nodeset(struct hwloc_topology *topology, hwloc_obj_t parent,
|
||||
hwloc_obj_t obj,
|
||||
hwloc_report_error_t report_error)
|
||||
hwloc_obj_t obj, const char *reason)
|
||||
{
|
||||
hwloc_obj_t *curp = &parent->memory_first_child;
|
||||
unsigned first = hwloc_bitmap_first(obj->nodeset);
|
||||
|
@ -1611,20 +1629,12 @@ hwloc___attach_memory_object_by_nodeset(struct hwloc_topology *topology, hwloc_o
|
|||
if (obj->type == HWLOC_OBJ_NUMANODE) {
|
||||
if (cur->type == HWLOC_OBJ_NUMANODE) {
|
||||
/* identical NUMA nodes? ignore the new one */
|
||||
if (report_error) {
|
||||
char curstr[512];
|
||||
char objstr[512];
|
||||
char msg[1100];
|
||||
hwloc__report_error_format_obj(curstr, sizeof(curstr), cur);
|
||||
hwloc__report_error_format_obj(objstr, sizeof(objstr), obj);
|
||||
snprintf(msg, sizeof(msg), "%s and %s have identical nodesets!", objstr, curstr);
|
||||
report_error(msg, __LINE__);
|
||||
}
|
||||
report_insert_error(obj, cur, "NUMAnodes with identical nodesets", reason);
|
||||
return NULL;
|
||||
}
|
||||
assert(cur->type == HWLOC_OBJ_MEMCACHE);
|
||||
/* insert the new NUMA node below that existing memcache */
|
||||
return hwloc___attach_memory_object_by_nodeset(topology, cur, obj, report_error);
|
||||
return hwloc___attach_memory_object_by_nodeset(topology, cur, obj, reason);
|
||||
|
||||
} else {
|
||||
assert(obj->type == HWLOC_OBJ_MEMCACHE);
|
||||
|
@ -1637,7 +1647,7 @@ hwloc___attach_memory_object_by_nodeset(struct hwloc_topology *topology, hwloc_o
|
|||
* (depth starts from the NUMA node).
|
||||
* insert the new memcache below the existing one
|
||||
*/
|
||||
return hwloc___attach_memory_object_by_nodeset(topology, cur, obj, report_error);
|
||||
return hwloc___attach_memory_object_by_nodeset(topology, cur, obj, reason);
|
||||
}
|
||||
/* insert the memcache above the existing memcache or numa node */
|
||||
obj->next_sibling = cur->next_sibling;
|
||||
|
@ -1673,8 +1683,7 @@ hwloc___attach_memory_object_by_nodeset(struct hwloc_topology *topology, hwloc_o
|
|||
*/
|
||||
struct hwloc_obj *
|
||||
hwloc__attach_memory_object(struct hwloc_topology *topology, hwloc_obj_t parent,
|
||||
hwloc_obj_t obj,
|
||||
hwloc_report_error_t report_error)
|
||||
hwloc_obj_t obj, const char *reason)
|
||||
{
|
||||
hwloc_obj_t result;
|
||||
|
||||
|
@ -1704,7 +1713,7 @@ hwloc__attach_memory_object(struct hwloc_topology *topology, hwloc_obj_t parent,
|
|||
hwloc_bitmap_copy(obj->complete_cpuset, parent->complete_cpuset);
|
||||
#endif
|
||||
|
||||
result = hwloc___attach_memory_object_by_nodeset(topology, parent, obj, report_error);
|
||||
result = hwloc___attach_memory_object_by_nodeset(topology, parent, obj, reason);
|
||||
if (result == obj) {
|
||||
/* Add the bit to the top sets, and to the parent CPU-side object */
|
||||
if (obj->type == HWLOC_OBJ_NUMANODE) {
|
||||
|
@ -1722,8 +1731,7 @@ hwloc__attach_memory_object(struct hwloc_topology *topology, hwloc_obj_t parent,
|
|||
/* insertion routine that lets you change the error reporting callback */
|
||||
struct hwloc_obj *
|
||||
hwloc__insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t root,
|
||||
hwloc_obj_t obj,
|
||||
hwloc_report_error_t report_error)
|
||||
hwloc_obj_t obj, const char *reason)
|
||||
{
|
||||
struct hwloc_obj *result;
|
||||
|
||||
|
@ -1740,20 +1748,20 @@ hwloc__insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t root
|
|||
|
||||
if (hwloc__obj_type_is_memory(obj->type)) {
|
||||
if (!root) {
|
||||
root = hwloc__find_insert_memory_parent(topology, obj, report_error);
|
||||
root = hwloc__find_insert_memory_parent(topology, obj, reason);
|
||||
if (!root) {
|
||||
hwloc_free_unlinked_object(obj);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return hwloc__attach_memory_object(topology, root, obj, report_error);
|
||||
return hwloc__attach_memory_object(topology, root, obj, reason);
|
||||
}
|
||||
|
||||
if (!root)
|
||||
/* Start at the top. */
|
||||
root = topology->levels[0][0];
|
||||
|
||||
result = hwloc___insert_object_by_cpuset(topology, root, obj, report_error);
|
||||
result = hwloc___insert_object_by_cpuset(topology, root, obj, reason);
|
||||
if (result && result->type == HWLOC_OBJ_PU) {
|
||||
/* Add the bit to the top sets */
|
||||
if (hwloc_bitmap_isset(result->cpuset, result->os_index))
|
||||
|
@ -1769,12 +1777,6 @@ hwloc__insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t root
|
|||
|
||||
/* the default insertion routine warns in case of error.
|
||||
* it's used by most backends */
|
||||
struct hwloc_obj *
|
||||
hwloc_insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t obj)
|
||||
{
|
||||
return hwloc__insert_object_by_cpuset(topology, NULL, obj, hwloc_report_os_error);
|
||||
}
|
||||
|
||||
void
|
||||
hwloc_insert_object_by_parent(struct hwloc_topology *topology, hwloc_obj_t parent, hwloc_obj_t obj)
|
||||
{
|
||||
|
@ -1917,6 +1919,7 @@ hwloc_topology_insert_group_object(struct hwloc_topology *topology, hwloc_obj_t
|
|||
if (hwloc_bitmap_isset(nodeset, numa->os_index))
|
||||
hwloc_bitmap_or(obj->cpuset, obj->cpuset, numa->cpuset);
|
||||
}
|
||||
/* FIXME insert by nodeset to group NUMAs even if CPUless? */
|
||||
|
||||
cmp = hwloc_obj_cmp_sets(obj, root);
|
||||
if (cmp == HWLOC_OBJ_INCLUDED) {
|
||||
|
@ -2047,7 +2050,7 @@ hwloc_find_insert_io_parent_by_complete_cpuset(struct hwloc_topology *topology,
|
|||
hwloc_bitmap_and(cpuset, cpuset, hwloc_topology_get_topology_cpuset(topology));
|
||||
group_obj->cpuset = hwloc_bitmap_dup(cpuset);
|
||||
group_obj->attr->group.kind = HWLOC_GROUP_KIND_IO;
|
||||
parent = hwloc__insert_object_by_cpuset(topology, largeparent, group_obj, hwloc_report_os_error);
|
||||
parent = hwloc__insert_object_by_cpuset(topology, largeparent, group_obj, "topology:io_parent");
|
||||
if (!parent)
|
||||
/* Failed to insert the Group, maybe a conflicting cpuset */
|
||||
return largeparent;
|
||||
|
@ -3251,7 +3254,7 @@ hwloc_discover(struct hwloc_topology *topology,
|
|||
* produced by hwloc_setup_pu_level()
|
||||
*/
|
||||
|
||||
/* To be able to just use hwloc_insert_object_by_cpuset to insert the object
|
||||
/* To be able to just use hwloc__insert_object_by_cpuset to insert the object
|
||||
* in the topology according to the cpuset, the cpuset field must be
|
||||
* initialized.
|
||||
*/
|
||||
|
@ -3356,7 +3359,7 @@ hwloc_discover(struct hwloc_topology *topology,
|
|||
hwloc_bitmap_set(node->nodeset, 0);
|
||||
memcpy(&node->attr->numanode, &topology->machine_memory, sizeof(topology->machine_memory));
|
||||
memset(&topology->machine_memory, 0, sizeof(topology->machine_memory));
|
||||
hwloc_insert_object_by_cpuset(topology, node);
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, node, "core:defaultnumanode");
|
||||
} else {
|
||||
/* if we're sure we found all NUMA nodes without their sizes (x86 backend?),
|
||||
* we could split topology->total_memory in all of them.
|
||||
|
@ -3514,6 +3517,7 @@ hwloc_topology_setup_defaults(struct hwloc_topology *topology)
|
|||
memset(topology->support.discovery, 0, sizeof(*topology->support.discovery));
|
||||
memset(topology->support.cpubind, 0, sizeof(*topology->support.cpubind));
|
||||
memset(topology->support.membind, 0, sizeof(*topology->support.membind));
|
||||
memset(topology->support.misc, 0, sizeof(*topology->support.misc));
|
||||
|
||||
/* Only the System object on top by default */
|
||||
topology->next_gp_index = 1; /* keep 0 as an invalid value */
|
||||
|
@ -3590,6 +3594,7 @@ hwloc__topology_init (struct hwloc_topology **topologyp,
|
|||
topology->support.discovery = hwloc_tma_malloc(tma, sizeof(*topology->support.discovery));
|
||||
topology->support.cpubind = hwloc_tma_malloc(tma, sizeof(*topology->support.cpubind));
|
||||
topology->support.membind = hwloc_tma_malloc(tma, sizeof(*topology->support.membind));
|
||||
topology->support.misc = hwloc_tma_malloc(tma, sizeof(*topology->support.misc));
|
||||
|
||||
topology->nb_levels_allocated = nblevels; /* enough for default 10 levels = Mach+Pack+Die+NUMA+L3+L2+L1d+L1i+Co+PU */
|
||||
topology->levels = hwloc_tma_calloc(tma, topology->nb_levels_allocated * sizeof(*topology->levels));
|
||||
|
@ -3598,6 +3603,8 @@ hwloc__topology_init (struct hwloc_topology **topologyp,
|
|||
hwloc__topology_filter_init(topology);
|
||||
|
||||
hwloc_internal_distances_init(topology);
|
||||
hwloc_internal_memattrs_init(topology);
|
||||
hwloc_internal_cpukinds_init(topology);
|
||||
|
||||
topology->userdata_export_cb = NULL;
|
||||
topology->userdata_import_cb = NULL;
|
||||
|
@ -3691,7 +3698,7 @@ hwloc_topology_set_flags (struct hwloc_topology *topology, unsigned long flags)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (flags & ~(HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED|HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM|HWLOC_TOPOLOGY_FLAG_THISSYSTEM_ALLOWED_RESOURCES)) {
|
||||
if (flags & ~(HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED|HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM|HWLOC_TOPOLOGY_FLAG_THISSYSTEM_ALLOWED_RESOURCES|HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -3827,7 +3834,9 @@ hwloc_topology_clear (struct hwloc_topology *topology)
|
|||
{
|
||||
/* no need to set to NULL after free() since callers will call setup_defaults() or just destroy the rest of the topology */
|
||||
unsigned l;
|
||||
hwloc_internal_cpukinds_destroy(topology);
|
||||
hwloc_internal_distances_destroy(topology);
|
||||
hwloc_internal_memattrs_destroy(topology);
|
||||
hwloc_free_object_and_children(topology->levels[0][0]);
|
||||
hwloc_bitmap_free(topology->allowed_cpuset);
|
||||
hwloc_bitmap_free(topology->allowed_nodeset);
|
||||
|
@ -3858,6 +3867,7 @@ hwloc_topology_destroy (struct hwloc_topology *topology)
|
|||
free(topology->support.discovery);
|
||||
free(topology->support.cpubind);
|
||||
free(topology->support.membind);
|
||||
free(topology->support.misc);
|
||||
free(topology);
|
||||
}
|
||||
|
||||
|
@ -3873,7 +3883,9 @@ hwloc_topology_load (struct hwloc_topology *topology)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* initialize envvar-related things */
|
||||
hwloc_internal_distances_prepare(topology);
|
||||
hwloc_internal_memattrs_prepare(topology);
|
||||
|
||||
if (getenv("HWLOC_XML_USERDATA_NOT_DECODED"))
|
||||
topology->userdata_not_decoded = 1;
|
||||
|
@ -3954,6 +3966,9 @@ hwloc_topology_load (struct hwloc_topology *topology)
|
|||
#endif
|
||||
hwloc_topology_check(topology);
|
||||
|
||||
/* Rank cpukinds */
|
||||
hwloc_internal_cpukinds_rank(topology);
|
||||
|
||||
/* Mark distances objs arrays as invalid since we may have removed objects
|
||||
* from the topology after adding the distances (remove_empty, etc).
|
||||
* It would be hard to actually verify whether it's needed.
|
||||
|
@ -3964,6 +3979,10 @@ hwloc_topology_load (struct hwloc_topology *topology)
|
|||
*/
|
||||
hwloc_internal_distances_refresh(topology);
|
||||
|
||||
/* Same for memattrs */
|
||||
hwloc_internal_memattrs_need_refresh(topology);
|
||||
hwloc_internal_memattrs_refresh(topology);
|
||||
|
||||
topology->is_loaded = 1;
|
||||
|
||||
if (topology->backend_phases & HWLOC_DISC_PHASE_TWEAK) {
|
||||
|
@ -4246,10 +4265,12 @@ hwloc_topology_restrict(struct hwloc_topology *topology, hwloc_const_bitmap_t se
|
|||
|
||||
/* some objects may have disappeared, we need to update distances objs arrays */
|
||||
hwloc_internal_distances_invalidate_cached_objs(topology);
|
||||
hwloc_internal_memattrs_need_refresh(topology);
|
||||
|
||||
hwloc_filter_levels_keep_structure(topology);
|
||||
hwloc_propagate_symmetric_subtree(topology, topology->levels[0][0]);
|
||||
propagate_total_memory(topology->levels[0][0]);
|
||||
hwloc_internal_cpukinds_restrict(topology);
|
||||
|
||||
#ifndef HWLOC_DEBUG
|
||||
if (getenv("HWLOC_DEBUG_CHECK"))
|
||||
|
@ -4334,6 +4355,15 @@ hwloc_topology_allow(struct hwloc_topology *topology,
|
|||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_topology_refresh(struct hwloc_topology *topology)
|
||||
{
|
||||
hwloc_internal_cpukinds_rank(topology);
|
||||
hwloc_internal_distances_refresh(topology);
|
||||
hwloc_internal_memattrs_refresh(topology);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_topology_is_thissystem(struct hwloc_topology *topology)
|
||||
{
|
||||
|
|
69
src/3rdparty/hwloc/src/traversal.c
vendored
69
src/3rdparty/hwloc/src/traversal.c
vendored
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2019 Inria. All rights reserved.
|
||||
* Copyright © 2009-2010 Université Bordeaux
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009-2010, 2020 Université Bordeaux
|
||||
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
@ -138,6 +138,37 @@ hwloc_obj_type_is_icache(hwloc_obj_type_t type)
|
|||
return hwloc__obj_type_is_icache(type);
|
||||
}
|
||||
|
||||
static hwloc_obj_t hwloc_get_obj_by_depth_and_gp_index(hwloc_topology_t topology, unsigned depth, uint64_t gp_index)
|
||||
{
|
||||
hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, 0);
|
||||
while (obj) {
|
||||
if (obj->gp_index == gp_index)
|
||||
return obj;
|
||||
obj = obj->next_cousin;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hwloc_obj_t hwloc_get_obj_by_type_and_gp_index(hwloc_topology_t topology, hwloc_obj_type_t type, uint64_t gp_index)
|
||||
{
|
||||
int depth = hwloc_get_type_depth(topology, type);
|
||||
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
|
||||
return NULL;
|
||||
if (depth == HWLOC_TYPE_DEPTH_MULTIPLE) {
|
||||
for(depth=1 /* no multiple machine levels */;
|
||||
(unsigned) depth < topology->nb_levels-1 /* no multiple PU levels */;
|
||||
depth++) {
|
||||
if (hwloc_get_depth_type(topology, depth) == type) {
|
||||
hwloc_obj_t obj = hwloc_get_obj_by_depth_and_gp_index(topology, depth, gp_index);
|
||||
if (obj)
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
return hwloc_get_obj_by_depth_and_gp_index(topology, depth, gp_index);
|
||||
}
|
||||
|
||||
unsigned hwloc_get_closest_objs (struct hwloc_topology *topology, struct hwloc_obj *src, struct hwloc_obj **objs, unsigned max)
|
||||
{
|
||||
struct hwloc_obj *parent, *nextparent, **src_objs;
|
||||
|
@ -654,7 +685,11 @@ hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
|
|||
unsigned i;
|
||||
for(i=0; i<obj->infos_count; i++) {
|
||||
struct hwloc_info_s *info = &obj->infos[i];
|
||||
const char *quote = strchr(info->value, ' ') ? "\"" : "";
|
||||
const char *quote;
|
||||
if (strchr(info->value, ' '))
|
||||
quote = "\"";
|
||||
else
|
||||
quote = "";
|
||||
res = hwloc_snprintf(tmp, tmplen, "%s%s=%s%s%s",
|
||||
prefix,
|
||||
info->name,
|
||||
|
@ -673,3 +708,31 @@ hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int hwloc_bitmap_singlify_per_core(hwloc_topology_t topology, hwloc_bitmap_t cpuset, unsigned which)
|
||||
{
|
||||
hwloc_obj_t core = NULL;
|
||||
while ((core = hwloc_get_next_obj_covering_cpuset_by_type(topology, cpuset, HWLOC_OBJ_CORE, core)) != NULL) {
|
||||
/* this core has some PUs in the cpuset, find the index-th one */
|
||||
unsigned i = 0;
|
||||
int pu = -1;
|
||||
do {
|
||||
pu = hwloc_bitmap_next(core->cpuset, pu);
|
||||
if (pu == -1) {
|
||||
/* no which-th PU in cpuset and core, remove the entire core */
|
||||
hwloc_bitmap_andnot(cpuset, cpuset, core->cpuset);
|
||||
break;
|
||||
}
|
||||
if (hwloc_bitmap_isset(cpuset, pu)) {
|
||||
if (i == which) {
|
||||
/* remove the entire core except that exact pu */
|
||||
hwloc_bitmap_andnot(cpuset, cpuset, core->cpuset);
|
||||
hwloc_bitmap_set(cpuset, pu);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue