mirror of
https://github.com/xmrig/xmrig.git
synced 2025-12-07 07:55:04 -05:00
Compare commits
23 Commits
v6.18.1
...
4948a8c354
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4948a8c354 | ||
|
|
637c023d06 | ||
|
|
f006ec0b68 | ||
|
|
04e5ff0349 | ||
|
|
9ad1c02430 | ||
|
|
61c263af6e | ||
|
|
fe0ed9eaae | ||
|
|
d8f39ebef3 | ||
|
|
07d53fb77e | ||
|
|
3ded8e6734 | ||
|
|
774f630e14 | ||
|
|
d6a1c98314 | ||
|
|
75283445fd | ||
|
|
45084cb718 | ||
|
|
bc150fec04 | ||
|
|
9a0cd68ea5 | ||
|
|
603eb261c5 | ||
|
|
de97f3492e | ||
|
|
8a167cb2a7 | ||
|
|
d0953a507c | ||
|
|
fe8e198106 | ||
|
|
dfc3b4632a | ||
|
|
6106bf30de |
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
[submodule "src/base"]
|
||||
path = src/base
|
||||
url = https://github.com/xmrig/base.git
|
||||
branch = master
|
||||
@@ -156,14 +156,12 @@ endif()
|
||||
if (XMRIG_OS_WIN)
|
||||
list(APPEND SOURCES_OS
|
||||
res/app.rc
|
||||
src/App_win.cpp
|
||||
src/crypto/common/VirtualMemory_win.cpp
|
||||
)
|
||||
|
||||
set(EXTRA_LIBS ws2_32 psapi iphlpapi userenv)
|
||||
elseif (XMRIG_OS_APPLE)
|
||||
list(APPEND SOURCES_OS
|
||||
src/App_unix.cpp
|
||||
src/crypto/common/VirtualMemory_unix.cpp
|
||||
)
|
||||
|
||||
@@ -172,7 +170,6 @@ elseif (XMRIG_OS_APPLE)
|
||||
set(EXTRA_LIBS ${IOKIT_LIBRARY} ${CORESERVICES_LIBRARY})
|
||||
else()
|
||||
list(APPEND SOURCES_OS
|
||||
src/App_unix.cpp
|
||||
src/crypto/common/VirtualMemory_unix.cpp
|
||||
)
|
||||
|
||||
@@ -190,11 +187,16 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_definitions(-DXMRIG_MINER_PROJECT -DXMRIG_JSON_SINGLE_LINE_ARRAY)
|
||||
add_definitions(-DXMRIG_MINER_PROJECT -DXMRIG_LEGACY -DXMRIG_JSON_SINGLE_LINE_ARRAY)
|
||||
add_definitions(-D__STDC_FORMAT_MACROS -DUNICODE -D_FILE_OFFSET_BITS=64)
|
||||
|
||||
find_package(UV REQUIRED)
|
||||
|
||||
include_directories(src)
|
||||
include_directories(src/3rdparty)
|
||||
include_directories(src/base)
|
||||
include_directories(${UV_INCLUDE_DIR})
|
||||
|
||||
include(cmake/flags.cmake)
|
||||
include(cmake/randomx.cmake)
|
||||
include(cmake/argon2.cmake)
|
||||
@@ -226,10 +228,6 @@ endif()
|
||||
include(src/hw/api/api.cmake)
|
||||
include(src/hw/dmi/dmi.cmake)
|
||||
|
||||
include_directories(src)
|
||||
include_directories(src/3rdparty)
|
||||
include_directories(${UV_INCLUDE_DIR})
|
||||
|
||||
if (WITH_DEBUG_LOG)
|
||||
add_definitions(/DAPP_DEBUG)
|
||||
endif()
|
||||
|
||||
@@ -11,7 +11,7 @@ if (WITH_KAWPOW)
|
||||
src/crypto/kawpow/KPHash.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(src/3rdparty/libethash)
|
||||
add_subdirectory(src/base/3rdparty/libethash)
|
||||
set(ETHASH_LIBRARY ethash)
|
||||
else()
|
||||
remove_definitions(/DXMRIG_ALGO_KAWPOW)
|
||||
|
||||
@@ -20,7 +20,7 @@ VS_VERSION_INFO VERSIONINFO
|
||||
BEGIN
|
||||
BLOCK "000004b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", APP_SITE
|
||||
VALUE "CompanyName", APP_DOMAIN
|
||||
VALUE "FileDescription", APP_DESC
|
||||
VALUE "FileVersion", APP_VERSION
|
||||
VALUE "LegalCopyright", APP_COPYRIGHT
|
||||
|
||||
25
src/3rdparty/epee/LICENSE.txt
vendored
25
src/3rdparty/epee/LICENSE.txt
vendored
@@ -1,25 +0,0 @@
|
||||
Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Andrey N. Sabelnikov nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL Andrey N. Sabelnikov BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
1
src/3rdparty/epee/README.md
vendored
1
src/3rdparty/epee/README.md
vendored
@@ -1 +0,0 @@
|
||||
epee - is a small library of helpers, wrappers, tools and and so on, used to make my life easier.
|
||||
176
src/3rdparty/epee/span.h
vendored
176
src/3rdparty/epee/span.h
vendored
@@ -1,176 +0,0 @@
|
||||
// Copyright (c) 2017-2020, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
namespace epee
|
||||
{
|
||||
/*!
|
||||
\brief Non-owning sequence of data. Does not deep copy
|
||||
|
||||
Inspired by `gsl::span` and/or `boost::iterator_range`. This class is
|
||||
intended to be used as a parameter type for functions that need to take a
|
||||
writable or read-only sequence of data. Most common cases are `span<char>`
|
||||
and `span<std::uint8_t>`. Using as a class member is only recommended if
|
||||
clearly documented as not doing a deep-copy. C-arrays are easily convertible
|
||||
to this type.
|
||||
|
||||
\note Conversion from C string literal to `span<const char>` will include
|
||||
the NULL-terminator.
|
||||
\note Never allows derived-to-base pointer conversion; an array of derived
|
||||
types is not an array of base types.
|
||||
*/
|
||||
template<typename T>
|
||||
class span
|
||||
{
|
||||
template<typename U>
|
||||
static constexpr bool safe_conversion() noexcept
|
||||
{
|
||||
// Allow exact matches or `T*` -> `const T*`.
|
||||
using with_const = typename std::add_const<U>::type;
|
||||
return std::is_same<T, U>() ||
|
||||
(std::is_const<T>() && std::is_same<T, with_const>());
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = T;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = T*;
|
||||
using const_pointer = const T*;
|
||||
using reference = T&;
|
||||
using const_reference = const T&;
|
||||
using iterator = pointer;
|
||||
using const_iterator = const_pointer;
|
||||
|
||||
constexpr span() noexcept : ptr(nullptr), len(0) {}
|
||||
constexpr span(std::nullptr_t) noexcept : span() {}
|
||||
|
||||
//! Prevent derived-to-base conversions; invalid in this context.
|
||||
template<typename U, typename = typename std::enable_if<safe_conversion<U>()>::type>
|
||||
constexpr span(U* const src_ptr, const std::size_t count) noexcept
|
||||
: ptr(src_ptr), len(count) {}
|
||||
|
||||
//! Conversion from C-array. Prevents common bugs with sizeof + arrays.
|
||||
template<std::size_t N>
|
||||
constexpr span(T (&src)[N]) noexcept : span(src, N) {}
|
||||
|
||||
constexpr span(const span&) noexcept = default;
|
||||
span& operator=(const span&) noexcept = default;
|
||||
|
||||
/*! Try to remove `amount` elements from beginning of span.
|
||||
\return Number of elements removed. */
|
||||
std::size_t remove_prefix(std::size_t amount) noexcept
|
||||
{
|
||||
amount = std::min(len, amount);
|
||||
ptr += amount;
|
||||
len -= amount;
|
||||
return amount;
|
||||
}
|
||||
|
||||
constexpr iterator begin() const noexcept { return ptr; }
|
||||
constexpr const_iterator cbegin() const noexcept { return ptr; }
|
||||
|
||||
constexpr iterator end() const noexcept { return begin() + size(); }
|
||||
constexpr const_iterator cend() const noexcept { return cbegin() + size(); }
|
||||
|
||||
constexpr bool empty() const noexcept { return size() == 0; }
|
||||
constexpr pointer data() const noexcept { return ptr; }
|
||||
constexpr std::size_t size() const noexcept { return len; }
|
||||
constexpr std::size_t size_bytes() const noexcept { return size() * sizeof(value_type); }
|
||||
|
||||
T &operator[](size_t idx) noexcept { return ptr[idx]; }
|
||||
const T &operator[](size_t idx) const noexcept { return ptr[idx]; }
|
||||
|
||||
private:
|
||||
T* ptr;
|
||||
std::size_t len;
|
||||
};
|
||||
|
||||
//! \return `span<const T::value_type>` from a STL compatible `src`.
|
||||
template<typename T>
|
||||
constexpr span<const typename T::value_type> to_span(const T& src)
|
||||
{
|
||||
// compiler provides diagnostic if size() is not size_t.
|
||||
return {src.data(), src.size()};
|
||||
}
|
||||
|
||||
//! \return `span<T::value_type>` from a STL compatible `src`.
|
||||
template<typename T>
|
||||
constexpr span<typename T::value_type> to_mut_span(T& src)
|
||||
{
|
||||
// compiler provides diagnostic if size() is not size_t.
|
||||
return {src.data(), src.size()};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr bool has_padding() noexcept
|
||||
{
|
||||
return !std::is_standard_layout<T>() || alignof(T) != 1;
|
||||
}
|
||||
|
||||
//! \return Cast data from `src` as `span<const std::uint8_t>`.
|
||||
template<typename T>
|
||||
span<const std::uint8_t> to_byte_span(const span<const T> src) noexcept
|
||||
{
|
||||
static_assert(!has_padding<T>(), "source type may have padding");
|
||||
return {reinterpret_cast<const std::uint8_t*>(src.data()), src.size_bytes()};
|
||||
}
|
||||
|
||||
//! \return `span<const std::uint8_t>` which represents the bytes at `&src`.
|
||||
template<typename T>
|
||||
span<const std::uint8_t> as_byte_span(const T& src) noexcept
|
||||
{
|
||||
static_assert(!std::is_empty<T>(), "empty types will not work -> sizeof == 1");
|
||||
static_assert(!has_padding<T>(), "source type may have padding");
|
||||
return {reinterpret_cast<const std::uint8_t*>(std::addressof(src)), sizeof(T)};
|
||||
}
|
||||
|
||||
//! \return `span<std::uint8_t>` which represents the bytes at `&src`.
|
||||
template<typename T>
|
||||
span<std::uint8_t> as_mut_byte_span(T& src) noexcept
|
||||
{
|
||||
static_assert(!std::is_empty<T>(), "empty types will not work -> sizeof == 1");
|
||||
static_assert(!has_padding<T>(), "source type may have padding");
|
||||
return {reinterpret_cast<std::uint8_t*>(std::addressof(src)), sizeof(T)};
|
||||
}
|
||||
|
||||
//! make a span from a std::string
|
||||
template<typename T>
|
||||
span<const T> strspan(const std::string &s) noexcept
|
||||
{
|
||||
static_assert(std::is_same<T, char>() || std::is_same<T, unsigned char>() || std::is_same<T, int8_t>() || std::is_same<T, uint8_t>(), "Unexpected type");
|
||||
return {reinterpret_cast<const T*>(s.data()), s.size()};
|
||||
}
|
||||
}
|
||||
27
src/3rdparty/fmt/LICENSE.rst
vendored
27
src/3rdparty/fmt/LICENSE.rst
vendored
@@ -1,27 +0,0 @@
|
||||
Copyright (c) 2012 - present, Victor Zverovich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
--- Optional exception to the license ---
|
||||
|
||||
As an exception, if, as a result of your compiling your source code, portions
|
||||
of this Software are embedded into a machine-executable object form of such
|
||||
source code, you may redistribute such embedded portions in such object form
|
||||
without including the above copyright and permission notices.
|
||||
505
src/3rdparty/fmt/README.rst
vendored
505
src/3rdparty/fmt/README.rst
vendored
@@ -1,505 +0,0 @@
|
||||
{fmt}
|
||||
=====
|
||||
|
||||
.. image:: https://travis-ci.org/fmtlib/fmt.png?branch=master
|
||||
:target: https://travis-ci.org/fmtlib/fmt
|
||||
|
||||
.. image:: https://ci.appveyor.com/api/projects/status/ehjkiefde6gucy1v
|
||||
:target: https://ci.appveyor.com/project/vitaut/fmt
|
||||
|
||||
.. image:: https://oss-fuzz-build-logs.storage.googleapis.com/badges/libfmt.svg
|
||||
:alt: fmt is continuously fuzzed at oss-fuzz
|
||||
:target: https://bugs.chromium.org/p/oss-fuzz/issues/list?\
|
||||
colspec=ID%20Type%20Component%20Status%20Proj%20Reported%20Owner%20\
|
||||
Summary&q=proj%3Dlibfmt&can=1
|
||||
|
||||
.. image:: https://img.shields.io/badge/stackoverflow-fmt-blue.svg
|
||||
:alt: Ask questions at StackOverflow with the tag fmt
|
||||
:target: https://stackoverflow.com/questions/tagged/fmt
|
||||
|
||||
**{fmt}** is an open-source formatting library providing a fast and safe
|
||||
alternative to C stdio and C++ iostreams.
|
||||
|
||||
If you like this project, please consider donating to BYSOL,
|
||||
an initiative to help victims of political repressions in Belarus:
|
||||
https://www.facebook.com/donate/759400044849707/108388587646909/.
|
||||
|
||||
`Documentation <https://fmt.dev>`__
|
||||
|
||||
Q&A: ask questions on `StackOverflow with the tag fmt
|
||||
<https://stackoverflow.com/questions/tagged/fmt>`_.
|
||||
|
||||
Try {fmt} in `Compiler Explorer <https://godbolt.org/z/Eq5763>`_.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* Simple `format API <https://fmt.dev/latest/api.html>`_ with positional arguments
|
||||
for localization
|
||||
* Implementation of `C++20 std::format
|
||||
<https://en.cppreference.com/w/cpp/utility/format>`__
|
||||
* `Format string syntax <https://fmt.dev/latest/syntax.html>`_ similar to Python's
|
||||
`format <https://docs.python.org/3/library/stdtypes.html#str.format>`_
|
||||
* Fast IEEE 754 floating-point formatter with correct rounding, shortness and
|
||||
round-trip guarantees.
|
||||
* Safe `printf implementation
|
||||
<https://fmt.dev/latest/api.html#printf-formatting>`_ including the POSIX
|
||||
extension for positional arguments
|
||||
* Extensibility: `support for user-defined types
|
||||
<https://fmt.dev/latest/api.html#formatting-user-defined-types>`_
|
||||
* High performance: faster than common standard library implementations of
|
||||
``(s)printf``, iostreams, ``to_string`` and ``to_chars``, see `Speed tests`_
|
||||
and `Converting a hundred million integers to strings per second
|
||||
<http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>`_
|
||||
* Small code size both in terms of source code with the minimum configuration
|
||||
consisting of just three files, ``core.h``, ``format.h`` and ``format-inl.h``,
|
||||
and compiled code; see `Compile time and code bloat`_
|
||||
* Reliability: the library has an extensive set of `tests
|
||||
<https://github.com/fmtlib/fmt/tree/master/test>`_ and is `continuously fuzzed
|
||||
<https://bugs.chromium.org/p/oss-fuzz/issues/list?colspec=ID%20Type%20
|
||||
Component%20Status%20Proj%20Reported%20Owner%20Summary&q=proj%3Dlibfmt&can=1>`_
|
||||
* Safety: the library is fully type safe, errors in format strings can be
|
||||
reported at compile time, automatic memory management prevents buffer overflow
|
||||
errors
|
||||
* Ease of use: small self-contained code base, no external dependencies,
|
||||
permissive MIT `license
|
||||
<https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_
|
||||
* `Portability <https://fmt.dev/latest/index.html#portability>`_ with
|
||||
consistent output across platforms and support for older compilers
|
||||
* Clean warning-free codebase even on high warning levels such as
|
||||
``-Wall -Wextra -pedantic``
|
||||
* Locale-independence by default
|
||||
* Optional header-only configuration enabled with the ``FMT_HEADER_ONLY`` macro
|
||||
|
||||
See the `documentation <https://fmt.dev>`_ for more details.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
**Print to stdout** (`run <https://godbolt.org/z/Tevcjh>`_)
|
||||
|
||||
.. code:: c++
|
||||
|
||||
#include <fmt/core.h>
|
||||
|
||||
int main() {
|
||||
fmt::print("Hello, world!\n");
|
||||
}
|
||||
|
||||
**Format a string** (`run <https://godbolt.org/z/oK8h33>`_)
|
||||
|
||||
.. code:: c++
|
||||
|
||||
std::string s = fmt::format("The answer is {}.", 42);
|
||||
// s == "The answer is 42."
|
||||
|
||||
**Format a string using positional arguments** (`run <https://godbolt.org/z/Yn7Txe>`_)
|
||||
|
||||
.. code:: c++
|
||||
|
||||
std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy");
|
||||
// s == "I'd rather be happy than right."
|
||||
|
||||
**Print chrono durations** (`run <https://godbolt.org/z/K8s4Mc>`_)
|
||||
|
||||
.. code:: c++
|
||||
|
||||
#include <fmt/chrono.h>
|
||||
|
||||
int main() {
|
||||
using namespace std::literals::chrono_literals;
|
||||
fmt::print("Default format: {} {}\n", 42s, 100ms);
|
||||
fmt::print("strftime-like format: {:%H:%M:%S}\n", 3h + 15min + 30s);
|
||||
}
|
||||
|
||||
Output::
|
||||
|
||||
Default format: 42s 100ms
|
||||
strftime-like format: 03:15:30
|
||||
|
||||
**Print a container** (`run <https://godbolt.org/z/MjsY7c>`_)
|
||||
|
||||
.. code:: c++
|
||||
|
||||
#include <vector>
|
||||
#include <fmt/ranges.h>
|
||||
|
||||
int main() {
|
||||
std::vector<int> v = {1, 2, 3};
|
||||
fmt::print("{}\n", v);
|
||||
}
|
||||
|
||||
Output::
|
||||
|
||||
{1, 2, 3}
|
||||
|
||||
**Check a format string at compile time**
|
||||
|
||||
.. code:: c++
|
||||
|
||||
std::string s = fmt::format(FMT_STRING("{:d}"), "don't panic");
|
||||
|
||||
This gives a compile-time error because ``d`` is an invalid format specifier for
|
||||
a string.
|
||||
|
||||
**Write a file from a single thread**
|
||||
|
||||
.. code:: c++
|
||||
|
||||
#include <fmt/os.h>
|
||||
|
||||
int main() {
|
||||
auto out = fmt::output_file("guide.txt");
|
||||
out.print("Don't {}", "Panic");
|
||||
}
|
||||
|
||||
This can be `5 to 9 times faster than fprintf
|
||||
<http://www.zverovich.net/2020/08/04/optimal-file-buffer-size.html>`_.
|
||||
|
||||
**Print with colors and text styles**
|
||||
|
||||
.. code:: c++
|
||||
|
||||
#include <fmt/color.h>
|
||||
|
||||
int main() {
|
||||
fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold,
|
||||
"Hello, {}!\n", "world");
|
||||
fmt::print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) |
|
||||
fmt::emphasis::underline, "Hello, {}!\n", "мир");
|
||||
fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic,
|
||||
"Hello, {}!\n", "世界");
|
||||
}
|
||||
|
||||
Output on a modern terminal:
|
||||
|
||||
.. image:: https://user-images.githubusercontent.com/
|
||||
576385/88485597-d312f600-cf2b-11ea-9cbe-61f535a86e28.png
|
||||
|
||||
Benchmarks
|
||||
----------
|
||||
|
||||
Speed tests
|
||||
~~~~~~~~~~~
|
||||
|
||||
================= ============= ===========
|
||||
Library Method Run Time, s
|
||||
================= ============= ===========
|
||||
libc printf 1.04
|
||||
libc++ std::ostream 3.05
|
||||
{fmt} 6.1.1 fmt::print 0.75
|
||||
Boost Format 1.67 boost::format 7.24
|
||||
Folly Format folly::format 2.23
|
||||
================= ============= ===========
|
||||
|
||||
{fmt} is the fastest of the benchmarked methods, ~35% faster than ``printf``.
|
||||
|
||||
The above results were generated by building ``tinyformat_test.cpp`` on macOS
|
||||
10.14.6 with ``clang++ -O3 -DNDEBUG -DSPEED_TEST -DHAVE_FORMAT``, and taking the
|
||||
best of three runs. In the test, the format string ``"%0.10f:%04d:%+g:%s:%p:%c:%%\n"``
|
||||
or equivalent is filled 2,000,000 times with output sent to ``/dev/null``; for
|
||||
further details refer to the `source
|
||||
<https://github.com/fmtlib/format-benchmark/blob/master/tinyformat_test.cpp>`_.
|
||||
|
||||
{fmt} is up to 10x faster than ``std::ostringstream`` and ``sprintf`` on
|
||||
floating-point formatting (`dtoa-benchmark <https://github.com/fmtlib/dtoa-benchmark>`_)
|
||||
and faster than `double-conversion <https://github.com/google/double-conversion>`_:
|
||||
|
||||
.. image:: https://user-images.githubusercontent.com/576385/
|
||||
69767160-cdaca400-112f-11ea-9fc5-347c9f83caad.png
|
||||
:target: https://fmt.dev/unknown_mac64_clang10.0.html
|
||||
|
||||
Compile time and code bloat
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The script `bloat-test.py
|
||||
<https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py>`_
|
||||
from `format-benchmark <https://github.com/fmtlib/format-benchmark>`_
|
||||
tests compile time and code bloat for nontrivial projects.
|
||||
It generates 100 translation units and uses ``printf()`` or its alternative
|
||||
five times in each to simulate a medium sized project. The resulting
|
||||
executable size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42),
|
||||
macOS Sierra, best of three) is shown in the following tables.
|
||||
|
||||
**Optimized build (-O3)**
|
||||
|
||||
============= =============== ==================== ==================
|
||||
Method Compile Time, s Executable size, KiB Stripped size, KiB
|
||||
============= =============== ==================== ==================
|
||||
printf 2.6 29 26
|
||||
printf+string 16.4 29 26
|
||||
iostreams 31.1 59 55
|
||||
{fmt} 19.0 37 34
|
||||
Boost Format 91.9 226 203
|
||||
Folly Format 115.7 101 88
|
||||
============= =============== ==================== ==================
|
||||
|
||||
As you can see, {fmt} has 60% less overhead in terms of resulting binary code
|
||||
size compared to iostreams and comes pretty close to ``printf``. Boost Format
|
||||
and Folly Format have the largest overheads.
|
||||
|
||||
``printf+string`` is the same as ``printf`` but with extra ``<string>``
|
||||
include to measure the overhead of the latter.
|
||||
|
||||
**Non-optimized build**
|
||||
|
||||
============= =============== ==================== ==================
|
||||
Method Compile Time, s Executable size, KiB Stripped size, KiB
|
||||
============= =============== ==================== ==================
|
||||
printf 2.2 33 30
|
||||
printf+string 16.0 33 30
|
||||
iostreams 28.3 56 52
|
||||
{fmt} 18.2 59 50
|
||||
Boost Format 54.1 365 303
|
||||
Folly Format 79.9 445 430
|
||||
============= =============== ==================== ==================
|
||||
|
||||
``libc``, ``lib(std)c++`` and ``libfmt`` are all linked as shared libraries to
|
||||
compare formatting function overhead only. Boost Format is a
|
||||
header-only library so it doesn't provide any linkage options.
|
||||
|
||||
Running the tests
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Please refer to `Building the library`__ for the instructions on how to build
|
||||
the library and run the unit tests.
|
||||
|
||||
__ https://fmt.dev/latest/usage.html#building-the-library
|
||||
|
||||
Benchmarks reside in a separate repository,
|
||||
`format-benchmarks <https://github.com/fmtlib/format-benchmark>`_,
|
||||
so to run the benchmarks you first need to clone this repository and
|
||||
generate Makefiles with CMake::
|
||||
|
||||
$ git clone --recursive https://github.com/fmtlib/format-benchmark.git
|
||||
$ cd format-benchmark
|
||||
$ cmake .
|
||||
|
||||
Then you can run the speed test::
|
||||
|
||||
$ make speed-test
|
||||
|
||||
or the bloat test::
|
||||
|
||||
$ make bloat-test
|
||||
|
||||
Projects using this library
|
||||
---------------------------
|
||||
|
||||
* `0 A.D. <https://play0ad.com/>`_: A free, open-source, cross-platform
|
||||
real-time strategy game
|
||||
|
||||
* `AMPL/MP <https://github.com/ampl/mp>`_:
|
||||
An open-source library for mathematical programming
|
||||
|
||||
* `Aseprite <https://github.com/aseprite/aseprite>`_:
|
||||
Animated sprite editor & pixel art tool
|
||||
|
||||
* `AvioBook <https://www.aviobook.aero/en>`_: A comprehensive aircraft
|
||||
operations suite
|
||||
|
||||
* `Celestia <https://celestia.space/>`_: Real-time 3D visualization of space
|
||||
|
||||
* `Ceph <https://ceph.com/>`_: A scalable distributed storage system
|
||||
|
||||
* `ccache <https://ccache.dev/>`_: A compiler cache
|
||||
|
||||
* `ClickHouse <https://github.com/ClickHouse/ClickHouse>`_: analytical database
|
||||
management system
|
||||
|
||||
* `CUAUV <http://cuauv.org/>`_: Cornell University's autonomous underwater
|
||||
vehicle
|
||||
|
||||
* `Drake <https://drake.mit.edu/>`_: A planning, control, and analysis toolbox
|
||||
for nonlinear dynamical systems (MIT)
|
||||
|
||||
* `Envoy <https://lyft.github.io/envoy/>`_: C++ L7 proxy and communication bus
|
||||
(Lyft)
|
||||
|
||||
* `FiveM <https://fivem.net/>`_: a modification framework for GTA V
|
||||
|
||||
* `Folly <https://github.com/facebook/folly>`_: Facebook open-source library
|
||||
|
||||
* `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_:
|
||||
Player vs Player Gaming Network with tweaks
|
||||
|
||||
* `KBEngine <https://github.com/kbengine/kbengine>`_: An open-source MMOG server
|
||||
engine
|
||||
|
||||
* `Keypirinha <https://keypirinha.com/>`_: A semantic launcher for Windows
|
||||
|
||||
* `Kodi <https://kodi.tv/>`_ (formerly xbmc): Home theater software
|
||||
|
||||
* `Knuth <https://kth.cash/>`_: High-performance Bitcoin full-node
|
||||
|
||||
* `Microsoft Verona <https://github.com/microsoft/verona>`_:
|
||||
Research programming language for concurrent ownership
|
||||
|
||||
* `MongoDB <https://mongodb.com/>`_: Distributed document database
|
||||
|
||||
* `MongoDB Smasher <https://github.com/duckie/mongo_smasher>`_: A small tool to
|
||||
generate randomized datasets
|
||||
|
||||
* `OpenSpace <https://openspaceproject.com/>`_: An open-source
|
||||
astrovisualization framework
|
||||
|
||||
* `PenUltima Online (POL) <https://www.polserver.com/>`_:
|
||||
An MMO server, compatible with most Ultima Online clients
|
||||
|
||||
* `PyTorch <https://github.com/pytorch/pytorch>`_: An open-source machine
|
||||
learning library
|
||||
|
||||
* `quasardb <https://www.quasardb.net/>`_: A distributed, high-performance,
|
||||
associative database
|
||||
|
||||
* `Quill <https://github.com/odygrd/quill>`_: Asynchronous low-latency logging library
|
||||
|
||||
* `QKW <https://github.com/ravijanjam/qkw>`_: Generalizing aliasing to simplify
|
||||
navigation, and executing complex multi-line terminal command sequences
|
||||
|
||||
* `readpe <https://bitbucket.org/sys_dev/readpe>`_: Read Portable Executable
|
||||
|
||||
* `redis-cerberus <https://github.com/HunanTV/redis-cerberus>`_: A Redis cluster
|
||||
proxy
|
||||
|
||||
* `redpanda <https://vectorized.io/redpanda>`_: A 10x faster Kafka® replacement
|
||||
for mission critical systems written in C++
|
||||
|
||||
* `rpclib <http://rpclib.net/>`_: A modern C++ msgpack-RPC server and client
|
||||
library
|
||||
|
||||
* `Salesforce Analytics Cloud
|
||||
<https://www.salesforce.com/analytics-cloud/overview/>`_:
|
||||
Business intelligence software
|
||||
|
||||
* `Scylla <https://www.scylladb.com/>`_: A Cassandra-compatible NoSQL data store
|
||||
that can handle 1 million transactions per second on a single server
|
||||
|
||||
* `Seastar <http://www.seastar-project.org/>`_: An advanced, open-source C++
|
||||
framework for high-performance server applications on modern hardware
|
||||
|
||||
* `spdlog <https://github.com/gabime/spdlog>`_: Super fast C++ logging library
|
||||
|
||||
* `Stellar <https://www.stellar.org/>`_: Financial platform
|
||||
|
||||
* `Touch Surgery <https://www.touchsurgery.com/>`_: Surgery simulator
|
||||
|
||||
* `TrinityCore <https://github.com/TrinityCore/TrinityCore>`_: Open-source
|
||||
MMORPG framework
|
||||
|
||||
* `Windows Terminal <https://github.com/microsoft/terminal>`_: The new Windows
|
||||
Terminal
|
||||
|
||||
`More... <https://github.com/search?q=fmtlib&type=Code>`_
|
||||
|
||||
If you are aware of other projects using this library, please let me know
|
||||
by `email <mailto:victor.zverovich@gmail.com>`_ or by submitting an
|
||||
`issue <https://github.com/fmtlib/fmt/issues>`_.
|
||||
|
||||
Motivation
|
||||
----------
|
||||
|
||||
So why yet another formatting library?
|
||||
|
||||
There are plenty of methods for doing this task, from standard ones like
|
||||
the printf family of function and iostreams to Boost Format and FastFormat
|
||||
libraries. The reason for creating a new library is that every existing
|
||||
solution that I found either had serious issues or didn't provide
|
||||
all the features I needed.
|
||||
|
||||
printf
|
||||
~~~~~~
|
||||
|
||||
The good thing about ``printf`` is that it is pretty fast and readily available
|
||||
being a part of the C standard library. The main drawback is that it
|
||||
doesn't support user-defined types. ``printf`` also has safety issues although
|
||||
they are somewhat mitigated with `__attribute__ ((format (printf, ...))
|
||||
<https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ in GCC.
|
||||
There is a POSIX extension that adds positional arguments required for
|
||||
`i18n <https://en.wikipedia.org/wiki/Internationalization_and_localization>`_
|
||||
to ``printf`` but it is not a part of C99 and may not be available on some
|
||||
platforms.
|
||||
|
||||
iostreams
|
||||
~~~~~~~~~
|
||||
|
||||
The main issue with iostreams is best illustrated with an example:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n";
|
||||
|
||||
which is a lot of typing compared to printf:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
printf("%.2f\n", 1.23456);
|
||||
|
||||
Matthew Wilson, the author of FastFormat, called this "chevron hell". iostreams
|
||||
don't support positional arguments by design.
|
||||
|
||||
The good part is that iostreams support user-defined types and are safe although
|
||||
error handling is awkward.
|
||||
|
||||
Boost Format
|
||||
~~~~~~~~~~~~
|
||||
|
||||
This is a very powerful library which supports both ``printf``-like format
|
||||
strings and positional arguments. Its main drawback is performance. According to
|
||||
various, benchmarks it is much slower than other methods considered here. Boost
|
||||
Format also has excessive build times and severe code bloat issues (see
|
||||
`Benchmarks`_).
|
||||
|
||||
FastFormat
|
||||
~~~~~~~~~~
|
||||
|
||||
This is an interesting library which is fast, safe and has positional arguments.
|
||||
However, it has significant limitations, citing its author:
|
||||
|
||||
Three features that have no hope of being accommodated within the
|
||||
current design are:
|
||||
|
||||
* Leading zeros (or any other non-space padding)
|
||||
* Octal/hexadecimal encoding
|
||||
* Runtime width/alignment specification
|
||||
|
||||
It is also quite big and has a heavy dependency, STLSoft, which might be too
|
||||
restrictive for using it in some projects.
|
||||
|
||||
Boost Spirit.Karma
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This is not really a formatting library but I decided to include it here for
|
||||
completeness. As iostreams, it suffers from the problem of mixing verbatim text
|
||||
with arguments. The library is pretty fast, but slower on integer formatting
|
||||
than ``fmt::format_to`` with format string compilation on Karma's own benchmark,
|
||||
see `Converting a hundred million integers to strings per second
|
||||
<http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>`_.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
{fmt} is distributed under the MIT `license
|
||||
<https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_.
|
||||
|
||||
Documentation License
|
||||
---------------------
|
||||
|
||||
The `Format String Syntax <https://fmt.dev/latest/syntax.html>`_
|
||||
section in the documentation is based on the one from Python `string module
|
||||
documentation <https://docs.python.org/3/library/string.html#module-string>`_.
|
||||
For this reason the documentation is distributed under the Python Software
|
||||
Foundation license available in `doc/python-license.txt
|
||||
<https://raw.github.com/fmtlib/fmt/master/doc/python-license.txt>`_.
|
||||
It only applies if you distribute the documentation of {fmt}.
|
||||
|
||||
Maintainers
|
||||
-----------
|
||||
|
||||
The {fmt} library is maintained by Victor Zverovich (`vitaut
|
||||
<https://github.com/vitaut>`_) and Jonathan Müller (`foonathan
|
||||
<https://github.com/foonathan>`_) with contributions from many other people.
|
||||
See `Contributors <https://github.com/fmtlib/fmt/graphs/contributors>`_ and
|
||||
`Releases <https://github.com/fmtlib/fmt/releases>`_ for some of the names.
|
||||
Let us know if your contribution is not listed or mentioned incorrectly and
|
||||
we'll make it right.
|
||||
1118
src/3rdparty/fmt/chrono.h
vendored
1118
src/3rdparty/fmt/chrono.h
vendored
File diff suppressed because it is too large
Load Diff
602
src/3rdparty/fmt/color.h
vendored
602
src/3rdparty/fmt/color.h
vendored
@@ -1,602 +0,0 @@
|
||||
// Formatting library for C++ - color support
|
||||
//
|
||||
// Copyright (c) 2018 - present, Victor Zverovich and fmt contributors
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_COLOR_H_
|
||||
#define FMT_COLOR_H_
|
||||
|
||||
#include "format.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
enum class color : uint32_t {
|
||||
alice_blue = 0xF0F8FF, // rgb(240,248,255)
|
||||
antique_white = 0xFAEBD7, // rgb(250,235,215)
|
||||
aqua = 0x00FFFF, // rgb(0,255,255)
|
||||
aquamarine = 0x7FFFD4, // rgb(127,255,212)
|
||||
azure = 0xF0FFFF, // rgb(240,255,255)
|
||||
beige = 0xF5F5DC, // rgb(245,245,220)
|
||||
bisque = 0xFFE4C4, // rgb(255,228,196)
|
||||
black = 0x000000, // rgb(0,0,0)
|
||||
blanched_almond = 0xFFEBCD, // rgb(255,235,205)
|
||||
blue = 0x0000FF, // rgb(0,0,255)
|
||||
blue_violet = 0x8A2BE2, // rgb(138,43,226)
|
||||
brown = 0xA52A2A, // rgb(165,42,42)
|
||||
burly_wood = 0xDEB887, // rgb(222,184,135)
|
||||
cadet_blue = 0x5F9EA0, // rgb(95,158,160)
|
||||
chartreuse = 0x7FFF00, // rgb(127,255,0)
|
||||
chocolate = 0xD2691E, // rgb(210,105,30)
|
||||
coral = 0xFF7F50, // rgb(255,127,80)
|
||||
cornflower_blue = 0x6495ED, // rgb(100,149,237)
|
||||
cornsilk = 0xFFF8DC, // rgb(255,248,220)
|
||||
crimson = 0xDC143C, // rgb(220,20,60)
|
||||
cyan = 0x00FFFF, // rgb(0,255,255)
|
||||
dark_blue = 0x00008B, // rgb(0,0,139)
|
||||
dark_cyan = 0x008B8B, // rgb(0,139,139)
|
||||
dark_golden_rod = 0xB8860B, // rgb(184,134,11)
|
||||
dark_gray = 0xA9A9A9, // rgb(169,169,169)
|
||||
dark_green = 0x006400, // rgb(0,100,0)
|
||||
dark_khaki = 0xBDB76B, // rgb(189,183,107)
|
||||
dark_magenta = 0x8B008B, // rgb(139,0,139)
|
||||
dark_olive_green = 0x556B2F, // rgb(85,107,47)
|
||||
dark_orange = 0xFF8C00, // rgb(255,140,0)
|
||||
dark_orchid = 0x9932CC, // rgb(153,50,204)
|
||||
dark_red = 0x8B0000, // rgb(139,0,0)
|
||||
dark_salmon = 0xE9967A, // rgb(233,150,122)
|
||||
dark_sea_green = 0x8FBC8F, // rgb(143,188,143)
|
||||
dark_slate_blue = 0x483D8B, // rgb(72,61,139)
|
||||
dark_slate_gray = 0x2F4F4F, // rgb(47,79,79)
|
||||
dark_turquoise = 0x00CED1, // rgb(0,206,209)
|
||||
dark_violet = 0x9400D3, // rgb(148,0,211)
|
||||
deep_pink = 0xFF1493, // rgb(255,20,147)
|
||||
deep_sky_blue = 0x00BFFF, // rgb(0,191,255)
|
||||
dim_gray = 0x696969, // rgb(105,105,105)
|
||||
dodger_blue = 0x1E90FF, // rgb(30,144,255)
|
||||
fire_brick = 0xB22222, // rgb(178,34,34)
|
||||
floral_white = 0xFFFAF0, // rgb(255,250,240)
|
||||
forest_green = 0x228B22, // rgb(34,139,34)
|
||||
fuchsia = 0xFF00FF, // rgb(255,0,255)
|
||||
gainsboro = 0xDCDCDC, // rgb(220,220,220)
|
||||
ghost_white = 0xF8F8FF, // rgb(248,248,255)
|
||||
gold = 0xFFD700, // rgb(255,215,0)
|
||||
golden_rod = 0xDAA520, // rgb(218,165,32)
|
||||
gray = 0x808080, // rgb(128,128,128)
|
||||
green = 0x008000, // rgb(0,128,0)
|
||||
green_yellow = 0xADFF2F, // rgb(173,255,47)
|
||||
honey_dew = 0xF0FFF0, // rgb(240,255,240)
|
||||
hot_pink = 0xFF69B4, // rgb(255,105,180)
|
||||
indian_red = 0xCD5C5C, // rgb(205,92,92)
|
||||
indigo = 0x4B0082, // rgb(75,0,130)
|
||||
ivory = 0xFFFFF0, // rgb(255,255,240)
|
||||
khaki = 0xF0E68C, // rgb(240,230,140)
|
||||
lavender = 0xE6E6FA, // rgb(230,230,250)
|
||||
lavender_blush = 0xFFF0F5, // rgb(255,240,245)
|
||||
lawn_green = 0x7CFC00, // rgb(124,252,0)
|
||||
lemon_chiffon = 0xFFFACD, // rgb(255,250,205)
|
||||
light_blue = 0xADD8E6, // rgb(173,216,230)
|
||||
light_coral = 0xF08080, // rgb(240,128,128)
|
||||
light_cyan = 0xE0FFFF, // rgb(224,255,255)
|
||||
light_golden_rod_yellow = 0xFAFAD2, // rgb(250,250,210)
|
||||
light_gray = 0xD3D3D3, // rgb(211,211,211)
|
||||
light_green = 0x90EE90, // rgb(144,238,144)
|
||||
light_pink = 0xFFB6C1, // rgb(255,182,193)
|
||||
light_salmon = 0xFFA07A, // rgb(255,160,122)
|
||||
light_sea_green = 0x20B2AA, // rgb(32,178,170)
|
||||
light_sky_blue = 0x87CEFA, // rgb(135,206,250)
|
||||
light_slate_gray = 0x778899, // rgb(119,136,153)
|
||||
light_steel_blue = 0xB0C4DE, // rgb(176,196,222)
|
||||
light_yellow = 0xFFFFE0, // rgb(255,255,224)
|
||||
lime = 0x00FF00, // rgb(0,255,0)
|
||||
lime_green = 0x32CD32, // rgb(50,205,50)
|
||||
linen = 0xFAF0E6, // rgb(250,240,230)
|
||||
magenta = 0xFF00FF, // rgb(255,0,255)
|
||||
maroon = 0x800000, // rgb(128,0,0)
|
||||
medium_aquamarine = 0x66CDAA, // rgb(102,205,170)
|
||||
medium_blue = 0x0000CD, // rgb(0,0,205)
|
||||
medium_orchid = 0xBA55D3, // rgb(186,85,211)
|
||||
medium_purple = 0x9370DB, // rgb(147,112,219)
|
||||
medium_sea_green = 0x3CB371, // rgb(60,179,113)
|
||||
medium_slate_blue = 0x7B68EE, // rgb(123,104,238)
|
||||
medium_spring_green = 0x00FA9A, // rgb(0,250,154)
|
||||
medium_turquoise = 0x48D1CC, // rgb(72,209,204)
|
||||
medium_violet_red = 0xC71585, // rgb(199,21,133)
|
||||
midnight_blue = 0x191970, // rgb(25,25,112)
|
||||
mint_cream = 0xF5FFFA, // rgb(245,255,250)
|
||||
misty_rose = 0xFFE4E1, // rgb(255,228,225)
|
||||
moccasin = 0xFFE4B5, // rgb(255,228,181)
|
||||
navajo_white = 0xFFDEAD, // rgb(255,222,173)
|
||||
navy = 0x000080, // rgb(0,0,128)
|
||||
old_lace = 0xFDF5E6, // rgb(253,245,230)
|
||||
olive = 0x808000, // rgb(128,128,0)
|
||||
olive_drab = 0x6B8E23, // rgb(107,142,35)
|
||||
orange = 0xFFA500, // rgb(255,165,0)
|
||||
orange_red = 0xFF4500, // rgb(255,69,0)
|
||||
orchid = 0xDA70D6, // rgb(218,112,214)
|
||||
pale_golden_rod = 0xEEE8AA, // rgb(238,232,170)
|
||||
pale_green = 0x98FB98, // rgb(152,251,152)
|
||||
pale_turquoise = 0xAFEEEE, // rgb(175,238,238)
|
||||
pale_violet_red = 0xDB7093, // rgb(219,112,147)
|
||||
papaya_whip = 0xFFEFD5, // rgb(255,239,213)
|
||||
peach_puff = 0xFFDAB9, // rgb(255,218,185)
|
||||
peru = 0xCD853F, // rgb(205,133,63)
|
||||
pink = 0xFFC0CB, // rgb(255,192,203)
|
||||
plum = 0xDDA0DD, // rgb(221,160,221)
|
||||
powder_blue = 0xB0E0E6, // rgb(176,224,230)
|
||||
purple = 0x800080, // rgb(128,0,128)
|
||||
rebecca_purple = 0x663399, // rgb(102,51,153)
|
||||
red = 0xFF0000, // rgb(255,0,0)
|
||||
rosy_brown = 0xBC8F8F, // rgb(188,143,143)
|
||||
royal_blue = 0x4169E1, // rgb(65,105,225)
|
||||
saddle_brown = 0x8B4513, // rgb(139,69,19)
|
||||
salmon = 0xFA8072, // rgb(250,128,114)
|
||||
sandy_brown = 0xF4A460, // rgb(244,164,96)
|
||||
sea_green = 0x2E8B57, // rgb(46,139,87)
|
||||
sea_shell = 0xFFF5EE, // rgb(255,245,238)
|
||||
sienna = 0xA0522D, // rgb(160,82,45)
|
||||
silver = 0xC0C0C0, // rgb(192,192,192)
|
||||
sky_blue = 0x87CEEB, // rgb(135,206,235)
|
||||
slate_blue = 0x6A5ACD, // rgb(106,90,205)
|
||||
slate_gray = 0x708090, // rgb(112,128,144)
|
||||
snow = 0xFFFAFA, // rgb(255,250,250)
|
||||
spring_green = 0x00FF7F, // rgb(0,255,127)
|
||||
steel_blue = 0x4682B4, // rgb(70,130,180)
|
||||
tan = 0xD2B48C, // rgb(210,180,140)
|
||||
teal = 0x008080, // rgb(0,128,128)
|
||||
thistle = 0xD8BFD8, // rgb(216,191,216)
|
||||
tomato = 0xFF6347, // rgb(255,99,71)
|
||||
turquoise = 0x40E0D0, // rgb(64,224,208)
|
||||
violet = 0xEE82EE, // rgb(238,130,238)
|
||||
wheat = 0xF5DEB3, // rgb(245,222,179)
|
||||
white = 0xFFFFFF, // rgb(255,255,255)
|
||||
white_smoke = 0xF5F5F5, // rgb(245,245,245)
|
||||
yellow = 0xFFFF00, // rgb(255,255,0)
|
||||
yellow_green = 0x9ACD32 // rgb(154,205,50)
|
||||
}; // enum class color
|
||||
|
||||
enum class terminal_color : uint8_t {
|
||||
black = 30,
|
||||
red,
|
||||
green,
|
||||
yellow,
|
||||
blue,
|
||||
magenta,
|
||||
cyan,
|
||||
white,
|
||||
bright_black = 90,
|
||||
bright_red,
|
||||
bright_green,
|
||||
bright_yellow,
|
||||
bright_blue,
|
||||
bright_magenta,
|
||||
bright_cyan,
|
||||
bright_white
|
||||
};
|
||||
|
||||
enum class emphasis : uint8_t {
|
||||
bold = 1,
|
||||
italic = 1 << 1,
|
||||
underline = 1 << 2,
|
||||
strikethrough = 1 << 3
|
||||
};
|
||||
|
||||
// rgb is a struct for red, green and blue colors.
|
||||
// Using the name "rgb" makes some editors show the color in a tooltip.
|
||||
struct rgb {
|
||||
FMT_CONSTEXPR rgb() : r(0), g(0), b(0) {}
|
||||
FMT_CONSTEXPR rgb(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {}
|
||||
FMT_CONSTEXPR rgb(uint32_t hex)
|
||||
: r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b(hex & 0xFF) {}
|
||||
FMT_CONSTEXPR rgb(color hex)
|
||||
: r((uint32_t(hex) >> 16) & 0xFF),
|
||||
g((uint32_t(hex) >> 8) & 0xFF),
|
||||
b(uint32_t(hex) & 0xFF) {}
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
// color is a struct of either a rgb color or a terminal color.
|
||||
struct color_type {
|
||||
FMT_CONSTEXPR color_type() FMT_NOEXCEPT : is_rgb(), value{} {}
|
||||
FMT_CONSTEXPR color_type(color rgb_color) FMT_NOEXCEPT : is_rgb(true),
|
||||
value{} {
|
||||
value.rgb_color = static_cast<uint32_t>(rgb_color);
|
||||
}
|
||||
FMT_CONSTEXPR color_type(rgb rgb_color) FMT_NOEXCEPT : is_rgb(true), value{} {
|
||||
value.rgb_color = (static_cast<uint32_t>(rgb_color.r) << 16) |
|
||||
(static_cast<uint32_t>(rgb_color.g) << 8) | rgb_color.b;
|
||||
}
|
||||
FMT_CONSTEXPR color_type(terminal_color term_color) FMT_NOEXCEPT : is_rgb(),
|
||||
value{} {
|
||||
value.term_color = static_cast<uint8_t>(term_color);
|
||||
}
|
||||
bool is_rgb;
|
||||
union color_union {
|
||||
uint8_t term_color;
|
||||
uint32_t rgb_color;
|
||||
} value;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
// Experimental text formatting support.
|
||||
class text_style {
|
||||
public:
|
||||
FMT_CONSTEXPR text_style(emphasis em = emphasis()) FMT_NOEXCEPT
|
||||
: set_foreground_color(),
|
||||
set_background_color(),
|
||||
ems(em) {}
|
||||
|
||||
FMT_CONSTEXPR text_style& operator|=(const text_style& rhs) {
|
||||
if (!set_foreground_color) {
|
||||
set_foreground_color = rhs.set_foreground_color;
|
||||
foreground_color = rhs.foreground_color;
|
||||
} else if (rhs.set_foreground_color) {
|
||||
if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb)
|
||||
FMT_THROW(format_error("can't OR a terminal color"));
|
||||
foreground_color.value.rgb_color |= rhs.foreground_color.value.rgb_color;
|
||||
}
|
||||
|
||||
if (!set_background_color) {
|
||||
set_background_color = rhs.set_background_color;
|
||||
background_color = rhs.background_color;
|
||||
} else if (rhs.set_background_color) {
|
||||
if (!background_color.is_rgb || !rhs.background_color.is_rgb)
|
||||
FMT_THROW(format_error("can't OR a terminal color"));
|
||||
background_color.value.rgb_color |= rhs.background_color.value.rgb_color;
|
||||
}
|
||||
|
||||
ems = static_cast<emphasis>(static_cast<uint8_t>(ems) |
|
||||
static_cast<uint8_t>(rhs.ems));
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend FMT_CONSTEXPR text_style operator|(text_style lhs,
|
||||
const text_style& rhs) {
|
||||
return lhs |= rhs;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR text_style& operator&=(const text_style& rhs) {
|
||||
if (!set_foreground_color) {
|
||||
set_foreground_color = rhs.set_foreground_color;
|
||||
foreground_color = rhs.foreground_color;
|
||||
} else if (rhs.set_foreground_color) {
|
||||
if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb)
|
||||
FMT_THROW(format_error("can't AND a terminal color"));
|
||||
foreground_color.value.rgb_color &= rhs.foreground_color.value.rgb_color;
|
||||
}
|
||||
|
||||
if (!set_background_color) {
|
||||
set_background_color = rhs.set_background_color;
|
||||
background_color = rhs.background_color;
|
||||
} else if (rhs.set_background_color) {
|
||||
if (!background_color.is_rgb || !rhs.background_color.is_rgb)
|
||||
FMT_THROW(format_error("can't AND a terminal color"));
|
||||
background_color.value.rgb_color &= rhs.background_color.value.rgb_color;
|
||||
}
|
||||
|
||||
ems = static_cast<emphasis>(static_cast<uint8_t>(ems) &
|
||||
static_cast<uint8_t>(rhs.ems));
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend FMT_CONSTEXPR text_style operator&(text_style lhs,
|
||||
const text_style& rhs) {
|
||||
return lhs &= rhs;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR bool has_foreground() const FMT_NOEXCEPT {
|
||||
return set_foreground_color;
|
||||
}
|
||||
FMT_CONSTEXPR bool has_background() const FMT_NOEXCEPT {
|
||||
return set_background_color;
|
||||
}
|
||||
FMT_CONSTEXPR bool has_emphasis() const FMT_NOEXCEPT {
|
||||
return static_cast<uint8_t>(ems) != 0;
|
||||
}
|
||||
FMT_CONSTEXPR detail::color_type get_foreground() const FMT_NOEXCEPT {
|
||||
FMT_ASSERT(has_foreground(), "no foreground specified for this style");
|
||||
return foreground_color;
|
||||
}
|
||||
FMT_CONSTEXPR detail::color_type get_background() const FMT_NOEXCEPT {
|
||||
FMT_ASSERT(has_background(), "no background specified for this style");
|
||||
return background_color;
|
||||
}
|
||||
FMT_CONSTEXPR emphasis get_emphasis() const FMT_NOEXCEPT {
|
||||
FMT_ASSERT(has_emphasis(), "no emphasis specified for this style");
|
||||
return ems;
|
||||
}
|
||||
|
||||
private:
|
||||
FMT_CONSTEXPR text_style(bool is_foreground,
|
||||
detail::color_type text_color) FMT_NOEXCEPT
|
||||
: set_foreground_color(),
|
||||
set_background_color(),
|
||||
ems() {
|
||||
if (is_foreground) {
|
||||
foreground_color = text_color;
|
||||
set_foreground_color = true;
|
||||
} else {
|
||||
background_color = text_color;
|
||||
set_background_color = true;
|
||||
}
|
||||
}
|
||||
|
||||
friend FMT_CONSTEXPR_DECL text_style fg(detail::color_type foreground)
|
||||
FMT_NOEXCEPT;
|
||||
friend FMT_CONSTEXPR_DECL text_style bg(detail::color_type background)
|
||||
FMT_NOEXCEPT;
|
||||
|
||||
detail::color_type foreground_color;
|
||||
detail::color_type background_color;
|
||||
bool set_foreground_color;
|
||||
bool set_background_color;
|
||||
emphasis ems;
|
||||
};
|
||||
|
||||
FMT_CONSTEXPR text_style fg(detail::color_type foreground) FMT_NOEXCEPT {
|
||||
return text_style(/*is_foreground=*/true, foreground);
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR text_style bg(detail::color_type background) FMT_NOEXCEPT {
|
||||
return text_style(/*is_foreground=*/false, background);
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR text_style operator|(emphasis lhs, emphasis rhs) FMT_NOEXCEPT {
|
||||
return text_style(lhs) | rhs;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Char> struct ansi_color_escape {
|
||||
FMT_CONSTEXPR ansi_color_escape(detail::color_type text_color,
|
||||
const char* esc) FMT_NOEXCEPT {
|
||||
// If we have a terminal color, we need to output another escape code
|
||||
// sequence.
|
||||
if (!text_color.is_rgb) {
|
||||
bool is_background = esc == detail::data::background_color;
|
||||
uint32_t value = text_color.value.term_color;
|
||||
// Background ASCII codes are the same as the foreground ones but with
|
||||
// 10 more.
|
||||
if (is_background) value += 10u;
|
||||
|
||||
size_t index = 0;
|
||||
buffer[index++] = static_cast<Char>('\x1b');
|
||||
buffer[index++] = static_cast<Char>('[');
|
||||
|
||||
if (value >= 100u) {
|
||||
buffer[index++] = static_cast<Char>('1');
|
||||
value %= 100u;
|
||||
}
|
||||
buffer[index++] = static_cast<Char>('0' + value / 10u);
|
||||
buffer[index++] = static_cast<Char>('0' + value % 10u);
|
||||
|
||||
buffer[index++] = static_cast<Char>('m');
|
||||
buffer[index++] = static_cast<Char>('\0');
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
buffer[i] = static_cast<Char>(esc[i]);
|
||||
}
|
||||
rgb color(text_color.value.rgb_color);
|
||||
to_esc(color.r, buffer + 7, ';');
|
||||
to_esc(color.g, buffer + 11, ';');
|
||||
to_esc(color.b, buffer + 15, 'm');
|
||||
buffer[19] = static_cast<Char>(0);
|
||||
}
|
||||
FMT_CONSTEXPR ansi_color_escape(emphasis em) FMT_NOEXCEPT {
|
||||
uint8_t em_codes[4] = {};
|
||||
uint8_t em_bits = static_cast<uint8_t>(em);
|
||||
if (em_bits & static_cast<uint8_t>(emphasis::bold)) em_codes[0] = 1;
|
||||
if (em_bits & static_cast<uint8_t>(emphasis::italic)) em_codes[1] = 3;
|
||||
if (em_bits & static_cast<uint8_t>(emphasis::underline)) em_codes[2] = 4;
|
||||
if (em_bits & static_cast<uint8_t>(emphasis::strikethrough))
|
||||
em_codes[3] = 9;
|
||||
|
||||
size_t index = 0;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (!em_codes[i]) continue;
|
||||
buffer[index++] = static_cast<Char>('\x1b');
|
||||
buffer[index++] = static_cast<Char>('[');
|
||||
buffer[index++] = static_cast<Char>('0' + em_codes[i]);
|
||||
buffer[index++] = static_cast<Char>('m');
|
||||
}
|
||||
buffer[index++] = static_cast<Char>(0);
|
||||
}
|
||||
FMT_CONSTEXPR operator const Char*() const FMT_NOEXCEPT { return buffer; }
|
||||
|
||||
FMT_CONSTEXPR const Char* begin() const FMT_NOEXCEPT { return buffer; }
|
||||
FMT_CONSTEXPR const Char* end() const FMT_NOEXCEPT {
|
||||
return buffer + std::char_traits<Char>::length(buffer);
|
||||
}
|
||||
|
||||
private:
|
||||
Char buffer[7u + 3u * 4u + 1u];
|
||||
|
||||
static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out,
|
||||
char delimiter) FMT_NOEXCEPT {
|
||||
out[0] = static_cast<Char>('0' + c / 100);
|
||||
out[1] = static_cast<Char>('0' + c / 10 % 10);
|
||||
out[2] = static_cast<Char>('0' + c % 10);
|
||||
out[3] = static_cast<Char>(delimiter);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR ansi_color_escape<Char> make_foreground_color(
|
||||
detail::color_type foreground) FMT_NOEXCEPT {
|
||||
return ansi_color_escape<Char>(foreground, detail::data::foreground_color);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR ansi_color_escape<Char> make_background_color(
|
||||
detail::color_type background) FMT_NOEXCEPT {
|
||||
return ansi_color_escape<Char>(background, detail::data::background_color);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR ansi_color_escape<Char> make_emphasis(emphasis em) FMT_NOEXCEPT {
|
||||
return ansi_color_escape<Char>(em);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline void fputs(const Char* chars, FILE* stream) FMT_NOEXCEPT {
|
||||
std::fputs(chars, stream);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void fputs<wchar_t>(const wchar_t* chars, FILE* stream) FMT_NOEXCEPT {
|
||||
std::fputws(chars, stream);
|
||||
}
|
||||
|
||||
template <typename Char> inline void reset_color(FILE* stream) FMT_NOEXCEPT {
|
||||
fputs(detail::data::reset_color, stream);
|
||||
}
|
||||
|
||||
template <> inline void reset_color<wchar_t>(FILE* stream) FMT_NOEXCEPT {
|
||||
fputs(detail::data::wreset_color, stream);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline void reset_color(buffer<Char>& buffer) FMT_NOEXCEPT {
|
||||
const char* begin = data::reset_color;
|
||||
const char* end = begin + sizeof(data::reset_color) - 1;
|
||||
buffer.append(begin, end);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
void vformat_to(buffer<Char>& buf, const text_style& ts,
|
||||
basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
bool has_style = false;
|
||||
if (ts.has_emphasis()) {
|
||||
has_style = true;
|
||||
auto emphasis = detail::make_emphasis<Char>(ts.get_emphasis());
|
||||
buf.append(emphasis.begin(), emphasis.end());
|
||||
}
|
||||
if (ts.has_foreground()) {
|
||||
has_style = true;
|
||||
auto foreground = detail::make_foreground_color<Char>(ts.get_foreground());
|
||||
buf.append(foreground.begin(), foreground.end());
|
||||
}
|
||||
if (ts.has_background()) {
|
||||
has_style = true;
|
||||
auto background = detail::make_background_color<Char>(ts.get_background());
|
||||
buf.append(background.begin(), background.end());
|
||||
}
|
||||
detail::vformat_to(buf, format_str, args);
|
||||
if (has_style) detail::reset_color<Char>(buf);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
void vprint(std::FILE* f, const text_style& ts, const S& format,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buf;
|
||||
detail::vformat_to(buf, ts, to_string_view(format), args);
|
||||
buf.push_back(Char(0));
|
||||
detail::fputs(buf.data(), f);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Formats a string and prints it to the specified file stream using ANSI
|
||||
escape sequences to specify text formatting.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
|
||||
"Elapsed time: {0:.2f} seconds", 1.23);
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_string<S>::value)>
|
||||
void print(std::FILE* f, const text_style& ts, const S& format_str,
|
||||
const Args&... args) {
|
||||
vprint(f, ts, format_str,
|
||||
fmt::make_args_checked<Args...>(format_str, args...));
|
||||
}
|
||||
|
||||
/**
|
||||
Formats a string and prints it to stdout using ANSI escape sequences to
|
||||
specify text formatting.
|
||||
Example:
|
||||
fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
|
||||
"Elapsed time: {0:.2f} seconds", 1.23);
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_string<S>::value)>
|
||||
void print(const text_style& ts, const S& format_str, const Args&... args) {
|
||||
return print(stdout, ts, format_str, args...);
|
||||
}
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline std::basic_string<Char> vformat(
|
||||
const text_style& ts, const S& format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buf;
|
||||
detail::vformat_to(buf, ts, to_string_view(format_str), args);
|
||||
return fmt::to_string(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Formats arguments and returns the result as a string using ANSI
|
||||
escape sequences to specify text formatting.
|
||||
|
||||
**Example**::
|
||||
|
||||
#include <fmt/color.h>
|
||||
std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red),
|
||||
"The answer is {}", 42);
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args, typename Char = char_t<S>>
|
||||
inline std::basic_string<Char> format(const text_style& ts, const S& format_str,
|
||||
const Args&... args) {
|
||||
return vformat(ts, to_string_view(format_str),
|
||||
fmt::make_args_checked<Args...>(format_str, args...));
|
||||
}
|
||||
|
||||
/**
|
||||
Formats a string with the given text_style and writes the output to ``out``.
|
||||
*/
|
||||
template <typename OutputIt, typename Char,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt>::value)>
|
||||
OutputIt vformat_to(
|
||||
OutputIt out, const text_style& ts, basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
decltype(detail::get_buffer<Char>(out)) buf(detail::get_buffer_init(out));
|
||||
detail::vformat_to(buf, ts, format_str, args);
|
||||
return detail::get_iterator(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Formats arguments with the given text_style, writes the result to the output
|
||||
iterator ``out`` and returns the iterator past the end of the output range.
|
||||
|
||||
**Example**::
|
||||
|
||||
std::vector<char> out;
|
||||
fmt::format_to(std::back_inserter(out),
|
||||
fmt::emphasis::bold | fg(fmt::color::red), "{}", 42);
|
||||
\endrst
|
||||
*/
|
||||
template <typename OutputIt, typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt>::value&&
|
||||
detail::is_string<S>::value)>
|
||||
inline OutputIt format_to(OutputIt out, const text_style& ts,
|
||||
const S& format_str, Args&&... args) {
|
||||
return vformat_to(out, ts, to_string_view(format_str),
|
||||
fmt::make_args_checked<Args...>(format_str, args...));
|
||||
}
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_COLOR_H_
|
||||
699
src/3rdparty/fmt/compile.h
vendored
699
src/3rdparty/fmt/compile.h
vendored
@@ -1,699 +0,0 @@
|
||||
// Formatting library for C++ - experimental format string compilation
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich and fmt contributors
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_COMPILE_H_
|
||||
#define FMT_COMPILE_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "format.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
// A compile-time string which is compiled into fast formatting code.
|
||||
class compiled_string {};
|
||||
|
||||
template <typename S>
|
||||
struct is_compiled_string : std::is_base_of<compiled_string, S> {};
|
||||
|
||||
/**
|
||||
\rst
|
||||
Converts a string literal *s* into a format string that will be parsed at
|
||||
compile time and converted into efficient formatting code. Requires C++17
|
||||
``constexpr if`` compiler support.
|
||||
|
||||
**Example**::
|
||||
|
||||
// Converts 42 into std::string using the most efficient method and no
|
||||
// runtime format string processing.
|
||||
std::string s = fmt::format(FMT_COMPILE("{}"), 42);
|
||||
\endrst
|
||||
*/
|
||||
#define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::detail::compiled_string)
|
||||
|
||||
template <typename T, typename... Tail>
|
||||
const T& first(const T& value, const Tail&...) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// Part of a compiled format string. It can be either literal text or a
|
||||
// replacement field.
|
||||
template <typename Char> struct format_part {
|
||||
enum class kind { arg_index, arg_name, text, replacement };
|
||||
|
||||
struct replacement {
|
||||
arg_ref<Char> arg_id;
|
||||
dynamic_format_specs<Char> specs;
|
||||
};
|
||||
|
||||
kind part_kind;
|
||||
union value {
|
||||
int arg_index;
|
||||
basic_string_view<Char> str;
|
||||
replacement repl;
|
||||
|
||||
FMT_CONSTEXPR value(int index = 0) : arg_index(index) {}
|
||||
FMT_CONSTEXPR value(basic_string_view<Char> s) : str(s) {}
|
||||
FMT_CONSTEXPR value(replacement r) : repl(r) {}
|
||||
} val;
|
||||
// Position past the end of the argument id.
|
||||
const Char* arg_id_end = nullptr;
|
||||
|
||||
FMT_CONSTEXPR format_part(kind k = kind::arg_index, value v = {})
|
||||
: part_kind(k), val(v) {}
|
||||
|
||||
static FMT_CONSTEXPR format_part make_arg_index(int index) {
|
||||
return format_part(kind::arg_index, index);
|
||||
}
|
||||
static FMT_CONSTEXPR format_part make_arg_name(basic_string_view<Char> name) {
|
||||
return format_part(kind::arg_name, name);
|
||||
}
|
||||
static FMT_CONSTEXPR format_part make_text(basic_string_view<Char> text) {
|
||||
return format_part(kind::text, text);
|
||||
}
|
||||
static FMT_CONSTEXPR format_part make_replacement(replacement repl) {
|
||||
return format_part(kind::replacement, repl);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char> struct part_counter {
|
||||
unsigned num_parts = 0;
|
||||
|
||||
FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) {
|
||||
if (begin != end) ++num_parts;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR int on_arg_id() { return ++num_parts, 0; }
|
||||
FMT_CONSTEXPR int on_arg_id(int) { return ++num_parts, 0; }
|
||||
FMT_CONSTEXPR int on_arg_id(basic_string_view<Char>) {
|
||||
return ++num_parts, 0;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void on_replacement_field(int, const Char*) {}
|
||||
|
||||
FMT_CONSTEXPR const Char* on_format_specs(int, const Char* begin,
|
||||
const Char* end) {
|
||||
// Find the matching brace.
|
||||
unsigned brace_counter = 0;
|
||||
for (; begin != end; ++begin) {
|
||||
if (*begin == '{') {
|
||||
++brace_counter;
|
||||
} else if (*begin == '}') {
|
||||
if (brace_counter == 0u) break;
|
||||
--brace_counter;
|
||||
}
|
||||
}
|
||||
return begin;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void on_error(const char*) {}
|
||||
};
|
||||
|
||||
// Counts the number of parts in a format string.
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR unsigned count_parts(basic_string_view<Char> format_str) {
|
||||
part_counter<Char> counter;
|
||||
parse_format_string<true>(format_str, counter);
|
||||
return counter.num_parts;
|
||||
}
|
||||
|
||||
template <typename Char, typename PartHandler>
|
||||
class format_string_compiler : public error_handler {
|
||||
private:
|
||||
using part = format_part<Char>;
|
||||
|
||||
PartHandler handler_;
|
||||
part part_;
|
||||
basic_string_view<Char> format_str_;
|
||||
basic_format_parse_context<Char> parse_context_;
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR format_string_compiler(basic_string_view<Char> format_str,
|
||||
PartHandler handler)
|
||||
: handler_(handler),
|
||||
format_str_(format_str),
|
||||
parse_context_(format_str) {}
|
||||
|
||||
FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) {
|
||||
if (begin != end)
|
||||
handler_(part::make_text({begin, to_unsigned(end - begin)}));
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR int on_arg_id() {
|
||||
part_ = part::make_arg_index(parse_context_.next_arg_id());
|
||||
return 0;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR int on_arg_id(int id) {
|
||||
parse_context_.check_arg_id(id);
|
||||
part_ = part::make_arg_index(id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR int on_arg_id(basic_string_view<Char> id) {
|
||||
part_ = part::make_arg_name(id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void on_replacement_field(int, const Char* ptr) {
|
||||
part_.arg_id_end = ptr;
|
||||
handler_(part_);
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR const Char* on_format_specs(int, const Char* begin,
|
||||
const Char* end) {
|
||||
auto repl = typename part::replacement();
|
||||
dynamic_specs_handler<basic_format_parse_context<Char>> handler(
|
||||
repl.specs, parse_context_);
|
||||
auto it = parse_format_specs(begin, end, handler);
|
||||
if (*it != '}') on_error("missing '}' in format string");
|
||||
repl.arg_id = part_.part_kind == part::kind::arg_index
|
||||
? arg_ref<Char>(part_.val.arg_index)
|
||||
: arg_ref<Char>(part_.val.str);
|
||||
auto part = part::make_replacement(repl);
|
||||
part.arg_id_end = begin;
|
||||
handler_(part);
|
||||
return it;
|
||||
}
|
||||
};
|
||||
|
||||
// Compiles a format string and invokes handler(part) for each parsed part.
|
||||
template <bool IS_CONSTEXPR, typename Char, typename PartHandler>
|
||||
FMT_CONSTEXPR void compile_format_string(basic_string_view<Char> format_str,
|
||||
PartHandler handler) {
|
||||
parse_format_string<IS_CONSTEXPR>(
|
||||
format_str,
|
||||
format_string_compiler<Char, PartHandler>(format_str, handler));
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename Context, typename Id>
|
||||
void format_arg(
|
||||
basic_format_parse_context<typename Context::char_type>& parse_ctx,
|
||||
Context& ctx, Id arg_id) {
|
||||
ctx.advance_to(visit_format_arg(
|
||||
arg_formatter<OutputIt, typename Context::char_type>(ctx, &parse_ctx),
|
||||
ctx.arg(arg_id)));
|
||||
}
|
||||
|
||||
// vformat_to is defined in a subnamespace to prevent ADL.
|
||||
namespace cf {
|
||||
template <typename Context, typename OutputIt, typename CompiledFormat>
|
||||
auto vformat_to(OutputIt out, CompiledFormat& cf,
|
||||
basic_format_args<Context> args) -> typename Context::iterator {
|
||||
using char_type = typename Context::char_type;
|
||||
basic_format_parse_context<char_type> parse_ctx(
|
||||
to_string_view(cf.format_str_));
|
||||
Context ctx(out, args);
|
||||
|
||||
const auto& parts = cf.parts();
|
||||
for (auto part_it = std::begin(parts); part_it != std::end(parts);
|
||||
++part_it) {
|
||||
const auto& part = *part_it;
|
||||
const auto& value = part.val;
|
||||
|
||||
using format_part_t = format_part<char_type>;
|
||||
switch (part.part_kind) {
|
||||
case format_part_t::kind::text: {
|
||||
const auto text = value.str;
|
||||
auto output = ctx.out();
|
||||
auto&& it = reserve(output, text.size());
|
||||
it = std::copy_n(text.begin(), text.size(), it);
|
||||
ctx.advance_to(output);
|
||||
break;
|
||||
}
|
||||
|
||||
case format_part_t::kind::arg_index:
|
||||
advance_to(parse_ctx, part.arg_id_end);
|
||||
detail::format_arg<OutputIt>(parse_ctx, ctx, value.arg_index);
|
||||
break;
|
||||
|
||||
case format_part_t::kind::arg_name:
|
||||
advance_to(parse_ctx, part.arg_id_end);
|
||||
detail::format_arg<OutputIt>(parse_ctx, ctx, value.str);
|
||||
break;
|
||||
|
||||
case format_part_t::kind::replacement: {
|
||||
const auto& arg_id_value = value.repl.arg_id.val;
|
||||
const auto arg = value.repl.arg_id.kind == arg_id_kind::index
|
||||
? ctx.arg(arg_id_value.index)
|
||||
: ctx.arg(arg_id_value.name);
|
||||
|
||||
auto specs = value.repl.specs;
|
||||
|
||||
handle_dynamic_spec<width_checker>(specs.width, specs.width_ref, ctx);
|
||||
handle_dynamic_spec<precision_checker>(specs.precision,
|
||||
specs.precision_ref, ctx);
|
||||
|
||||
error_handler h;
|
||||
numeric_specs_checker<error_handler> checker(h, arg.type());
|
||||
if (specs.align == align::numeric) checker.require_numeric_argument();
|
||||
if (specs.sign != sign::none) checker.check_sign();
|
||||
if (specs.alt) checker.require_numeric_argument();
|
||||
if (specs.precision >= 0) checker.check_precision();
|
||||
|
||||
advance_to(parse_ctx, part.arg_id_end);
|
||||
ctx.advance_to(
|
||||
visit_format_arg(arg_formatter<OutputIt, typename Context::char_type>(
|
||||
ctx, nullptr, &specs),
|
||||
arg));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ctx.out();
|
||||
}
|
||||
} // namespace cf
|
||||
|
||||
struct basic_compiled_format {};
|
||||
|
||||
template <typename S, typename = void>
|
||||
struct compiled_format_base : basic_compiled_format {
|
||||
using char_type = char_t<S>;
|
||||
using parts_container = std::vector<detail::format_part<char_type>>;
|
||||
|
||||
parts_container compiled_parts;
|
||||
|
||||
explicit compiled_format_base(basic_string_view<char_type> format_str) {
|
||||
compile_format_string<false>(format_str,
|
||||
[this](const format_part<char_type>& part) {
|
||||
compiled_parts.push_back(part);
|
||||
});
|
||||
}
|
||||
|
||||
const parts_container& parts() const { return compiled_parts; }
|
||||
};
|
||||
|
||||
template <typename Char, unsigned N> struct format_part_array {
|
||||
format_part<Char> data[N] = {};
|
||||
FMT_CONSTEXPR format_part_array() = default;
|
||||
};
|
||||
|
||||
template <typename Char, unsigned N>
|
||||
FMT_CONSTEXPR format_part_array<Char, N> compile_to_parts(
|
||||
basic_string_view<Char> format_str) {
|
||||
format_part_array<Char, N> parts;
|
||||
unsigned counter = 0;
|
||||
// This is not a lambda for compatibility with older compilers.
|
||||
struct {
|
||||
format_part<Char>* parts;
|
||||
unsigned* counter;
|
||||
FMT_CONSTEXPR void operator()(const format_part<Char>& part) {
|
||||
parts[(*counter)++] = part;
|
||||
}
|
||||
} collector{parts.data, &counter};
|
||||
compile_format_string<true>(format_str, collector);
|
||||
if (counter < N) {
|
||||
parts.data[counter] =
|
||||
format_part<Char>::make_text(basic_string_view<Char>());
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
template <typename T> constexpr const T& constexpr_max(const T& a, const T& b) {
|
||||
return (a < b) ? b : a;
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
struct compiled_format_base<S, enable_if_t<is_compile_string<S>::value>>
|
||||
: basic_compiled_format {
|
||||
using char_type = char_t<S>;
|
||||
|
||||
FMT_CONSTEXPR explicit compiled_format_base(basic_string_view<char_type>) {}
|
||||
|
||||
// Workaround for old compilers. Format string compilation will not be
|
||||
// performed there anyway.
|
||||
#if FMT_USE_CONSTEXPR
|
||||
static FMT_CONSTEXPR_DECL const unsigned num_format_parts =
|
||||
constexpr_max(count_parts(to_string_view(S())), 1u);
|
||||
#else
|
||||
static const unsigned num_format_parts = 1;
|
||||
#endif
|
||||
|
||||
using parts_container = format_part<char_type>[num_format_parts];
|
||||
|
||||
const parts_container& parts() const {
|
||||
static FMT_CONSTEXPR_DECL const auto compiled_parts =
|
||||
compile_to_parts<char_type, num_format_parts>(
|
||||
detail::to_string_view(S()));
|
||||
return compiled_parts.data;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename S, typename... Args>
|
||||
class compiled_format : private compiled_format_base<S> {
|
||||
public:
|
||||
using typename compiled_format_base<S>::char_type;
|
||||
|
||||
private:
|
||||
basic_string_view<char_type> format_str_;
|
||||
|
||||
template <typename Context, typename OutputIt, typename CompiledFormat>
|
||||
friend auto cf::vformat_to(OutputIt out, CompiledFormat& cf,
|
||||
basic_format_args<Context> args) ->
|
||||
typename Context::iterator;
|
||||
|
||||
public:
|
||||
compiled_format() = delete;
|
||||
explicit constexpr compiled_format(basic_string_view<char_type> format_str)
|
||||
: compiled_format_base<S>(format_str), format_str_(format_str) {}
|
||||
};
|
||||
|
||||
#ifdef __cpp_if_constexpr
|
||||
template <typename... Args> struct type_list {};
|
||||
|
||||
// Returns a reference to the argument at index N from [first, rest...].
|
||||
template <int N, typename T, typename... Args>
|
||||
constexpr const auto& get([[maybe_unused]] const T& first,
|
||||
[[maybe_unused]] const Args&... rest) {
|
||||
static_assert(N < 1 + sizeof...(Args), "index is out of bounds");
|
||||
if constexpr (N == 0)
|
||||
return first;
|
||||
else
|
||||
return get<N - 1>(rest...);
|
||||
}
|
||||
|
||||
template <int N, typename> struct get_type_impl;
|
||||
|
||||
template <int N, typename... Args> struct get_type_impl<N, type_list<Args...>> {
|
||||
using type = remove_cvref_t<decltype(get<N>(std::declval<Args>()...))>;
|
||||
};
|
||||
|
||||
template <int N, typename T>
|
||||
using get_type = typename get_type_impl<N, T>::type;
|
||||
|
||||
template <typename T> struct is_compiled_format : std::false_type {};
|
||||
|
||||
template <typename Char> struct text {
|
||||
basic_string_view<Char> data;
|
||||
using char_type = Char;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
OutputIt format(OutputIt out, const Args&...) const {
|
||||
return write<Char>(out, data);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
struct is_compiled_format<text<Char>> : std::true_type {};
|
||||
|
||||
template <typename Char>
|
||||
constexpr text<Char> make_text(basic_string_view<Char> s, size_t pos,
|
||||
size_t size) {
|
||||
return {{&s[pos], size}};
|
||||
}
|
||||
|
||||
template <typename Char> struct code_unit {
|
||||
Char value;
|
||||
using char_type = Char;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
OutputIt format(OutputIt out, const Args&...) const {
|
||||
return write<Char>(out, value);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
struct is_compiled_format<code_unit<Char>> : std::true_type {};
|
||||
|
||||
// A replacement field that refers to argument N.
|
||||
template <typename Char, typename T, int N> struct field {
|
||||
using char_type = Char;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
OutputIt format(OutputIt out, const Args&... args) const {
|
||||
// This ensures that the argument type is convertile to `const T&`.
|
||||
const T& arg = get<N>(args...);
|
||||
return write<Char>(out, arg);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename T, int N>
|
||||
struct is_compiled_format<field<Char, T, N>> : std::true_type {};
|
||||
|
||||
// A replacement field that refers to argument N and has format specifiers.
|
||||
template <typename Char, typename T, int N> struct spec_field {
|
||||
using char_type = Char;
|
||||
mutable formatter<T, Char> fmt;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
OutputIt format(OutputIt out, const Args&... args) const {
|
||||
// This ensures that the argument type is convertile to `const T&`.
|
||||
const T& arg = get<N>(args...);
|
||||
const auto& vargs =
|
||||
make_format_args<basic_format_context<OutputIt, Char>>(args...);
|
||||
basic_format_context<OutputIt, Char> ctx(out, vargs);
|
||||
return fmt.format(arg, ctx);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename T, int N>
|
||||
struct is_compiled_format<spec_field<Char, T, N>> : std::true_type {};
|
||||
|
||||
template <typename L, typename R> struct concat {
|
||||
L lhs;
|
||||
R rhs;
|
||||
using char_type = typename L::char_type;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
OutputIt format(OutputIt out, const Args&... args) const {
|
||||
out = lhs.format(out, args...);
|
||||
return rhs.format(out, args...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
struct is_compiled_format<concat<L, R>> : std::true_type {};
|
||||
|
||||
template <typename L, typename R>
|
||||
constexpr concat<L, R> make_concat(L lhs, R rhs) {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
|
||||
struct unknown_format {};
|
||||
|
||||
template <typename Char>
|
||||
constexpr size_t parse_text(basic_string_view<Char> str, size_t pos) {
|
||||
for (size_t size = str.size(); pos != size; ++pos) {
|
||||
if (str[pos] == '{' || str[pos] == '}') break;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
template <typename Args, size_t POS, int ID, typename S>
|
||||
constexpr auto compile_format_string(S format_str);
|
||||
|
||||
template <typename Args, size_t POS, int ID, typename T, typename S>
|
||||
constexpr auto parse_tail(T head, S format_str) {
|
||||
if constexpr (POS !=
|
||||
basic_string_view<typename S::char_type>(format_str).size()) {
|
||||
constexpr auto tail = compile_format_string<Args, POS, ID>(format_str);
|
||||
if constexpr (std::is_same<remove_cvref_t<decltype(tail)>,
|
||||
unknown_format>())
|
||||
return tail;
|
||||
else
|
||||
return make_concat(head, tail);
|
||||
} else {
|
||||
return head;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Char> struct parse_specs_result {
|
||||
formatter<T, Char> fmt;
|
||||
size_t end;
|
||||
int next_arg_id;
|
||||
};
|
||||
|
||||
template <typename T, typename Char>
|
||||
constexpr parse_specs_result<T, Char> parse_specs(basic_string_view<Char> str,
|
||||
size_t pos, int arg_id) {
|
||||
str.remove_prefix(pos);
|
||||
auto ctx = basic_format_parse_context<Char>(str, {}, arg_id + 1);
|
||||
auto f = formatter<T, Char>();
|
||||
auto end = f.parse(ctx);
|
||||
return {f, pos + (end - str.data()) + 1, ctx.next_arg_id()};
|
||||
}
|
||||
|
||||
// Compiles a non-empty format string and returns the compiled representation
|
||||
// or unknown_format() on unrecognized input.
|
||||
template <typename Args, size_t POS, int ID, typename S>
|
||||
constexpr auto compile_format_string(S format_str) {
|
||||
using char_type = typename S::char_type;
|
||||
constexpr basic_string_view<char_type> str = format_str;
|
||||
if constexpr (str[POS] == '{') {
|
||||
if (POS + 1 == str.size())
|
||||
throw format_error("unmatched '{' in format string");
|
||||
if constexpr (str[POS + 1] == '{') {
|
||||
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
|
||||
} else if constexpr (str[POS + 1] == '}') {
|
||||
using type = get_type<ID, Args>;
|
||||
return parse_tail<Args, POS + 2, ID + 1>(field<char_type, type, ID>(),
|
||||
format_str);
|
||||
} else if constexpr (str[POS + 1] == ':') {
|
||||
using type = get_type<ID, Args>;
|
||||
constexpr auto result = parse_specs<type>(str, POS + 2, ID);
|
||||
return parse_tail<Args, result.end, result.next_arg_id>(
|
||||
spec_field<char_type, type, ID>{result.fmt}, format_str);
|
||||
} else {
|
||||
return unknown_format();
|
||||
}
|
||||
} else if constexpr (str[POS] == '}') {
|
||||
if (POS + 1 == str.size())
|
||||
throw format_error("unmatched '}' in format string");
|
||||
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
|
||||
} else {
|
||||
constexpr auto end = parse_text(str, POS + 1);
|
||||
if constexpr (end - POS > 1) {
|
||||
return parse_tail<Args, end, ID>(make_text(str, POS, end - POS),
|
||||
format_str);
|
||||
} else {
|
||||
return parse_tail<Args, end, ID>(code_unit<char_type>{str[POS]},
|
||||
format_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args, typename S,
|
||||
FMT_ENABLE_IF(is_compile_string<S>::value ||
|
||||
detail::is_compiled_string<S>::value)>
|
||||
constexpr auto compile(S format_str) {
|
||||
constexpr basic_string_view<typename S::char_type> str = format_str;
|
||||
if constexpr (str.size() == 0) {
|
||||
return detail::make_text(str, 0, 0);
|
||||
} else {
|
||||
constexpr auto result =
|
||||
detail::compile_format_string<detail::type_list<Args...>, 0, 0>(
|
||||
format_str);
|
||||
if constexpr (std::is_same<remove_cvref_t<decltype(result)>,
|
||||
detail::unknown_format>()) {
|
||||
return detail::compiled_format<S, Args...>(to_string_view(format_str));
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
template <typename... Args, typename S,
|
||||
FMT_ENABLE_IF(is_compile_string<S>::value)>
|
||||
constexpr auto compile(S format_str) -> detail::compiled_format<S, Args...> {
|
||||
return detail::compiled_format<S, Args...>(to_string_view(format_str));
|
||||
}
|
||||
#endif // __cpp_if_constexpr
|
||||
|
||||
// Compiles the format string which must be a string literal.
|
||||
template <typename... Args, typename Char, size_t N>
|
||||
auto compile(const Char (&format_str)[N])
|
||||
-> detail::compiled_format<const Char*, Args...> {
|
||||
return detail::compiled_format<const Char*, Args...>(
|
||||
basic_string_view<Char>(format_str, N - 1));
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// DEPRECATED! use FMT_COMPILE instead.
|
||||
template <typename... Args>
|
||||
FMT_DEPRECATED auto compile(const Args&... args)
|
||||
-> decltype(detail::compile(args...)) {
|
||||
return detail::compile(args...);
|
||||
}
|
||||
|
||||
#if FMT_USE_CONSTEXPR
|
||||
# ifdef __cpp_if_constexpr
|
||||
|
||||
template <typename CompiledFormat, typename... Args,
|
||||
typename Char = typename CompiledFormat::char_type,
|
||||
FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
|
||||
FMT_INLINE std::basic_string<Char> format(const CompiledFormat& cf,
|
||||
const Args&... args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
cf.format(detail::buffer_appender<Char>(buffer), args...);
|
||||
return to_string(buffer);
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename CompiledFormat, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
|
||||
OutputIt format_to(OutputIt out, const CompiledFormat& cf,
|
||||
const Args&... args) {
|
||||
return cf.format(out, args...);
|
||||
}
|
||||
# endif // __cpp_if_constexpr
|
||||
#endif // FMT_USE_CONSTEXPR
|
||||
|
||||
template <typename CompiledFormat, typename... Args,
|
||||
typename Char = typename CompiledFormat::char_type,
|
||||
FMT_ENABLE_IF(std::is_base_of<detail::basic_compiled_format,
|
||||
CompiledFormat>::value)>
|
||||
std::basic_string<Char> format(const CompiledFormat& cf, const Args&... args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
using context = buffer_context<Char>;
|
||||
detail::cf::vformat_to<context>(detail::buffer_appender<Char>(buffer), cf,
|
||||
make_format_args<context>(args...));
|
||||
return to_string(buffer);
|
||||
}
|
||||
|
||||
template <typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
||||
FMT_INLINE std::basic_string<typename S::char_type> format(const S&,
|
||||
Args&&... args) {
|
||||
#ifdef __cpp_if_constexpr
|
||||
if constexpr (std::is_same<typename S::char_type, char>::value) {
|
||||
constexpr basic_string_view<typename S::char_type> str = S();
|
||||
if (str.size() == 2 && str[0] == '{' && str[1] == '}')
|
||||
return fmt::to_string(detail::first(args...));
|
||||
}
|
||||
#endif
|
||||
constexpr auto compiled = detail::compile<Args...>(S());
|
||||
return format(compiled, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename CompiledFormat, typename... Args,
|
||||
FMT_ENABLE_IF(std::is_base_of<detail::basic_compiled_format,
|
||||
CompiledFormat>::value)>
|
||||
OutputIt format_to(OutputIt out, const CompiledFormat& cf,
|
||||
const Args&... args) {
|
||||
using char_type = typename CompiledFormat::char_type;
|
||||
using context = format_context_t<OutputIt, char_type>;
|
||||
return detail::cf::vformat_to<context>(out, cf,
|
||||
make_format_args<context>(args...));
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
||||
OutputIt format_to(OutputIt out, const S&, const Args&... args) {
|
||||
constexpr auto compiled = detail::compile<Args...>(S());
|
||||
return format_to(out, compiled, args...);
|
||||
}
|
||||
|
||||
template <
|
||||
typename OutputIt, typename CompiledFormat, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt>::value&& std::is_base_of<
|
||||
detail::basic_compiled_format, CompiledFormat>::value)>
|
||||
format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n,
|
||||
const CompiledFormat& cf,
|
||||
const Args&... args) {
|
||||
auto it =
|
||||
format_to(detail::truncating_iterator<OutputIt>(out, n), cf, args...);
|
||||
return {it.base(), it.count()};
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
||||
format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n, const S&,
|
||||
const Args&... args) {
|
||||
constexpr auto compiled = detail::compile<Args...>(S());
|
||||
auto it = format_to(detail::truncating_iterator<OutputIt>(out, n), compiled,
|
||||
args...);
|
||||
return {it.base(), it.count()};
|
||||
}
|
||||
|
||||
template <typename CompiledFormat, typename... Args>
|
||||
size_t formatted_size(const CompiledFormat& cf, const Args&... args) {
|
||||
return format_to(detail::counting_iterator(), cf, args...).count();
|
||||
}
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_COMPILE_H_
|
||||
2129
src/3rdparty/fmt/core.h
vendored
2129
src/3rdparty/fmt/core.h
vendored
File diff suppressed because it is too large
Load Diff
2801
src/3rdparty/fmt/format-inl.h
vendored
2801
src/3rdparty/fmt/format-inl.h
vendored
File diff suppressed because it is too large
Load Diff
69
src/3rdparty/fmt/format.cc
vendored
69
src/3rdparty/fmt/format.cc
vendored
@@ -1,69 +0,0 @@
|
||||
// Formatting library for C++
|
||||
//
|
||||
// Copyright (c) 2012 - 2016, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#include "3rdparty/fmt/format-inl.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
int format_float(char* buf, std::size_t size, const char* format, int precision,
|
||||
T value) {
|
||||
#ifdef FMT_FUZZ
|
||||
if (precision > 100000)
|
||||
throw std::runtime_error(
|
||||
"fuzz mode - avoid large allocation inside snprintf");
|
||||
#endif
|
||||
// Suppress the warning about nonliteral format string.
|
||||
int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF;
|
||||
return precision < 0 ? snprintf_ptr(buf, size, format, value)
|
||||
: snprintf_ptr(buf, size, format, precision, value);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template struct FMT_INSTANTIATION_DEF_API detail::basic_data<void>;
|
||||
|
||||
// Workaround a bug in MSVC2013 that prevents instantiation of format_float.
|
||||
int (*instantiate_format_float)(double, int, detail::float_specs,
|
||||
detail::buffer<char>&) = detail::format_float;
|
||||
|
||||
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
||||
template FMT_API detail::locale_ref::locale_ref(const std::locale& loc);
|
||||
template FMT_API std::locale detail::locale_ref::get<std::locale>() const;
|
||||
#endif
|
||||
|
||||
// Explicit instantiations for char.
|
||||
|
||||
template FMT_API std::string detail::grouping_impl<char>(locale_ref);
|
||||
template FMT_API char detail::thousands_sep_impl(locale_ref);
|
||||
template FMT_API char detail::decimal_point_impl(locale_ref);
|
||||
|
||||
template FMT_API void detail::buffer<char>::append(const char*, const char*);
|
||||
|
||||
template FMT_API FMT_BUFFER_CONTEXT(char)::iterator detail::vformat_to(
|
||||
detail::buffer<char>&, string_view,
|
||||
basic_format_args<FMT_BUFFER_CONTEXT(char)>);
|
||||
|
||||
template FMT_API int detail::snprintf_float(double, int, detail::float_specs,
|
||||
detail::buffer<char>&);
|
||||
template FMT_API int detail::snprintf_float(long double, int,
|
||||
detail::float_specs,
|
||||
detail::buffer<char>&);
|
||||
template FMT_API int detail::format_float(double, int, detail::float_specs,
|
||||
detail::buffer<char>&);
|
||||
template FMT_API int detail::format_float(long double, int, detail::float_specs,
|
||||
detail::buffer<char>&);
|
||||
|
||||
// Explicit instantiations for wchar_t.
|
||||
|
||||
template FMT_API std::string detail::grouping_impl<wchar_t>(locale_ref);
|
||||
template FMT_API wchar_t detail::thousands_sep_impl(locale_ref);
|
||||
template FMT_API wchar_t detail::decimal_point_impl(locale_ref);
|
||||
|
||||
template FMT_API void detail::buffer<wchar_t>::append(const wchar_t*,
|
||||
const wchar_t*);
|
||||
FMT_END_NAMESPACE
|
||||
3869
src/3rdparty/fmt/format.h
vendored
3869
src/3rdparty/fmt/format.h
vendored
File diff suppressed because it is too large
Load Diff
78
src/3rdparty/fmt/locale.h
vendored
78
src/3rdparty/fmt/locale.h
vendored
@@ -1,78 +0,0 @@
|
||||
// Formatting library for C++ - std::locale support
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_LOCALE_H_
|
||||
#define FMT_LOCALE_H_
|
||||
|
||||
#include <locale>
|
||||
|
||||
#include "format.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
namespace detail {
|
||||
template <typename Char>
|
||||
typename buffer_context<Char>::iterator vformat_to(
|
||||
const std::locale& loc, buffer<Char>& buf,
|
||||
basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
using af = arg_formatter<typename buffer_context<Char>::iterator, Char>;
|
||||
return vformat_to<af>(buffer_appender<Char>(buf), to_string_view(format_str),
|
||||
args, detail::locale_ref(loc));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
std::basic_string<Char> vformat(
|
||||
const std::locale& loc, basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
detail::vformat_to(loc, buffer, format_str, args);
|
||||
return fmt::to_string(buffer);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline std::basic_string<Char> vformat(
|
||||
const std::locale& loc, const S& format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
return detail::vformat(loc, to_string_view(format_str), args);
|
||||
}
|
||||
|
||||
template <typename S, typename... Args, typename Char = char_t<S>>
|
||||
inline std::basic_string<Char> format(const std::locale& loc,
|
||||
const S& format_str, Args&&... args) {
|
||||
return detail::vformat(
|
||||
loc, to_string_view(format_str),
|
||||
fmt::make_args_checked<Args...>(format_str, args...));
|
||||
}
|
||||
|
||||
template <typename S, typename OutputIt, typename... Args,
|
||||
typename Char = enable_if_t<
|
||||
detail::is_output_iterator<OutputIt>::value, char_t<S>>>
|
||||
inline OutputIt vformat_to(
|
||||
OutputIt out, const std::locale& loc, const S& format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
decltype(detail::get_buffer<Char>(out)) buf(detail::get_buffer_init(out));
|
||||
using af =
|
||||
detail::arg_formatter<typename buffer_context<Char>::iterator, Char>;
|
||||
vformat_to<af>(detail::buffer_appender<Char>(buf), to_string_view(format_str),
|
||||
args, detail::locale_ref(loc));
|
||||
return detail::get_iterator(buf);
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt>::value&&
|
||||
detail::is_string<S>::value)>
|
||||
inline OutputIt format_to(OutputIt out, const std::locale& loc,
|
||||
const S& format_str, Args&&... args) {
|
||||
const auto& vargs = fmt::make_args_checked<Args...>(format_str, args...);
|
||||
return vformat_to(out, loc, to_string_view(format_str), vargs);
|
||||
}
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_LOCALE_H_
|
||||
322
src/3rdparty/fmt/os.cc
vendored
322
src/3rdparty/fmt/os.cc
vendored
@@ -1,322 +0,0 @@
|
||||
// Formatting library for C++ - optional OS-specific functionality
|
||||
//
|
||||
// Copyright (c) 2012 - 2016, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
// Disable bogus MSVC warnings.
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS) && defined(_MSC_VER)
|
||||
# define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include "fmt/os.h"
|
||||
|
||||
#include <climits>
|
||||
|
||||
#if FMT_USE_FCNTL
|
||||
# include <sys/stat.h>
|
||||
# include <sys/types.h>
|
||||
|
||||
# ifndef _WIN32
|
||||
# include <unistd.h>
|
||||
# else
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <io.h>
|
||||
# include <windows.h>
|
||||
|
||||
# define O_CREAT _O_CREAT
|
||||
# define O_TRUNC _O_TRUNC
|
||||
|
||||
# ifndef S_IRUSR
|
||||
# define S_IRUSR _S_IREAD
|
||||
# endif
|
||||
|
||||
# ifndef S_IWUSR
|
||||
# define S_IWUSR _S_IWRITE
|
||||
# endif
|
||||
|
||||
# ifdef __MINGW32__
|
||||
# define _SH_DENYNO 0x40
|
||||
# endif
|
||||
# endif // _WIN32
|
||||
#endif // FMT_USE_FCNTL
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef fileno
|
||||
# undef fileno
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
#ifdef _WIN32
|
||||
// Return type of read and write functions.
|
||||
using RWResult = int;
|
||||
|
||||
// On Windows the count argument to read and write is unsigned, so convert
|
||||
// it from size_t preventing integer overflow.
|
||||
inline unsigned convert_rwcount(std::size_t count) {
|
||||
return count <= UINT_MAX ? static_cast<unsigned>(count) : UINT_MAX;
|
||||
}
|
||||
#else
|
||||
// Return type of read and write functions.
|
||||
using RWResult = ssize_t;
|
||||
|
||||
inline std::size_t convert_rwcount(std::size_t count) { return count; }
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
#ifdef _WIN32
|
||||
detail::utf16_to_utf8::utf16_to_utf8(wstring_view s) {
|
||||
if (int error_code = convert(s)) {
|
||||
FMT_THROW(windows_error(error_code,
|
||||
"cannot convert string from UTF-16 to UTF-8"));
|
||||
}
|
||||
}
|
||||
|
||||
int detail::utf16_to_utf8::convert(wstring_view s) {
|
||||
if (s.size() > INT_MAX) return ERROR_INVALID_PARAMETER;
|
||||
int s_size = static_cast<int>(s.size());
|
||||
if (s_size == 0) {
|
||||
// WideCharToMultiByte does not support zero length, handle separately.
|
||||
buffer_.resize(1);
|
||||
buffer_[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, nullptr, 0,
|
||||
nullptr, nullptr);
|
||||
if (length == 0) return GetLastError();
|
||||
buffer_.resize(length + 1);
|
||||
length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, &buffer_[0],
|
||||
length, nullptr, nullptr);
|
||||
if (length == 0) return GetLastError();
|
||||
buffer_[length] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void windows_error::init(int err_code, string_view format_str,
|
||||
format_args args) {
|
||||
error_code_ = err_code;
|
||||
memory_buffer buffer;
|
||||
detail::format_windows_error(buffer, err_code, vformat(format_str, args));
|
||||
std::runtime_error& base = *this;
|
||||
base = std::runtime_error(to_string(buffer));
|
||||
}
|
||||
|
||||
void detail::format_windows_error(detail::buffer<char>& out, int error_code,
|
||||
string_view message) FMT_NOEXCEPT {
|
||||
FMT_TRY {
|
||||
wmemory_buffer buf;
|
||||
buf.resize(inline_buffer_size);
|
||||
for (;;) {
|
||||
wchar_t* system_message = &buf[0];
|
||||
int result = FormatMessageW(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
|
||||
error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), system_message,
|
||||
static_cast<uint32_t>(buf.size()), nullptr);
|
||||
if (result != 0) {
|
||||
utf16_to_utf8 utf8_message;
|
||||
if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
|
||||
format_to(buffer_appender<char>(out), "{}: {}", message,
|
||||
utf8_message);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
||||
break; // Can't get error message, report error code instead.
|
||||
buf.resize(buf.size() * 2);
|
||||
}
|
||||
}
|
||||
FMT_CATCH(...) {}
|
||||
format_error_code(out, error_code, message);
|
||||
}
|
||||
|
||||
void report_windows_error(int error_code,
|
||||
fmt::string_view message) FMT_NOEXCEPT {
|
||||
report_error(detail::format_windows_error, error_code, message);
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
buffered_file::~buffered_file() FMT_NOEXCEPT {
|
||||
if (file_ && FMT_SYSTEM(fclose(file_)) != 0)
|
||||
report_system_error(errno, "cannot close file");
|
||||
}
|
||||
|
||||
buffered_file::buffered_file(cstring_view filename, cstring_view mode) {
|
||||
FMT_RETRY_VAL(file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())),
|
||||
nullptr);
|
||||
if (!file_)
|
||||
FMT_THROW(system_error(errno, "cannot open file {}", filename.c_str()));
|
||||
}
|
||||
|
||||
void buffered_file::close() {
|
||||
if (!file_) return;
|
||||
int result = FMT_SYSTEM(fclose(file_));
|
||||
file_ = nullptr;
|
||||
if (result != 0) FMT_THROW(system_error(errno, "cannot close file"));
|
||||
}
|
||||
|
||||
// A macro used to prevent expansion of fileno on broken versions of MinGW.
|
||||
#define FMT_ARGS
|
||||
|
||||
int buffered_file::fileno() const {
|
||||
int fd = FMT_POSIX_CALL(fileno FMT_ARGS(file_));
|
||||
if (fd == -1) FMT_THROW(system_error(errno, "cannot get file descriptor"));
|
||||
return fd;
|
||||
}
|
||||
|
||||
#if FMT_USE_FCNTL
|
||||
file::file(cstring_view path, int oflag) {
|
||||
int mode = S_IRUSR | S_IWUSR;
|
||||
# if defined(_WIN32) && !defined(__MINGW32__)
|
||||
fd_ = -1;
|
||||
FMT_POSIX_CALL(sopen_s(&fd_, path.c_str(), oflag, _SH_DENYNO, mode));
|
||||
# else
|
||||
FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, mode)));
|
||||
# endif
|
||||
if (fd_ == -1)
|
||||
FMT_THROW(system_error(errno, "cannot open file {}", path.c_str()));
|
||||
}
|
||||
|
||||
file::~file() FMT_NOEXCEPT {
|
||||
// Don't retry close in case of EINTR!
|
||||
// See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
|
||||
if (fd_ != -1 && FMT_POSIX_CALL(close(fd_)) != 0)
|
||||
report_system_error(errno, "cannot close file");
|
||||
}
|
||||
|
||||
void file::close() {
|
||||
if (fd_ == -1) return;
|
||||
// Don't retry close in case of EINTR!
|
||||
// See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
|
||||
int result = FMT_POSIX_CALL(close(fd_));
|
||||
fd_ = -1;
|
||||
if (result != 0) FMT_THROW(system_error(errno, "cannot close file"));
|
||||
}
|
||||
|
||||
long long file::size() const {
|
||||
# ifdef _WIN32
|
||||
// Use GetFileSize instead of GetFileSizeEx for the case when _WIN32_WINNT
|
||||
// is less than 0x0500 as is the case with some default MinGW builds.
|
||||
// Both functions support large file sizes.
|
||||
DWORD size_upper = 0;
|
||||
HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd_));
|
||||
DWORD size_lower = FMT_SYSTEM(GetFileSize(handle, &size_upper));
|
||||
if (size_lower == INVALID_FILE_SIZE) {
|
||||
DWORD error = GetLastError();
|
||||
if (error != NO_ERROR)
|
||||
FMT_THROW(windows_error(GetLastError(), "cannot get file size"));
|
||||
}
|
||||
unsigned long long long_size = size_upper;
|
||||
return (long_size << sizeof(DWORD) * CHAR_BIT) | size_lower;
|
||||
# else
|
||||
using Stat = struct stat;
|
||||
Stat file_stat = Stat();
|
||||
if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1)
|
||||
FMT_THROW(system_error(errno, "cannot get file attributes"));
|
||||
static_assert(sizeof(long long) >= sizeof(file_stat.st_size),
|
||||
"return type of file::size is not large enough");
|
||||
return file_stat.st_size;
|
||||
# endif
|
||||
}
|
||||
|
||||
std::size_t file::read(void* buffer, std::size_t count) {
|
||||
RWResult result = 0;
|
||||
FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count))));
|
||||
if (result < 0) FMT_THROW(system_error(errno, "cannot read from file"));
|
||||
return detail::to_unsigned(result);
|
||||
}
|
||||
|
||||
std::size_t file::write(const void* buffer, std::size_t count) {
|
||||
RWResult result = 0;
|
||||
FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count))));
|
||||
if (result < 0) FMT_THROW(system_error(errno, "cannot write to file"));
|
||||
return detail::to_unsigned(result);
|
||||
}
|
||||
|
||||
file file::dup(int fd) {
|
||||
// Don't retry as dup doesn't return EINTR.
|
||||
// http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html
|
||||
int new_fd = FMT_POSIX_CALL(dup(fd));
|
||||
if (new_fd == -1)
|
||||
FMT_THROW(system_error(errno, "cannot duplicate file descriptor {}", fd));
|
||||
return file(new_fd);
|
||||
}
|
||||
|
||||
void file::dup2(int fd) {
|
||||
int result = 0;
|
||||
FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
|
||||
if (result == -1) {
|
||||
FMT_THROW(system_error(errno, "cannot duplicate file descriptor {} to {}",
|
||||
fd_, fd));
|
||||
}
|
||||
}
|
||||
|
||||
void file::dup2(int fd, error_code& ec) FMT_NOEXCEPT {
|
||||
int result = 0;
|
||||
FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
|
||||
if (result == -1) ec = error_code(errno);
|
||||
}
|
||||
|
||||
void file::pipe(file& read_end, file& write_end) {
|
||||
// Close the descriptors first to make sure that assignments don't throw
|
||||
// and there are no leaks.
|
||||
read_end.close();
|
||||
write_end.close();
|
||||
int fds[2] = {};
|
||||
# ifdef _WIN32
|
||||
// Make the default pipe capacity same as on Linux 2.6.11+.
|
||||
enum { DEFAULT_CAPACITY = 65536 };
|
||||
int result = FMT_POSIX_CALL(pipe(fds, DEFAULT_CAPACITY, _O_BINARY));
|
||||
# else
|
||||
// Don't retry as the pipe function doesn't return EINTR.
|
||||
// http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html
|
||||
int result = FMT_POSIX_CALL(pipe(fds));
|
||||
# endif
|
||||
if (result != 0) FMT_THROW(system_error(errno, "cannot create pipe"));
|
||||
// The following assignments don't throw because read_fd and write_fd
|
||||
// are closed.
|
||||
read_end = file(fds[0]);
|
||||
write_end = file(fds[1]);
|
||||
}
|
||||
|
||||
buffered_file file::fdopen(const char* mode) {
|
||||
// Don't retry as fdopen doesn't return EINTR.
|
||||
# if defined(__MINGW32__) && defined(_POSIX_)
|
||||
FILE* f = ::fdopen(fd_, mode);
|
||||
# else
|
||||
FILE* f = FMT_POSIX_CALL(fdopen(fd_, mode));
|
||||
# endif
|
||||
if (!f)
|
||||
FMT_THROW(
|
||||
system_error(errno, "cannot associate stream with file descriptor"));
|
||||
buffered_file bf(f);
|
||||
fd_ = -1;
|
||||
return bf;
|
||||
}
|
||||
|
||||
long getpagesize() {
|
||||
# ifdef _WIN32
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
return si.dwPageSize;
|
||||
# else
|
||||
long size = FMT_POSIX_CALL(sysconf(_SC_PAGESIZE));
|
||||
if (size < 0) FMT_THROW(system_error(errno, "cannot get memory page size"));
|
||||
return size;
|
||||
# endif
|
||||
}
|
||||
|
||||
void ostream::grow(size_t) {
|
||||
if (this->size() == this->capacity()) flush();
|
||||
}
|
||||
#endif // FMT_USE_FCNTL
|
||||
FMT_END_NAMESPACE
|
||||
480
src/3rdparty/fmt/os.h
vendored
480
src/3rdparty/fmt/os.h
vendored
@@ -1,480 +0,0 @@
|
||||
// Formatting library for C++ - optional OS-specific functionality
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_OS_H_
|
||||
#define FMT_OS_H_
|
||||
|
||||
#if defined(__MINGW32__) || defined(__CYGWIN__)
|
||||
// Workaround MinGW bug https://sourceforge.net/p/mingw/bugs/2024/.
|
||||
# undef __STRICT_ANSI__
|
||||
#endif
|
||||
|
||||
#include <cerrno>
|
||||
#include <clocale> // for locale_t
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstdlib> // for strtod_l
|
||||
|
||||
#if defined __APPLE__ || defined(__FreeBSD__)
|
||||
# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
|
||||
#endif
|
||||
|
||||
#include "format.h"
|
||||
|
||||
// UWP doesn't provide _pipe.
|
||||
#if FMT_HAS_INCLUDE("winapifamily.h")
|
||||
# include <winapifamily.h>
|
||||
#endif
|
||||
#if (FMT_HAS_INCLUDE(<fcntl.h>) || defined(__APPLE__) || \
|
||||
defined(__linux__)) && \
|
||||
(!defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
|
||||
# include <fcntl.h> // for O_RDONLY
|
||||
# define FMT_USE_FCNTL 1
|
||||
#else
|
||||
# define FMT_USE_FCNTL 0
|
||||
#endif
|
||||
|
||||
#ifndef FMT_POSIX
|
||||
# if defined(_WIN32) && !defined(__MINGW32__)
|
||||
// Fix warnings about deprecated symbols.
|
||||
# define FMT_POSIX(call) _##call
|
||||
# else
|
||||
# define FMT_POSIX(call) call
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Calls to system functions are wrapped in FMT_SYSTEM for testability.
|
||||
#ifdef FMT_SYSTEM
|
||||
# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
|
||||
#else
|
||||
# define FMT_SYSTEM(call) ::call
|
||||
# ifdef _WIN32
|
||||
// Fix warnings about deprecated symbols.
|
||||
# define FMT_POSIX_CALL(call) ::_##call
|
||||
# else
|
||||
# define FMT_POSIX_CALL(call) ::call
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Retries the expression while it evaluates to error_result and errno
|
||||
// equals to EINTR.
|
||||
#ifndef _WIN32
|
||||
# define FMT_RETRY_VAL(result, expression, error_result) \
|
||||
do { \
|
||||
(result) = (expression); \
|
||||
} while ((result) == (error_result) && errno == EINTR)
|
||||
#else
|
||||
# define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
|
||||
#endif
|
||||
|
||||
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
/**
|
||||
\rst
|
||||
A reference to a null-terminated string. It can be constructed from a C
|
||||
string or ``std::string``.
|
||||
|
||||
You can use one of the following type aliases for common character types:
|
||||
|
||||
+---------------+-----------------------------+
|
||||
| Type | Definition |
|
||||
+===============+=============================+
|
||||
| cstring_view | basic_cstring_view<char> |
|
||||
+---------------+-----------------------------+
|
||||
| wcstring_view | basic_cstring_view<wchar_t> |
|
||||
+---------------+-----------------------------+
|
||||
|
||||
This class is most useful as a parameter type to allow passing
|
||||
different types of strings to a function, for example::
|
||||
|
||||
template <typename... Args>
|
||||
std::string format(cstring_view format_str, const Args & ... args);
|
||||
|
||||
format("{}", 42);
|
||||
format(std::string("{}"), 42);
|
||||
\endrst
|
||||
*/
|
||||
template <typename Char> class basic_cstring_view {
|
||||
private:
|
||||
const Char* data_;
|
||||
|
||||
public:
|
||||
/** Constructs a string reference object from a C string. */
|
||||
basic_cstring_view(const Char* s) : data_(s) {}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Constructs a string reference from an ``std::string`` object.
|
||||
\endrst
|
||||
*/
|
||||
basic_cstring_view(const std::basic_string<Char>& s) : data_(s.c_str()) {}
|
||||
|
||||
/** Returns the pointer to a C string. */
|
||||
const Char* c_str() const { return data_; }
|
||||
};
|
||||
|
||||
using cstring_view = basic_cstring_view<char>;
|
||||
using wcstring_view = basic_cstring_view<wchar_t>;
|
||||
|
||||
// An error code.
|
||||
class error_code {
|
||||
private:
|
||||
int value_;
|
||||
|
||||
public:
|
||||
explicit error_code(int value = 0) FMT_NOEXCEPT : value_(value) {}
|
||||
|
||||
int get() const FMT_NOEXCEPT { return value_; }
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
namespace detail {
|
||||
// A converter from UTF-16 to UTF-8.
|
||||
// It is only provided for Windows since other systems support UTF-8 natively.
|
||||
class utf16_to_utf8 {
|
||||
private:
|
||||
memory_buffer buffer_;
|
||||
|
||||
public:
|
||||
utf16_to_utf8() {}
|
||||
FMT_API explicit utf16_to_utf8(wstring_view s);
|
||||
operator string_view() const { return string_view(&buffer_[0], size()); }
|
||||
size_t size() const { return buffer_.size() - 1; }
|
||||
const char* c_str() const { return &buffer_[0]; }
|
||||
std::string str() const { return std::string(&buffer_[0], size()); }
|
||||
|
||||
// Performs conversion returning a system error code instead of
|
||||
// throwing exception on conversion error. This method may still throw
|
||||
// in case of memory allocation error.
|
||||
FMT_API int convert(wstring_view s);
|
||||
};
|
||||
|
||||
FMT_API void format_windows_error(buffer<char>& out, int error_code,
|
||||
string_view message) FMT_NOEXCEPT;
|
||||
} // namespace detail
|
||||
|
||||
/** A Windows error. */
|
||||
class windows_error : public system_error {
|
||||
private:
|
||||
FMT_API void init(int error_code, string_view format_str, format_args args);
|
||||
|
||||
public:
|
||||
/**
|
||||
\rst
|
||||
Constructs a :class:`fmt::windows_error` object with the description
|
||||
of the form
|
||||
|
||||
.. parsed-literal::
|
||||
*<message>*: *<system-message>*
|
||||
|
||||
where *<message>* is the formatted message and *<system-message>* is the
|
||||
system message corresponding to the error code.
|
||||
*error_code* is a Windows error code as given by ``GetLastError``.
|
||||
If *error_code* is not a valid error code such as -1, the system message
|
||||
will look like "error -1".
|
||||
|
||||
**Example**::
|
||||
|
||||
// This throws a windows_error with the description
|
||||
// cannot open file 'madeup': The system cannot find the file specified.
|
||||
// or similar (system message may vary).
|
||||
const char *filename = "madeup";
|
||||
LPOFSTRUCT of = LPOFSTRUCT();
|
||||
HFILE file = OpenFile(filename, &of, OF_READ);
|
||||
if (file == HFILE_ERROR) {
|
||||
throw fmt::windows_error(GetLastError(),
|
||||
"cannot open file '{}'", filename);
|
||||
}
|
||||
\endrst
|
||||
*/
|
||||
template <typename... Args>
|
||||
windows_error(int error_code, string_view message, const Args&... args) {
|
||||
init(error_code, message, make_format_args(args...));
|
||||
}
|
||||
};
|
||||
|
||||
// Reports a Windows error without throwing an exception.
|
||||
// Can be used to report errors from destructors.
|
||||
FMT_API void report_windows_error(int error_code,
|
||||
string_view message) FMT_NOEXCEPT;
|
||||
#endif // _WIN32
|
||||
|
||||
// A buffered file.
|
||||
class buffered_file {
|
||||
private:
|
||||
FILE* file_;
|
||||
|
||||
friend class file;
|
||||
|
||||
explicit buffered_file(FILE* f) : file_(f) {}
|
||||
|
||||
public:
|
||||
buffered_file(const buffered_file&) = delete;
|
||||
void operator=(const buffered_file&) = delete;
|
||||
|
||||
// Constructs a buffered_file object which doesn't represent any file.
|
||||
buffered_file() FMT_NOEXCEPT : file_(nullptr) {}
|
||||
|
||||
// Destroys the object closing the file it represents if any.
|
||||
FMT_API ~buffered_file() FMT_NOEXCEPT;
|
||||
|
||||
public:
|
||||
buffered_file(buffered_file&& other) FMT_NOEXCEPT : file_(other.file_) {
|
||||
other.file_ = nullptr;
|
||||
}
|
||||
|
||||
buffered_file& operator=(buffered_file&& other) {
|
||||
close();
|
||||
file_ = other.file_;
|
||||
other.file_ = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Opens a file.
|
||||
FMT_API buffered_file(cstring_view filename, cstring_view mode);
|
||||
|
||||
// Closes the file.
|
||||
FMT_API void close();
|
||||
|
||||
// Returns the pointer to a FILE object representing this file.
|
||||
FILE* get() const FMT_NOEXCEPT { return file_; }
|
||||
|
||||
// We place parentheses around fileno to workaround a bug in some versions
|
||||
// of MinGW that define fileno as a macro.
|
||||
FMT_API int(fileno)() const;
|
||||
|
||||
void vprint(string_view format_str, format_args args) {
|
||||
fmt::vprint(file_, format_str, args);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void print(string_view format_str, const Args&... args) {
|
||||
vprint(format_str, make_format_args(args...));
|
||||
}
|
||||
};
|
||||
|
||||
#if FMT_USE_FCNTL
|
||||
// A file. Closed file is represented by a file object with descriptor -1.
|
||||
// Methods that are not declared with FMT_NOEXCEPT may throw
|
||||
// fmt::system_error in case of failure. Note that some errors such as
|
||||
// closing the file multiple times will cause a crash on Windows rather
|
||||
// than an exception. You can get standard behavior by overriding the
|
||||
// invalid parameter handler with _set_invalid_parameter_handler.
|
||||
class file {
|
||||
private:
|
||||
int fd_; // File descriptor.
|
||||
|
||||
// Constructs a file object with a given descriptor.
|
||||
explicit file(int fd) : fd_(fd) {}
|
||||
|
||||
public:
|
||||
// Possible values for the oflag argument to the constructor.
|
||||
enum {
|
||||
RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only.
|
||||
WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only.
|
||||
RDWR = FMT_POSIX(O_RDWR), // Open for reading and writing.
|
||||
CREATE = FMT_POSIX(O_CREAT), // Create if the file doesn't exist.
|
||||
APPEND = FMT_POSIX(O_APPEND) // Open in append mode.
|
||||
};
|
||||
|
||||
// Constructs a file object which doesn't represent any file.
|
||||
file() FMT_NOEXCEPT : fd_(-1) {}
|
||||
|
||||
// Opens a file and constructs a file object representing this file.
|
||||
FMT_API file(cstring_view path, int oflag);
|
||||
|
||||
public:
|
||||
file(const file&) = delete;
|
||||
void operator=(const file&) = delete;
|
||||
|
||||
file(file&& other) FMT_NOEXCEPT : fd_(other.fd_) { other.fd_ = -1; }
|
||||
|
||||
file& operator=(file&& other) FMT_NOEXCEPT {
|
||||
close();
|
||||
fd_ = other.fd_;
|
||||
other.fd_ = -1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Destroys the object closing the file it represents if any.
|
||||
FMT_API ~file() FMT_NOEXCEPT;
|
||||
|
||||
// Returns the file descriptor.
|
||||
int descriptor() const FMT_NOEXCEPT { return fd_; }
|
||||
|
||||
// Closes the file.
|
||||
FMT_API void close();
|
||||
|
||||
// Returns the file size. The size has signed type for consistency with
|
||||
// stat::st_size.
|
||||
FMT_API long long size() const;
|
||||
|
||||
// Attempts to read count bytes from the file into the specified buffer.
|
||||
FMT_API size_t read(void* buffer, size_t count);
|
||||
|
||||
// Attempts to write count bytes from the specified buffer to the file.
|
||||
FMT_API size_t write(const void* buffer, size_t count);
|
||||
|
||||
// Duplicates a file descriptor with the dup function and returns
|
||||
// the duplicate as a file object.
|
||||
FMT_API static file dup(int fd);
|
||||
|
||||
// Makes fd be the copy of this file descriptor, closing fd first if
|
||||
// necessary.
|
||||
FMT_API void dup2(int fd);
|
||||
|
||||
// Makes fd be the copy of this file descriptor, closing fd first if
|
||||
// necessary.
|
||||
FMT_API void dup2(int fd, error_code& ec) FMT_NOEXCEPT;
|
||||
|
||||
// Creates a pipe setting up read_end and write_end file objects for reading
|
||||
// and writing respectively.
|
||||
FMT_API static void pipe(file& read_end, file& write_end);
|
||||
|
||||
// Creates a buffered_file object associated with this file and detaches
|
||||
// this file object from the file.
|
||||
FMT_API buffered_file fdopen(const char* mode);
|
||||
};
|
||||
|
||||
// Returns the memory page size.
|
||||
long getpagesize();
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct buffer_size {
|
||||
size_t value = 0;
|
||||
buffer_size operator=(size_t val) const {
|
||||
auto bs = buffer_size();
|
||||
bs.value = val;
|
||||
return bs;
|
||||
}
|
||||
};
|
||||
|
||||
struct ostream_params {
|
||||
int oflag = file::WRONLY | file::CREATE;
|
||||
size_t buffer_size = BUFSIZ > 32768 ? BUFSIZ : 32768;
|
||||
|
||||
ostream_params() {}
|
||||
|
||||
template <typename... T>
|
||||
ostream_params(T... params, int oflag) : ostream_params(params...) {
|
||||
this->oflag = oflag;
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
ostream_params(T... params, detail::buffer_size bs)
|
||||
: ostream_params(params...) {
|
||||
this->buffer_size = bs.value;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
static constexpr detail::buffer_size buffer_size;
|
||||
|
||||
// A fast output stream which is not thread-safe.
|
||||
class ostream : private detail::buffer<char> {
|
||||
private:
|
||||
file file_;
|
||||
|
||||
void flush() {
|
||||
if (size() == 0) return;
|
||||
file_.write(data(), size());
|
||||
clear();
|
||||
}
|
||||
|
||||
void grow(size_t) final;
|
||||
|
||||
ostream(cstring_view path, const detail::ostream_params& params)
|
||||
: file_(path, params.oflag) {
|
||||
set(new char[params.buffer_size], params.buffer_size);
|
||||
}
|
||||
|
||||
public:
|
||||
ostream(ostream&& other)
|
||||
: detail::buffer<char>(other.data(), other.size(), other.capacity()),
|
||||
file_(std::move(other.file_)) {
|
||||
other.set(nullptr, 0);
|
||||
}
|
||||
~ostream() {
|
||||
flush();
|
||||
delete[] data();
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
friend ostream output_file(cstring_view path, T... params);
|
||||
|
||||
void close() {
|
||||
flush();
|
||||
file_.close();
|
||||
}
|
||||
|
||||
template <typename S, typename... Args>
|
||||
void print(const S& format_str, const Args&... args) {
|
||||
format_to(detail::buffer_appender<char>(*this), format_str, args...);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
Opens a file for writing. Supported parameters passed in `params`:
|
||||
* ``<integer>``: Output flags (``file::WRONLY | file::CREATE`` by default)
|
||||
* ``buffer_size=<integer>``: Output buffer size
|
||||
*/
|
||||
template <typename... T>
|
||||
inline ostream output_file(cstring_view path, T... params) {
|
||||
return {path, detail::ostream_params(params...)};
|
||||
}
|
||||
#endif // FMT_USE_FCNTL
|
||||
|
||||
#ifdef FMT_LOCALE
|
||||
// A "C" numeric locale.
|
||||
class locale {
|
||||
private:
|
||||
# ifdef _WIN32
|
||||
using locale_t = _locale_t;
|
||||
|
||||
static void freelocale(locale_t loc) { _free_locale(loc); }
|
||||
|
||||
static double strtod_l(const char* nptr, char** endptr, _locale_t loc) {
|
||||
return _strtod_l(nptr, endptr, loc);
|
||||
}
|
||||
# endif
|
||||
|
||||
locale_t locale_;
|
||||
|
||||
public:
|
||||
using type = locale_t;
|
||||
locale(const locale&) = delete;
|
||||
void operator=(const locale&) = delete;
|
||||
|
||||
locale() {
|
||||
# ifndef _WIN32
|
||||
locale_ = FMT_SYSTEM(newlocale(LC_NUMERIC_MASK, "C", nullptr));
|
||||
# else
|
||||
locale_ = _create_locale(LC_NUMERIC, "C");
|
||||
# endif
|
||||
if (!locale_) FMT_THROW(system_error(errno, "cannot create locale"));
|
||||
}
|
||||
~locale() { freelocale(locale_); }
|
||||
|
||||
type get() const { return locale_; }
|
||||
|
||||
// Converts string to floating-point number and advances str past the end
|
||||
// of the parsed input.
|
||||
double strtod(const char*& str) const {
|
||||
char* end = nullptr;
|
||||
double result = strtod_l(str, &end, locale_);
|
||||
str = end;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
using Locale FMT_DEPRECATED_ALIAS = locale;
|
||||
#endif // FMT_LOCALE
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_OS_H_
|
||||
177
src/3rdparty/fmt/ostream.h
vendored
177
src/3rdparty/fmt/ostream.h
vendored
@@ -1,177 +0,0 @@
|
||||
// Formatting library for C++ - std::ostream support
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_OSTREAM_H_
|
||||
#define FMT_OSTREAM_H_
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "format.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
template <typename Char> class basic_printf_parse_context;
|
||||
template <typename OutputIt, typename Char> class basic_printf_context;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class Char> class formatbuf : public std::basic_streambuf<Char> {
|
||||
private:
|
||||
using int_type = typename std::basic_streambuf<Char>::int_type;
|
||||
using traits_type = typename std::basic_streambuf<Char>::traits_type;
|
||||
|
||||
buffer<Char>& buffer_;
|
||||
|
||||
public:
|
||||
formatbuf(buffer<Char>& buf) : buffer_(buf) {}
|
||||
|
||||
protected:
|
||||
// The put-area is actually always empty. This makes the implementation
|
||||
// simpler and has the advantage that the streambuf and the buffer are always
|
||||
// in sync and sputc never writes into uninitialized memory. The obvious
|
||||
// disadvantage is that each call to sputc always results in a (virtual) call
|
||||
// to overflow. There is no disadvantage here for sputn since this always
|
||||
// results in a call to xsputn.
|
||||
|
||||
int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE {
|
||||
if (!traits_type::eq_int_type(ch, traits_type::eof()))
|
||||
buffer_.push_back(static_cast<Char>(ch));
|
||||
return ch;
|
||||
}
|
||||
|
||||
std::streamsize xsputn(const Char* s, std::streamsize count) FMT_OVERRIDE {
|
||||
buffer_.append(s, s + count);
|
||||
return count;
|
||||
}
|
||||
};
|
||||
|
||||
struct converter {
|
||||
template <typename T, FMT_ENABLE_IF(is_integral<T>::value)> converter(T);
|
||||
};
|
||||
|
||||
template <typename Char> struct test_stream : std::basic_ostream<Char> {
|
||||
private:
|
||||
void_t<> operator<<(converter);
|
||||
};
|
||||
|
||||
// Hide insertion operators for built-in types.
|
||||
template <typename Char, typename Traits>
|
||||
void_t<> operator<<(std::basic_ostream<Char, Traits>&, Char);
|
||||
template <typename Char, typename Traits>
|
||||
void_t<> operator<<(std::basic_ostream<Char, Traits>&, char);
|
||||
template <typename Traits>
|
||||
void_t<> operator<<(std::basic_ostream<char, Traits>&, char);
|
||||
template <typename Traits>
|
||||
void_t<> operator<<(std::basic_ostream<char, Traits>&, signed char);
|
||||
template <typename Traits>
|
||||
void_t<> operator<<(std::basic_ostream<char, Traits>&, unsigned char);
|
||||
|
||||
// Checks if T has a user-defined operator<< (e.g. not a member of
|
||||
// std::ostream).
|
||||
template <typename T, typename Char> class is_streamable {
|
||||
private:
|
||||
template <typename U>
|
||||
static bool_constant<!std::is_same<decltype(std::declval<test_stream<Char>&>()
|
||||
<< std::declval<U>()),
|
||||
void_t<>>::value>
|
||||
test(int);
|
||||
|
||||
template <typename> static std::false_type test(...);
|
||||
|
||||
using result = decltype(test<T>(0));
|
||||
|
||||
public:
|
||||
static const bool value = result::value;
|
||||
};
|
||||
|
||||
// Write the content of buf to os.
|
||||
template <typename Char>
|
||||
void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {
|
||||
const Char* buf_data = buf.data();
|
||||
using unsigned_streamsize = std::make_unsigned<std::streamsize>::type;
|
||||
unsigned_streamsize size = buf.size();
|
||||
unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());
|
||||
do {
|
||||
unsigned_streamsize n = size <= max_size ? size : max_size;
|
||||
os.write(buf_data, static_cast<std::streamsize>(n));
|
||||
buf_data += n;
|
||||
size -= n;
|
||||
} while (size != 0);
|
||||
}
|
||||
|
||||
template <typename Char, typename T>
|
||||
void format_value(buffer<Char>& buf, const T& value,
|
||||
locale_ref loc = locale_ref()) {
|
||||
formatbuf<Char> format_buf(buf);
|
||||
std::basic_ostream<Char> output(&format_buf);
|
||||
#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
|
||||
if (loc) output.imbue(loc.get<std::locale>());
|
||||
#endif
|
||||
output << value;
|
||||
output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
|
||||
buf.try_resize(buf.size());
|
||||
}
|
||||
|
||||
// Formats an object of type T that has an overloaded ostream operator<<.
|
||||
template <typename T, typename Char>
|
||||
struct fallback_formatter<T, Char, enable_if_t<is_streamable<T, Char>::value>>
|
||||
: private formatter<basic_string_view<Char>, Char> {
|
||||
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
|
||||
-> decltype(ctx.begin()) {
|
||||
return formatter<basic_string_view<Char>, Char>::parse(ctx);
|
||||
}
|
||||
template <typename ParseCtx,
|
||||
FMT_ENABLE_IF(std::is_same<
|
||||
ParseCtx, basic_printf_parse_context<Char>>::value)>
|
||||
auto parse(ParseCtx& ctx) -> decltype(ctx.begin()) {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
template <typename OutputIt>
|
||||
auto format(const T& value, basic_format_context<OutputIt, Char>& ctx)
|
||||
-> OutputIt {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
format_value(buffer, value, ctx.locale());
|
||||
basic_string_view<Char> str(buffer.data(), buffer.size());
|
||||
return formatter<basic_string_view<Char>, Char>::format(str, ctx);
|
||||
}
|
||||
template <typename OutputIt>
|
||||
auto format(const T& value, basic_printf_context<OutputIt, Char>& ctx)
|
||||
-> OutputIt {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
format_value(buffer, value, ctx.locale());
|
||||
return std::copy(buffer.begin(), buffer.end(), ctx.out());
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <typename Char>
|
||||
void vprint(std::basic_ostream<Char>& os, basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
detail::vformat_to(buffer, format_str, args);
|
||||
detail::write_buffer(os, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Prints formatted data to the stream *os*.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::print(cerr, "Don't {}!", "panic");
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
|
||||
void print(std::basic_ostream<Char>& os, const S& format_str, Args&&... args) {
|
||||
vprint(os, to_string_view(format_str),
|
||||
fmt::make_args_checked<Args...>(format_str, args...));
|
||||
}
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_OSTREAM_H_
|
||||
2
src/3rdparty/fmt/posix.h
vendored
2
src/3rdparty/fmt/posix.h
vendored
@@ -1,2 +0,0 @@
|
||||
#include "os.h"
|
||||
#warning "fmt/posix.h is deprecated; use fmt/os.h instead"
|
||||
751
src/3rdparty/fmt/printf.h
vendored
751
src/3rdparty/fmt/printf.h
vendored
@@ -1,751 +0,0 @@
|
||||
// Formatting library for C++ - legacy printf implementation
|
||||
//
|
||||
// Copyright (c) 2012 - 2016, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_PRINTF_H_
|
||||
#define FMT_PRINTF_H_
|
||||
|
||||
#include <algorithm> // std::max
|
||||
#include <limits> // std::numeric_limits
|
||||
|
||||
#include "ostream.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
// Checks if a value fits in int - used to avoid warnings about comparing
|
||||
// signed and unsigned integers.
|
||||
template <bool IsSigned> struct int_checker {
|
||||
template <typename T> static bool fits_in_int(T value) {
|
||||
unsigned max = max_value<int>();
|
||||
return value <= max;
|
||||
}
|
||||
static bool fits_in_int(bool) { return true; }
|
||||
};
|
||||
|
||||
template <> struct int_checker<true> {
|
||||
template <typename T> static bool fits_in_int(T value) {
|
||||
return value >= (std::numeric_limits<int>::min)() &&
|
||||
value <= max_value<int>();
|
||||
}
|
||||
static bool fits_in_int(int) { return true; }
|
||||
};
|
||||
|
||||
class printf_precision_handler {
|
||||
public:
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
int operator()(T value) {
|
||||
if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
|
||||
FMT_THROW(format_error("number is too big"));
|
||||
return (std::max)(static_cast<int>(value), 0);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
int operator()(T) {
|
||||
FMT_THROW(format_error("precision is not integer"));
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
// An argument visitor that returns true iff arg is a zero integer.
|
||||
class is_zero_int {
|
||||
public:
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
bool operator()(T value) {
|
||||
return value == 0;
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
bool operator()(T) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> struct make_unsigned_or_bool : std::make_unsigned<T> {};
|
||||
|
||||
template <> struct make_unsigned_or_bool<bool> { using type = bool; };
|
||||
|
||||
template <typename T, typename Context> class arg_converter {
|
||||
private:
|
||||
using char_type = typename Context::char_type;
|
||||
|
||||
basic_format_arg<Context>& arg_;
|
||||
char_type type_;
|
||||
|
||||
public:
|
||||
arg_converter(basic_format_arg<Context>& arg, char_type type)
|
||||
: arg_(arg), type_(type) {}
|
||||
|
||||
void operator()(bool value) {
|
||||
if (type_ != 's') operator()<bool>(value);
|
||||
}
|
||||
|
||||
template <typename U, FMT_ENABLE_IF(std::is_integral<U>::value)>
|
||||
void operator()(U value) {
|
||||
bool is_signed = type_ == 'd' || type_ == 'i';
|
||||
using target_type = conditional_t<std::is_same<T, void>::value, U, T>;
|
||||
if (const_check(sizeof(target_type) <= sizeof(int))) {
|
||||
// Extra casts are used to silence warnings.
|
||||
if (is_signed) {
|
||||
arg_ = detail::make_arg<Context>(
|
||||
static_cast<int>(static_cast<target_type>(value)));
|
||||
} else {
|
||||
using unsigned_type = typename make_unsigned_or_bool<target_type>::type;
|
||||
arg_ = detail::make_arg<Context>(
|
||||
static_cast<unsigned>(static_cast<unsigned_type>(value)));
|
||||
}
|
||||
} else {
|
||||
if (is_signed) {
|
||||
// glibc's printf doesn't sign extend arguments of smaller types:
|
||||
// std::printf("%lld", -42); // prints "4294967254"
|
||||
// but we don't have to do the same because it's a UB.
|
||||
arg_ = detail::make_arg<Context>(static_cast<long long>(value));
|
||||
} else {
|
||||
arg_ = detail::make_arg<Context>(
|
||||
static_cast<typename make_unsigned_or_bool<U>::type>(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename U, FMT_ENABLE_IF(!std::is_integral<U>::value)>
|
||||
void operator()(U) {} // No conversion needed for non-integral types.
|
||||
};
|
||||
|
||||
// Converts an integer argument to T for printf, if T is an integral type.
|
||||
// If T is void, the argument is converted to corresponding signed or unsigned
|
||||
// type depending on the type specifier: 'd' and 'i' - signed, other -
|
||||
// unsigned).
|
||||
template <typename T, typename Context, typename Char>
|
||||
void convert_arg(basic_format_arg<Context>& arg, Char type) {
|
||||
visit_format_arg(arg_converter<T, Context>(arg, type), arg);
|
||||
}
|
||||
|
||||
// Converts an integer argument to char for printf.
|
||||
template <typename Context> class char_converter {
|
||||
private:
|
||||
basic_format_arg<Context>& arg_;
|
||||
|
||||
public:
|
||||
explicit char_converter(basic_format_arg<Context>& arg) : arg_(arg) {}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
void operator()(T value) {
|
||||
arg_ = detail::make_arg<Context>(
|
||||
static_cast<typename Context::char_type>(value));
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
void operator()(T) {} // No conversion needed for non-integral types.
|
||||
};
|
||||
|
||||
// An argument visitor that return a pointer to a C string if argument is a
|
||||
// string or null otherwise.
|
||||
template <typename Char> struct get_cstring {
|
||||
template <typename T> const Char* operator()(T) { return nullptr; }
|
||||
const Char* operator()(const Char* s) { return s; }
|
||||
};
|
||||
|
||||
// Checks if an argument is a valid printf width specifier and sets
|
||||
// left alignment if it is negative.
|
||||
template <typename Char> class printf_width_handler {
|
||||
private:
|
||||
using format_specs = basic_format_specs<Char>;
|
||||
|
||||
format_specs& specs_;
|
||||
|
||||
public:
|
||||
explicit printf_width_handler(format_specs& specs) : specs_(specs) {}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
unsigned operator()(T value) {
|
||||
auto width = static_cast<uint32_or_64_or_128_t<T>>(value);
|
||||
if (detail::is_negative(value)) {
|
||||
specs_.align = align::left;
|
||||
width = 0 - width;
|
||||
}
|
||||
unsigned int_max = max_value<int>();
|
||||
if (width > int_max) FMT_THROW(format_error("number is too big"));
|
||||
return static_cast<unsigned>(width);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
unsigned operator()(T) {
|
||||
FMT_THROW(format_error("width is not integer"));
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename Context>
|
||||
void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
|
||||
basic_format_args<Context> args) {
|
||||
Context(buffer_appender<Char>(buf), format, args).format();
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// For printing into memory_buffer.
|
||||
template <typename Char, typename Context>
|
||||
FMT_DEPRECATED void printf(detail::buffer<Char>& buf,
|
||||
basic_string_view<Char> format,
|
||||
basic_format_args<Context> args) {
|
||||
return detail::vprintf(buf, format, args);
|
||||
}
|
||||
using detail::vprintf;
|
||||
|
||||
template <typename Char>
|
||||
class basic_printf_parse_context : public basic_format_parse_context<Char> {
|
||||
using basic_format_parse_context<Char>::basic_format_parse_context;
|
||||
};
|
||||
template <typename OutputIt, typename Char> class basic_printf_context;
|
||||
|
||||
/**
|
||||
\rst
|
||||
The ``printf`` argument formatter.
|
||||
\endrst
|
||||
*/
|
||||
template <typename OutputIt, typename Char>
|
||||
class printf_arg_formatter : public detail::arg_formatter_base<OutputIt, Char> {
|
||||
public:
|
||||
using iterator = OutputIt;
|
||||
|
||||
private:
|
||||
using char_type = Char;
|
||||
using base = detail::arg_formatter_base<OutputIt, Char>;
|
||||
using context_type = basic_printf_context<OutputIt, Char>;
|
||||
|
||||
context_type& context_;
|
||||
|
||||
void write_null_pointer(char) {
|
||||
this->specs()->type = 0;
|
||||
this->write("(nil)");
|
||||
}
|
||||
|
||||
void write_null_pointer(wchar_t) {
|
||||
this->specs()->type = 0;
|
||||
this->write(L"(nil)");
|
||||
}
|
||||
|
||||
public:
|
||||
using format_specs = typename base::format_specs;
|
||||
|
||||
/**
|
||||
\rst
|
||||
Constructs an argument formatter object.
|
||||
*buffer* is a reference to the output buffer and *specs* contains format
|
||||
specifier information for standard argument types.
|
||||
\endrst
|
||||
*/
|
||||
printf_arg_formatter(iterator iter, format_specs& specs, context_type& ctx)
|
||||
: base(iter, &specs, detail::locale_ref()), context_(ctx) {}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(fmt::detail::is_integral<T>::value)>
|
||||
iterator operator()(T value) {
|
||||
// MSVC2013 fails to compile separate overloads for bool and char_type so
|
||||
// use std::is_same instead.
|
||||
if (std::is_same<T, bool>::value) {
|
||||
format_specs& fmt_specs = *this->specs();
|
||||
if (fmt_specs.type != 's') return base::operator()(value ? 1 : 0);
|
||||
fmt_specs.type = 0;
|
||||
this->write(value != 0);
|
||||
} else if (std::is_same<T, char_type>::value) {
|
||||
format_specs& fmt_specs = *this->specs();
|
||||
if (fmt_specs.type && fmt_specs.type != 'c')
|
||||
return (*this)(static_cast<int>(value));
|
||||
fmt_specs.sign = sign::none;
|
||||
fmt_specs.alt = false;
|
||||
fmt_specs.fill[0] = ' '; // Ignore '0' flag for char types.
|
||||
// align::numeric needs to be overwritten here since the '0' flag is
|
||||
// ignored for non-numeric types
|
||||
if (fmt_specs.align == align::none || fmt_specs.align == align::numeric)
|
||||
fmt_specs.align = align::right;
|
||||
return base::operator()(value);
|
||||
} else {
|
||||
return base::operator()(value);
|
||||
}
|
||||
return this->out();
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
|
||||
iterator operator()(T value) {
|
||||
return base::operator()(value);
|
||||
}
|
||||
|
||||
/** Formats a null-terminated C string. */
|
||||
iterator operator()(const char* value) {
|
||||
if (value)
|
||||
base::operator()(value);
|
||||
else if (this->specs()->type == 'p')
|
||||
write_null_pointer(char_type());
|
||||
else
|
||||
this->write("(null)");
|
||||
return this->out();
|
||||
}
|
||||
|
||||
/** Formats a null-terminated wide C string. */
|
||||
iterator operator()(const wchar_t* value) {
|
||||
if (value)
|
||||
base::operator()(value);
|
||||
else if (this->specs()->type == 'p')
|
||||
write_null_pointer(char_type());
|
||||
else
|
||||
this->write(L"(null)");
|
||||
return this->out();
|
||||
}
|
||||
|
||||
iterator operator()(basic_string_view<char_type> value) {
|
||||
return base::operator()(value);
|
||||
}
|
||||
|
||||
iterator operator()(monostate value) { return base::operator()(value); }
|
||||
|
||||
/** Formats a pointer. */
|
||||
iterator operator()(const void* value) {
|
||||
if (value) return base::operator()(value);
|
||||
this->specs()->type = 0;
|
||||
write_null_pointer(char_type());
|
||||
return this->out();
|
||||
}
|
||||
|
||||
/** Formats an argument of a custom (user-defined) type. */
|
||||
iterator operator()(typename basic_format_arg<context_type>::handle handle) {
|
||||
handle.format(context_.parse_context(), context_);
|
||||
return this->out();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> struct printf_formatter {
|
||||
printf_formatter() = delete;
|
||||
|
||||
template <typename ParseContext>
|
||||
auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(const T& value, FormatContext& ctx) -> decltype(ctx.out()) {
|
||||
detail::format_value(detail::get_container(ctx.out()), value);
|
||||
return ctx.out();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
This template formats data and writes the output through an output iterator.
|
||||
*/
|
||||
template <typename OutputIt, typename Char> class basic_printf_context {
|
||||
public:
|
||||
/** The character type for the output. */
|
||||
using char_type = Char;
|
||||
using iterator = OutputIt;
|
||||
using format_arg = basic_format_arg<basic_printf_context>;
|
||||
using parse_context_type = basic_printf_parse_context<Char>;
|
||||
template <typename T> using formatter_type = printf_formatter<T>;
|
||||
|
||||
private:
|
||||
using format_specs = basic_format_specs<char_type>;
|
||||
|
||||
OutputIt out_;
|
||||
basic_format_args<basic_printf_context> args_;
|
||||
parse_context_type parse_ctx_;
|
||||
|
||||
static void parse_flags(format_specs& specs, const Char*& it,
|
||||
const Char* end);
|
||||
|
||||
// Returns the argument with specified index or, if arg_index is -1, the next
|
||||
// argument.
|
||||
format_arg get_arg(int arg_index = -1);
|
||||
|
||||
// Parses argument index, flags and width and returns the argument index.
|
||||
int parse_header(const Char*& it, const Char* end, format_specs& specs);
|
||||
|
||||
public:
|
||||
/**
|
||||
\rst
|
||||
Constructs a ``printf_context`` object. References to the arguments are
|
||||
stored in the context object so make sure they have appropriate lifetimes.
|
||||
\endrst
|
||||
*/
|
||||
basic_printf_context(OutputIt out, basic_string_view<char_type> format_str,
|
||||
basic_format_args<basic_printf_context> args)
|
||||
: out_(out), args_(args), parse_ctx_(format_str) {}
|
||||
|
||||
OutputIt out() { return out_; }
|
||||
void advance_to(OutputIt it) { out_ = it; }
|
||||
|
||||
detail::locale_ref locale() { return {}; }
|
||||
|
||||
format_arg arg(int id) const { return args_.get(id); }
|
||||
|
||||
parse_context_type& parse_context() { return parse_ctx_; }
|
||||
|
||||
FMT_CONSTEXPR void on_error(const char* message) {
|
||||
parse_ctx_.on_error(message);
|
||||
}
|
||||
|
||||
/** Formats stored arguments and writes the output to the range. */
|
||||
template <typename ArgFormatter = printf_arg_formatter<OutputIt, Char>>
|
||||
OutputIt format();
|
||||
};
|
||||
|
||||
template <typename OutputIt, typename Char>
|
||||
void basic_printf_context<OutputIt, Char>::parse_flags(format_specs& specs,
|
||||
const Char*& it,
|
||||
const Char* end) {
|
||||
for (; it != end; ++it) {
|
||||
switch (*it) {
|
||||
case '-':
|
||||
specs.align = align::left;
|
||||
break;
|
||||
case '+':
|
||||
specs.sign = sign::plus;
|
||||
break;
|
||||
case '0':
|
||||
specs.fill[0] = '0';
|
||||
break;
|
||||
case ' ':
|
||||
if (specs.sign != sign::plus) {
|
||||
specs.sign = sign::space;
|
||||
}
|
||||
break;
|
||||
case '#':
|
||||
specs.alt = true;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename Char>
|
||||
typename basic_printf_context<OutputIt, Char>::format_arg
|
||||
basic_printf_context<OutputIt, Char>::get_arg(int arg_index) {
|
||||
if (arg_index < 0)
|
||||
arg_index = parse_ctx_.next_arg_id();
|
||||
else
|
||||
parse_ctx_.check_arg_id(--arg_index);
|
||||
return detail::get_arg(*this, arg_index);
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename Char>
|
||||
int basic_printf_context<OutputIt, Char>::parse_header(const Char*& it,
|
||||
const Char* end,
|
||||
format_specs& specs) {
|
||||
int arg_index = -1;
|
||||
char_type c = *it;
|
||||
if (c >= '0' && c <= '9') {
|
||||
// Parse an argument index (if followed by '$') or a width possibly
|
||||
// preceded with '0' flag(s).
|
||||
detail::error_handler eh;
|
||||
int value = parse_nonnegative_int(it, end, eh);
|
||||
if (it != end && *it == '$') { // value is an argument index
|
||||
++it;
|
||||
arg_index = value;
|
||||
} else {
|
||||
if (c == '0') specs.fill[0] = '0';
|
||||
if (value != 0) {
|
||||
// Nonzero value means that we parsed width and don't need to
|
||||
// parse it or flags again, so return now.
|
||||
specs.width = value;
|
||||
return arg_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
parse_flags(specs, it, end);
|
||||
// Parse width.
|
||||
if (it != end) {
|
||||
if (*it >= '0' && *it <= '9') {
|
||||
detail::error_handler eh;
|
||||
specs.width = parse_nonnegative_int(it, end, eh);
|
||||
} else if (*it == '*') {
|
||||
++it;
|
||||
specs.width = static_cast<int>(visit_format_arg(
|
||||
detail::printf_width_handler<char_type>(specs), get_arg()));
|
||||
}
|
||||
}
|
||||
return arg_index;
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename Char>
|
||||
template <typename ArgFormatter>
|
||||
OutputIt basic_printf_context<OutputIt, Char>::format() {
|
||||
auto out = this->out();
|
||||
const Char* start = parse_ctx_.begin();
|
||||
const Char* end = parse_ctx_.end();
|
||||
auto it = start;
|
||||
while (it != end) {
|
||||
char_type c = *it++;
|
||||
if (c != '%') continue;
|
||||
if (it != end && *it == c) {
|
||||
out = std::copy(start, it, out);
|
||||
start = ++it;
|
||||
continue;
|
||||
}
|
||||
out = std::copy(start, it - 1, out);
|
||||
|
||||
format_specs specs;
|
||||
specs.align = align::right;
|
||||
|
||||
// Parse argument index, flags and width.
|
||||
int arg_index = parse_header(it, end, specs);
|
||||
if (arg_index == 0) on_error("argument not found");
|
||||
|
||||
// Parse precision.
|
||||
if (it != end && *it == '.') {
|
||||
++it;
|
||||
c = it != end ? *it : 0;
|
||||
if ('0' <= c && c <= '9') {
|
||||
detail::error_handler eh;
|
||||
specs.precision = parse_nonnegative_int(it, end, eh);
|
||||
} else if (c == '*') {
|
||||
++it;
|
||||
specs.precision = static_cast<int>(
|
||||
visit_format_arg(detail::printf_precision_handler(), get_arg()));
|
||||
} else {
|
||||
specs.precision = 0;
|
||||
}
|
||||
}
|
||||
|
||||
format_arg arg = get_arg(arg_index);
|
||||
// For d, i, o, u, x, and X conversion specifiers, if a precision is
|
||||
// specified, the '0' flag is ignored
|
||||
if (specs.precision >= 0 && arg.is_integral())
|
||||
specs.fill[0] =
|
||||
' '; // Ignore '0' flag for non-numeric types or if '-' present.
|
||||
if (specs.precision >= 0 && arg.type() == detail::type::cstring_type) {
|
||||
auto str = visit_format_arg(detail::get_cstring<Char>(), arg);
|
||||
auto str_end = str + specs.precision;
|
||||
auto nul = std::find(str, str_end, Char());
|
||||
arg = detail::make_arg<basic_printf_context>(basic_string_view<Char>(
|
||||
str,
|
||||
detail::to_unsigned(nul != str_end ? nul - str : specs.precision)));
|
||||
}
|
||||
if (specs.alt && visit_format_arg(detail::is_zero_int(), arg))
|
||||
specs.alt = false;
|
||||
if (specs.fill[0] == '0') {
|
||||
if (arg.is_arithmetic() && specs.align != align::left)
|
||||
specs.align = align::numeric;
|
||||
else
|
||||
specs.fill[0] = ' '; // Ignore '0' flag for non-numeric types or if '-'
|
||||
// flag is also present.
|
||||
}
|
||||
|
||||
// Parse length and convert the argument to the required type.
|
||||
c = it != end ? *it++ : 0;
|
||||
char_type t = it != end ? *it : 0;
|
||||
using detail::convert_arg;
|
||||
switch (c) {
|
||||
case 'h':
|
||||
if (t == 'h') {
|
||||
++it;
|
||||
t = it != end ? *it : 0;
|
||||
convert_arg<signed char>(arg, t);
|
||||
} else {
|
||||
convert_arg<short>(arg, t);
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
if (t == 'l') {
|
||||
++it;
|
||||
t = it != end ? *it : 0;
|
||||
convert_arg<long long>(arg, t);
|
||||
} else {
|
||||
convert_arg<long>(arg, t);
|
||||
}
|
||||
break;
|
||||
case 'j':
|
||||
convert_arg<intmax_t>(arg, t);
|
||||
break;
|
||||
case 'z':
|
||||
convert_arg<size_t>(arg, t);
|
||||
break;
|
||||
case 't':
|
||||
convert_arg<std::ptrdiff_t>(arg, t);
|
||||
break;
|
||||
case 'L':
|
||||
// printf produces garbage when 'L' is omitted for long double, no
|
||||
// need to do the same.
|
||||
break;
|
||||
default:
|
||||
--it;
|
||||
convert_arg<void>(arg, c);
|
||||
}
|
||||
|
||||
// Parse type.
|
||||
if (it == end) FMT_THROW(format_error("invalid format string"));
|
||||
specs.type = static_cast<char>(*it++);
|
||||
if (arg.is_integral()) {
|
||||
// Normalize type.
|
||||
switch (specs.type) {
|
||||
case 'i':
|
||||
case 'u':
|
||||
specs.type = 'd';
|
||||
break;
|
||||
case 'c':
|
||||
visit_format_arg(detail::char_converter<basic_printf_context>(arg),
|
||||
arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
start = it;
|
||||
|
||||
// Format argument.
|
||||
out = visit_format_arg(ArgFormatter(out, specs, *this), arg);
|
||||
}
|
||||
return std::copy(start, it, out);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
using basic_printf_context_t =
|
||||
basic_printf_context<detail::buffer_appender<Char>, Char>;
|
||||
|
||||
using printf_context = basic_printf_context_t<char>;
|
||||
using wprintf_context = basic_printf_context_t<wchar_t>;
|
||||
|
||||
using printf_args = basic_format_args<printf_context>;
|
||||
using wprintf_args = basic_format_args<wprintf_context>;
|
||||
|
||||
/**
|
||||
\rst
|
||||
Constructs an `~fmt::format_arg_store` object that contains references to
|
||||
arguments and can be implicitly converted to `~fmt::printf_args`.
|
||||
\endrst
|
||||
*/
|
||||
template <typename... Args>
|
||||
inline format_arg_store<printf_context, Args...> make_printf_args(
|
||||
const Args&... args) {
|
||||
return {args...};
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Constructs an `~fmt::format_arg_store` object that contains references to
|
||||
arguments and can be implicitly converted to `~fmt::wprintf_args`.
|
||||
\endrst
|
||||
*/
|
||||
template <typename... Args>
|
||||
inline format_arg_store<wprintf_context, Args...> make_wprintf_args(
|
||||
const Args&... args) {
|
||||
return {args...};
|
||||
}
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline std::basic_string<Char> vsprintf(
|
||||
const S& format,
|
||||
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
vprintf(buffer, to_string_view(format), args);
|
||||
return to_string(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Formats arguments and returns the result as a string.
|
||||
|
||||
**Example**::
|
||||
|
||||
std::string message = fmt::sprintf("The answer is %d", 42);
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
|
||||
inline std::basic_string<Char> sprintf(const S& format, const Args&... args) {
|
||||
using context = basic_printf_context_t<Char>;
|
||||
return vsprintf(to_string_view(format), make_format_args<context>(args...));
|
||||
}
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline int vfprintf(
|
||||
std::FILE* f, const S& format,
|
||||
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
vprintf(buffer, to_string_view(format), args);
|
||||
size_t size = buffer.size();
|
||||
return std::fwrite(buffer.data(), sizeof(Char), size, f) < size
|
||||
? -1
|
||||
: static_cast<int>(size);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Prints formatted data to the file *f*.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::fprintf(stderr, "Don't %s!", "panic");
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
|
||||
inline int fprintf(std::FILE* f, const S& format, const Args&... args) {
|
||||
using context = basic_printf_context_t<Char>;
|
||||
return vfprintf(f, to_string_view(format),
|
||||
make_format_args<context>(args...));
|
||||
}
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline int vprintf(
|
||||
const S& format,
|
||||
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
|
||||
return vfprintf(stdout, to_string_view(format), args);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Prints formatted data to ``stdout``.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::printf("Elapsed time: %.2f seconds", 1.23);
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_string<S>::value)>
|
||||
inline int printf(const S& format_str, const Args&... args) {
|
||||
using context = basic_printf_context_t<char_t<S>>;
|
||||
return vprintf(to_string_view(format_str),
|
||||
make_format_args<context>(args...));
|
||||
}
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline int vfprintf(
|
||||
std::basic_ostream<Char>& os, const S& format,
|
||||
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
vprintf(buffer, to_string_view(format), args);
|
||||
detail::write_buffer(os, buffer);
|
||||
return static_cast<int>(buffer.size());
|
||||
}
|
||||
|
||||
/** Formats arguments and writes the output to the range. */
|
||||
template <typename ArgFormatter, typename Char,
|
||||
typename Context =
|
||||
basic_printf_context<typename ArgFormatter::iterator, Char>>
|
||||
typename ArgFormatter::iterator vprintf(
|
||||
detail::buffer<Char>& out, basic_string_view<Char> format_str,
|
||||
basic_format_args<type_identity_t<Context>> args) {
|
||||
typename ArgFormatter::iterator iter(out);
|
||||
Context(iter, format_str, args).template format<ArgFormatter>();
|
||||
return iter;
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Prints formatted data to the stream *os*.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::fprintf(cerr, "Don't %s!", "panic");
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args, typename Char = char_t<S>>
|
||||
inline int fprintf(std::basic_ostream<Char>& os, const S& format_str,
|
||||
const Args&... args) {
|
||||
using context = basic_printf_context_t<Char>;
|
||||
return vfprintf(os, to_string_view(format_str),
|
||||
make_format_args<context>(args...));
|
||||
}
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_PRINTF_H_
|
||||
393
src/3rdparty/fmt/ranges.h
vendored
393
src/3rdparty/fmt/ranges.h
vendored
@@ -1,393 +0,0 @@
|
||||
// Formatting library for C++ - experimental range support
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
//
|
||||
// Copyright (c) 2018 - present, Remotion (Igor Schulz)
|
||||
// All Rights Reserved
|
||||
// {fmt} support for ranges, containers and types tuple interface.
|
||||
|
||||
#ifndef FMT_RANGES_H_
|
||||
#define FMT_RANGES_H_
|
||||
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
|
||||
#include "format.h"
|
||||
|
||||
// output only up to N items from the range.
|
||||
#ifndef FMT_RANGE_OUTPUT_LENGTH_LIMIT
|
||||
# define FMT_RANGE_OUTPUT_LENGTH_LIMIT 256
|
||||
#endif
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
template <typename Char> struct formatting_base {
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return ctx.begin();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename Enable = void>
|
||||
struct formatting_range : formatting_base<Char> {
|
||||
static FMT_CONSTEXPR_DECL const size_t range_length_limit =
|
||||
FMT_RANGE_OUTPUT_LENGTH_LIMIT; // output only up to N items from the
|
||||
// range.
|
||||
Char prefix;
|
||||
Char delimiter;
|
||||
Char postfix;
|
||||
formatting_range() : prefix('{'), delimiter(','), postfix('}') {}
|
||||
static FMT_CONSTEXPR_DECL const bool add_delimiter_spaces = true;
|
||||
static FMT_CONSTEXPR_DECL const bool add_prepostfix_space = false;
|
||||
};
|
||||
|
||||
template <typename Char, typename Enable = void>
|
||||
struct formatting_tuple : formatting_base<Char> {
|
||||
Char prefix;
|
||||
Char delimiter;
|
||||
Char postfix;
|
||||
formatting_tuple() : prefix('('), delimiter(','), postfix(')') {}
|
||||
static FMT_CONSTEXPR_DECL const bool add_delimiter_spaces = true;
|
||||
static FMT_CONSTEXPR_DECL const bool add_prepostfix_space = false;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename RangeT, typename OutputIterator>
|
||||
OutputIterator copy(const RangeT& range, OutputIterator out) {
|
||||
for (auto it = range.begin(), end = range.end(); it != end; ++it)
|
||||
*out++ = *it;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename OutputIterator>
|
||||
OutputIterator copy(const char* str, OutputIterator out) {
|
||||
while (*str) *out++ = *str++;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename OutputIterator>
|
||||
OutputIterator copy(char ch, OutputIterator out) {
|
||||
*out++ = ch;
|
||||
return out;
|
||||
}
|
||||
|
||||
/// Return true value if T has std::string interface, like std::string_view.
|
||||
template <typename T> class is_like_std_string {
|
||||
template <typename U>
|
||||
static auto check(U* p)
|
||||
-> decltype((void)p->find('a'), p->length(), (void)p->data(), int());
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
static FMT_CONSTEXPR_DECL const bool value =
|
||||
is_string<T>::value || !std::is_void<decltype(check<T>(nullptr))>::value;
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
struct is_like_std_string<fmt::basic_string_view<Char>> : std::true_type {};
|
||||
|
||||
template <typename... Ts> struct conditional_helper {};
|
||||
|
||||
template <typename T, typename _ = void> struct is_range_ : std::false_type {};
|
||||
|
||||
#if !FMT_MSC_VER || FMT_MSC_VER > 1800
|
||||
template <typename T>
|
||||
struct is_range_<
|
||||
T, conditional_t<false,
|
||||
conditional_helper<decltype(std::declval<T>().begin()),
|
||||
decltype(std::declval<T>().end())>,
|
||||
void>> : std::true_type {};
|
||||
#endif
|
||||
|
||||
/// tuple_size and tuple_element check.
|
||||
template <typename T> class is_tuple_like_ {
|
||||
template <typename U>
|
||||
static auto check(U* p) -> decltype(std::tuple_size<U>::value, int());
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
static FMT_CONSTEXPR_DECL const bool value =
|
||||
!std::is_void<decltype(check<T>(nullptr))>::value;
|
||||
};
|
||||
|
||||
// Check for integer_sequence
|
||||
#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VER >= 1900
|
||||
template <typename T, T... N>
|
||||
using integer_sequence = std::integer_sequence<T, N...>;
|
||||
template <size_t... N> using index_sequence = std::index_sequence<N...>;
|
||||
template <size_t N> using make_index_sequence = std::make_index_sequence<N>;
|
||||
#else
|
||||
template <typename T, T... N> struct integer_sequence {
|
||||
using value_type = T;
|
||||
|
||||
static FMT_CONSTEXPR size_t size() { return sizeof...(N); }
|
||||
};
|
||||
|
||||
template <size_t... N> using index_sequence = integer_sequence<size_t, N...>;
|
||||
|
||||
template <typename T, size_t N, T... Ns>
|
||||
struct make_integer_sequence : make_integer_sequence<T, N - 1, N - 1, Ns...> {};
|
||||
template <typename T, T... Ns>
|
||||
struct make_integer_sequence<T, 0, Ns...> : integer_sequence<T, Ns...> {};
|
||||
|
||||
template <size_t N>
|
||||
using make_index_sequence = make_integer_sequence<size_t, N>;
|
||||
#endif
|
||||
|
||||
template <class Tuple, class F, size_t... Is>
|
||||
void for_each(index_sequence<Is...>, Tuple&& tup, F&& f) FMT_NOEXCEPT {
|
||||
using std::get;
|
||||
// using free function get<I>(T) now.
|
||||
const int _[] = {0, ((void)f(get<Is>(tup)), 0)...};
|
||||
(void)_; // blocks warnings
|
||||
}
|
||||
|
||||
template <class T>
|
||||
FMT_CONSTEXPR make_index_sequence<std::tuple_size<T>::value> get_indexes(
|
||||
T const&) {
|
||||
return {};
|
||||
}
|
||||
|
||||
template <class Tuple, class F> void for_each(Tuple&& tup, F&& f) {
|
||||
const auto indexes = get_indexes(tup);
|
||||
for_each(indexes, std::forward<Tuple>(tup), std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
using value_type = remove_cvref_t<decltype(*std::declval<Range>().begin())>;
|
||||
|
||||
template <typename Arg, FMT_ENABLE_IF(!is_like_std_string<
|
||||
typename std::decay<Arg>::type>::value)>
|
||||
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&) {
|
||||
return add_space ? " {}" : "{}";
|
||||
}
|
||||
|
||||
template <typename Arg, FMT_ENABLE_IF(is_like_std_string<
|
||||
typename std::decay<Arg>::type>::value)>
|
||||
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&) {
|
||||
return add_space ? " \"{}\"" : "\"{}\"";
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const char*) {
|
||||
return add_space ? " \"{}\"" : "\"{}\"";
|
||||
}
|
||||
FMT_CONSTEXPR const wchar_t* format_str_quoted(bool add_space, const wchar_t*) {
|
||||
return add_space ? L" \"{}\"" : L"\"{}\"";
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const char) {
|
||||
return add_space ? " '{}'" : "'{}'";
|
||||
}
|
||||
FMT_CONSTEXPR const wchar_t* format_str_quoted(bool add_space, const wchar_t) {
|
||||
return add_space ? L" '{}'" : L"'{}'";
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <typename T> struct is_tuple_like {
|
||||
static FMT_CONSTEXPR_DECL const bool value =
|
||||
detail::is_tuple_like_<T>::value && !detail::is_range_<T>::value;
|
||||
};
|
||||
|
||||
template <typename TupleT, typename Char>
|
||||
struct formatter<TupleT, Char, enable_if_t<fmt::is_tuple_like<TupleT>::value>> {
|
||||
private:
|
||||
// C++11 generic lambda for format()
|
||||
template <typename FormatContext> struct format_each {
|
||||
template <typename T> void operator()(const T& v) {
|
||||
if (i > 0) {
|
||||
if (formatting.add_prepostfix_space) {
|
||||
*out++ = ' ';
|
||||
}
|
||||
out = detail::copy(formatting.delimiter, out);
|
||||
}
|
||||
out = format_to(out,
|
||||
detail::format_str_quoted(
|
||||
(formatting.add_delimiter_spaces && i > 0), v),
|
||||
v);
|
||||
++i;
|
||||
}
|
||||
|
||||
formatting_tuple<Char>& formatting;
|
||||
size_t& i;
|
||||
typename std::add_lvalue_reference<decltype(
|
||||
std::declval<FormatContext>().out())>::type out;
|
||||
};
|
||||
|
||||
public:
|
||||
formatting_tuple<Char> formatting;
|
||||
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return formatting.parse(ctx);
|
||||
}
|
||||
|
||||
template <typename FormatContext = format_context>
|
||||
auto format(const TupleT& values, FormatContext& ctx) -> decltype(ctx.out()) {
|
||||
auto out = ctx.out();
|
||||
size_t i = 0;
|
||||
detail::copy(formatting.prefix, out);
|
||||
|
||||
detail::for_each(values, format_each<FormatContext>{formatting, i, out});
|
||||
if (formatting.add_prepostfix_space) {
|
||||
*out++ = ' ';
|
||||
}
|
||||
detail::copy(formatting.postfix, out);
|
||||
|
||||
return ctx.out();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Char> struct is_range {
|
||||
static FMT_CONSTEXPR_DECL const bool value =
|
||||
detail::is_range_<T>::value && !detail::is_like_std_string<T>::value &&
|
||||
!std::is_convertible<T, std::basic_string<Char>>::value &&
|
||||
!std::is_constructible<detail::std_string_view<Char>, T>::value;
|
||||
};
|
||||
|
||||
template <typename T, typename Char>
|
||||
struct formatter<
|
||||
T, Char,
|
||||
enable_if_t<fmt::is_range<T, Char>::value
|
||||
// Workaround a bug in MSVC 2017 and earlier.
|
||||
#if !FMT_MSC_VER || FMT_MSC_VER >= 1927
|
||||
&& has_formatter<detail::value_type<T>, format_context>::value
|
||||
#endif
|
||||
>> {
|
||||
formatting_range<Char> formatting;
|
||||
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return formatting.parse(ctx);
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
typename FormatContext::iterator format(const T& values, FormatContext& ctx) {
|
||||
auto out = detail::copy(formatting.prefix, ctx.out());
|
||||
size_t i = 0;
|
||||
auto it = values.begin();
|
||||
auto end = values.end();
|
||||
for (; it != end; ++it) {
|
||||
if (i > 0) {
|
||||
if (formatting.add_prepostfix_space) *out++ = ' ';
|
||||
out = detail::copy(formatting.delimiter, out);
|
||||
}
|
||||
out = format_to(out,
|
||||
detail::format_str_quoted(
|
||||
(formatting.add_delimiter_spaces && i > 0), *it),
|
||||
*it);
|
||||
if (++i > formatting.range_length_limit) {
|
||||
out = format_to(out, " ... <other elements>");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (formatting.add_prepostfix_space) *out++ = ' ';
|
||||
return detail::copy(formatting.postfix, out);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename... T> struct tuple_arg_join : detail::view {
|
||||
const std::tuple<T...>& tuple;
|
||||
basic_string_view<Char> sep;
|
||||
|
||||
tuple_arg_join(const std::tuple<T...>& t, basic_string_view<Char> s)
|
||||
: tuple{t}, sep{s} {}
|
||||
};
|
||||
|
||||
template <typename Char, typename... T>
|
||||
struct formatter<tuple_arg_join<Char, T...>, Char> {
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
typename FormatContext::iterator format(
|
||||
const tuple_arg_join<Char, T...>& value, FormatContext& ctx) {
|
||||
return format(value, ctx, detail::make_index_sequence<sizeof...(T)>{});
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename FormatContext, size_t... N>
|
||||
typename FormatContext::iterator format(
|
||||
const tuple_arg_join<Char, T...>& value, FormatContext& ctx,
|
||||
detail::index_sequence<N...>) {
|
||||
return format_args(value, ctx, std::get<N>(value.tuple)...);
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
typename FormatContext::iterator format_args(
|
||||
const tuple_arg_join<Char, T...>&, FormatContext& ctx) {
|
||||
// NOTE: for compilers that support C++17, this empty function instantiation
|
||||
// can be replaced with a constexpr branch in the variadic overload.
|
||||
return ctx.out();
|
||||
}
|
||||
|
||||
template <typename FormatContext, typename Arg, typename... Args>
|
||||
typename FormatContext::iterator format_args(
|
||||
const tuple_arg_join<Char, T...>& value, FormatContext& ctx,
|
||||
const Arg& arg, const Args&... args) {
|
||||
using base = formatter<typename std::decay<Arg>::type, Char>;
|
||||
auto out = ctx.out();
|
||||
out = base{}.format(arg, ctx);
|
||||
if (sizeof...(Args) > 0) {
|
||||
out = std::copy(value.sep.begin(), value.sep.end(), out);
|
||||
ctx.advance_to(out);
|
||||
return format_args(value, ctx, args...);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
\rst
|
||||
Returns an object that formats `tuple` with elements separated by `sep`.
|
||||
|
||||
**Example**::
|
||||
|
||||
std::tuple<int, char> t = {1, 'a'};
|
||||
fmt::print("{}", fmt::join(t, ", "));
|
||||
// Output: "1, a"
|
||||
\endrst
|
||||
*/
|
||||
template <typename... T>
|
||||
FMT_CONSTEXPR tuple_arg_join<char, T...> join(const std::tuple<T...>& tuple,
|
||||
string_view sep) {
|
||||
return {tuple, sep};
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
FMT_CONSTEXPR tuple_arg_join<wchar_t, T...> join(const std::tuple<T...>& tuple,
|
||||
wstring_view sep) {
|
||||
return {tuple, sep};
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Returns an object that formats `initializer_list` with elements separated by
|
||||
`sep`.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::print("{}", fmt::join({1, 2, 3}, ", "));
|
||||
// Output: "1, 2, 3"
|
||||
\endrst
|
||||
*/
|
||||
template <typename T>
|
||||
arg_join<const T*, const T*, char> join(std::initializer_list<T> list,
|
||||
string_view sep) {
|
||||
return join(std::begin(list), std::end(list), sep);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
arg_join<const T*, const T*, wchar_t> join(std::initializer_list<T> list,
|
||||
wstring_view sep) {
|
||||
return join(std::begin(list), std::end(list), sep);
|
||||
}
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_RANGES_H_
|
||||
45
src/3rdparty/hwloc/AUTHORS
vendored
45
src/3rdparty/hwloc/AUTHORS
vendored
@@ -1,45 +0,0 @@
|
||||
hwloc Authors
|
||||
=============
|
||||
|
||||
The following cumulative list contains the names of most individuals
|
||||
who have committed code to the hwloc repository
|
||||
(either directly or through a third party).
|
||||
|
||||
Name Affiliation(s)
|
||||
--------------------------- --------------------
|
||||
Grzegorz Andrejczuk Intel
|
||||
Cédric Augonnet University of Bordeaux
|
||||
Guillaume Beauchamp Inria
|
||||
Ahmad Boissetri Binzagr Inria
|
||||
Cyril Bordage Inria
|
||||
Nicholas Buroker UWL
|
||||
Christopher M. Cantalupo Intel
|
||||
Jérôme Clet-Ortega University of Bordeaux
|
||||
Ludovic Courtès Inria
|
||||
Clément Foyer Inria
|
||||
Nathalie Furmento CNRS
|
||||
Bryon Gloden
|
||||
Brice Goglin Inria
|
||||
Gilles Gouaillardet RIST
|
||||
Valentin Hoyet Inria
|
||||
Joshua Hursey UWL
|
||||
Alexey Kardashevskiy IBM
|
||||
Rob Latham ANL
|
||||
Douglas MacFarland UWL
|
||||
Marc Marí BSC
|
||||
Jonathan L Peyton Intel
|
||||
Piotr Luc Intel
|
||||
Antoine Rougier intern from University of Bordeaux
|
||||
Jeff Squyres Cisco
|
||||
Samuel Thibault University of Bordeaux
|
||||
Jean-Yves VET DDN
|
||||
Benjamin Worpitz
|
||||
Jeff Zhao Zhaoxin
|
||||
|
||||
Affiliaion abbreviations:
|
||||
-------------------------
|
||||
ANL = Argonne National Lab
|
||||
BSC = Barcelona Supercomputing Center
|
||||
Cisco = Cisco Systems, Inc.
|
||||
CNRS = Centre national de la recherche scientifique (France)
|
||||
UWL = University of Wisconsin-La Crosse
|
||||
40
src/3rdparty/hwloc/CMakeLists.txt
vendored
40
src/3rdparty/hwloc/CMakeLists.txt
vendored
@@ -1,40 +0,0 @@
|
||||
cmake_minimum_required (VERSION 2.8.12)
|
||||
project (hwloc C)
|
||||
|
||||
include_directories(include)
|
||||
include_directories(src)
|
||||
|
||||
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
|
||||
set(CMAKE_C_FLAGS_RELEASE "/MT /O2 /Ob2 /DNDEBUG")
|
||||
|
||||
set(HEADERS
|
||||
include/hwloc.h
|
||||
src/static-components.h
|
||||
)
|
||||
|
||||
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/traversal.c
|
||||
src/memattrs.c
|
||||
src/cpukinds.c
|
||||
)
|
||||
|
||||
add_library(hwloc STATIC
|
||||
${HEADERS}
|
||||
${SOURCES}
|
||||
)
|
||||
39
src/3rdparty/hwloc/COPYING
vendored
39
src/3rdparty/hwloc/COPYING
vendored
@@ -1,39 +0,0 @@
|
||||
Copyright © 2004-2006 The Trustees of Indiana University and Indiana University Research and Technology Corporation. All rights reserved.
|
||||
Copyright © 2004-2005 The University of Tennessee and The University of Tennessee Research Foundation. All rights reserved.
|
||||
Copyright © 2004-2005 High Performance Computing Center Stuttgart, University of Stuttgart. All rights reserved.
|
||||
Copyright © 2004-2005 The Regents of the University of California. All rights reserved.
|
||||
Copyright © 2009 CNRS
|
||||
Copyright © 2009-2016 Inria. All rights reserved.
|
||||
Copyright © 2009-2015 Université Bordeaux
|
||||
Copyright © 2009-2015 Cisco Systems, Inc. All rights reserved.
|
||||
Copyright © 2009-2012 Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright © 2010 IBM
|
||||
Copyright © 2010 Jirka Hladky
|
||||
Copyright © 2012 Aleksej Saushev, The NetBSD Foundation
|
||||
Copyright © 2012 Blue Brain Project, EPFL. All rights reserved.
|
||||
Copyright © 2013-2014 University of Wisconsin-La Crosse. All rights reserved.
|
||||
Copyright © 2015 Research Organization for Information Science and Technology (RIST). All rights reserved.
|
||||
Copyright © 2015-2016 Intel, Inc. All rights reserved.
|
||||
See COPYING in top-level directory.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
1978
src/3rdparty/hwloc/NEWS
vendored
1978
src/3rdparty/hwloc/NEWS
vendored
File diff suppressed because it is too large
Load Diff
85
src/3rdparty/hwloc/README
vendored
85
src/3rdparty/hwloc/README
vendored
@@ -1,85 +0,0 @@
|
||||
Introduction
|
||||
|
||||
The Hardware Locality (hwloc) software project aims at easing the process of
|
||||
discovering hardware resources in parallel architectures. It offers
|
||||
command-line tools and a C API for consulting these resources, their locality,
|
||||
attributes, and interconnection. hwloc primarily aims at helping
|
||||
high-performance computing (HPC) applications, but is also applicable to any
|
||||
project seeking to exploit code and/or data locality on modern computing
|
||||
platforms.
|
||||
|
||||
hwloc is actually made of two subprojects distributed together:
|
||||
|
||||
* The original hwloc project for describing the internals of computing nodes.
|
||||
It is described in details starting at section Hardware Locality (hwloc)
|
||||
Introduction.
|
||||
* The network-oriented companion called netloc (Network Locality), described
|
||||
in details starting with section Network Locality (netloc).
|
||||
|
||||
See also the Related pages tab above for links to other sections.
|
||||
|
||||
Netloc may be disabled, but the original hwloc cannot. Both hwloc and netloc
|
||||
APIs are documented after these sections.
|
||||
|
||||
Installation
|
||||
|
||||
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.
|
||||
|
||||
Basic Installation
|
||||
|
||||
Installation is the fairly common GNU-based process:
|
||||
|
||||
shell$ ./configure --prefix=...
|
||||
shell$ make
|
||||
shell$ make install
|
||||
|
||||
hwloc- and netloc-specific configure options and requirements are documented in
|
||||
sections hwloc Installation and Netloc Installation respectively.
|
||||
|
||||
Also note that if you install supplemental libraries in non-standard locations,
|
||||
hwloc's configure script may not be able to find them without some help. You
|
||||
may need to specify additional CPPFLAGS, LDFLAGS, or PKG_CONFIG_PATH values on
|
||||
the configure command line.
|
||||
|
||||
For example, if libpciaccess was installed into /opt/pciaccess, hwloc's
|
||||
configure script may not find it be default. Try adding PKG_CONFIG_PATH to the
|
||||
./configure command line, like this:
|
||||
|
||||
./configure PKG_CONFIG_PATH=/opt/pciaccess/lib/pkgconfig ...
|
||||
|
||||
Running the "lstopo" tool is a good way to check as a graphical output whether
|
||||
hwloc properly detected the architecture of your node. Netloc command-line
|
||||
tools can be used to display the network topology interconnecting your nodes.
|
||||
|
||||
Installing from a Git clone
|
||||
|
||||
Additionally, the code can be directly cloned from Git:
|
||||
|
||||
shell$ git clone https://github.com/open-mpi/hwloc.git
|
||||
shell$ cd hwloc
|
||||
shell$ ./autogen.sh
|
||||
|
||||
Note that GNU Autoconf >=2.63, Automake >=1.11 and Libtool >=2.2.6 are required
|
||||
when building from a Git clone.
|
||||
|
||||
Nightly development snapshots are available on the web site, they can be
|
||||
configured and built without any need for Git or GNU Autotools.
|
||||
|
||||
Questions and Bugs
|
||||
|
||||
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 (https://
|
||||
www.open-mpi.org/community/lists/hwloc.php).
|
||||
|
||||
There is also a #hwloc IRC channel on Freenode (irc.freenode.net).
|
||||
|
||||
|
||||
|
||||
See https://www.open-mpi.org/projects/hwloc/doc/ for more hwloc documentation.
|
||||
47
src/3rdparty/hwloc/VERSION
vendored
47
src/3rdparty/hwloc/VERSION
vendored
@@ -1,47 +0,0 @@
|
||||
# This is the VERSION file for hwloc, describing the precise version
|
||||
# of hwloc in this distribution. The various components of the version
|
||||
# number below are combined to form a single version number string.
|
||||
|
||||
# major, minor, and release are generally combined in the form
|
||||
# <major>.<minor>.<release>. If release is zero, then it is omitted.
|
||||
|
||||
# Please update HWLOC_VERSION* in contrib/windows/hwloc_config.h too.
|
||||
|
||||
major=2
|
||||
minor=7
|
||||
release=1
|
||||
|
||||
# greek is used for alpha or beta release tags. If it is non-empty,
|
||||
# it will be appended to the version number. It does not have to be
|
||||
# numeric. Common examples include a1 (alpha release 1), b1 (beta
|
||||
# release 1), sc2005 (Super Computing 2005 release). The only
|
||||
# requirement is that it must be entirely printable ASCII characters
|
||||
# and have no white space.
|
||||
|
||||
greek=
|
||||
|
||||
# The date when this release was created
|
||||
|
||||
date="Mar 20, 2022"
|
||||
|
||||
# If snapshot=1, then use the value from snapshot_version as the
|
||||
# entire hwloc version (i.e., ignore major, minor, release, and
|
||||
# greek). This is only set to 1 when making snapshot tarballs.
|
||||
snapshot=0
|
||||
snapshot_version=${major}.${minor}.${release}${greek}-git
|
||||
|
||||
# The shared library version of hwloc's public library. This version
|
||||
# is maintained in accordance with the "Library Interface Versions"
|
||||
# chapter from the GNU Libtool documentation. Notes:
|
||||
|
||||
# 1. Since version numbers are associated with *releases*, the version
|
||||
# number maintained on the hwloc git master (and developer branches)
|
||||
# is always 0:0:0.
|
||||
|
||||
# 2. Version numbers are described in the Libtool current:revision:age
|
||||
# format.
|
||||
|
||||
libhwloc_so_version=20:3:5
|
||||
libnetloc_so_version=0:0:0
|
||||
|
||||
# Please also update the <TargetName> lines in contrib/windows/libhwloc.vcxproj
|
||||
2578
src/3rdparty/hwloc/include/hwloc.h
vendored
2578
src/3rdparty/hwloc/include/hwloc.h
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2021 Inria. All rights reserved.
|
||||
* Copyright © 2009-2012 Université Bordeaux
|
||||
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/* The configuration file */
|
||||
|
||||
#ifndef HWLOC_CONFIG_H
|
||||
#define HWLOC_CONFIG_H
|
||||
|
||||
#define HWLOC_VERSION "2.7.1"
|
||||
#define HWLOC_VERSION_MAJOR 2
|
||||
#define HWLOC_VERSION_MINOR 7
|
||||
#define HWLOC_VERSION_RELEASE 1
|
||||
#define HWLOC_VERSION_GREEK ""
|
||||
|
||||
#define __hwloc_restrict
|
||||
#define __hwloc_inline __inline
|
||||
|
||||
#define __hwloc_attribute_unused
|
||||
#define __hwloc_attribute_malloc
|
||||
#define __hwloc_attribute_const
|
||||
#define __hwloc_attribute_pure
|
||||
#define __hwloc_attribute_deprecated
|
||||
#define __hwloc_attribute_may_alias
|
||||
#define __hwloc_attribute_warn_unused_result
|
||||
|
||||
/* Defined to 1 if you have the `windows.h' header. */
|
||||
#define HWLOC_HAVE_WINDOWS_H 1
|
||||
#define hwloc_pid_t HANDLE
|
||||
#define hwloc_thread_t HANDLE
|
||||
|
||||
#include <windows.h>
|
||||
#include <BaseTsd.h>
|
||||
typedef DWORDLONG hwloc_uint64_t;
|
||||
|
||||
#if defined( _USRDLL ) /* dynamic linkage */
|
||||
#if defined( DECLSPEC_EXPORTS )
|
||||
#define HWLOC_DECLSPEC __declspec(dllexport)
|
||||
#else
|
||||
#define HWLOC_DECLSPEC __declspec(dllimport)
|
||||
#endif
|
||||
#else /* static linkage */
|
||||
#define HWLOC_DECLSPEC
|
||||
#endif
|
||||
|
||||
/* Whether we need to re-define all the hwloc public symbols or not */
|
||||
#define HWLOC_SYM_TRANSFORM 0
|
||||
|
||||
/* The hwloc symbol prefix */
|
||||
#define HWLOC_SYM_PREFIX hwloc_
|
||||
|
||||
/* The hwloc symbol prefix in all caps */
|
||||
#define HWLOC_SYM_PREFIX_CAPS HWLOC_
|
||||
|
||||
#endif /* HWLOC_CONFIG_H */
|
||||
494
src/3rdparty/hwloc/include/hwloc/bitmap.h
vendored
494
src/3rdparty/hwloc/include/hwloc/bitmap.h
vendored
@@ -1,494 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief The bitmap API, for use in hwloc itself.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_BITMAP_H
|
||||
#define HWLOC_BITMAP_H
|
||||
|
||||
#include "hwloc/autogen/config.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup hwlocality_bitmap The bitmap API
|
||||
*
|
||||
* The ::hwloc_bitmap_t type represents a set of integers (positive or null).
|
||||
* A bitmap may be of infinite size (all bits are set after some point).
|
||||
* A bitmap may even be full if all bits are set.
|
||||
*
|
||||
* Bitmaps are used by hwloc for sets of OS processors
|
||||
* (which may actually be hardware threads) as by ::hwloc_cpuset_t
|
||||
* (a typedef for ::hwloc_bitmap_t), or sets of NUMA memory nodes
|
||||
* as ::hwloc_nodeset_t (also a typedef for ::hwloc_bitmap_t).
|
||||
* Those are used for cpuset and nodeset fields in the ::hwloc_obj structure,
|
||||
* see \ref hwlocality_object_sets.
|
||||
*
|
||||
* <em>Both CPU and node sets are always indexed by OS physical number.</em>
|
||||
* However users should usually not build CPU and node sets manually
|
||||
* (e.g. with hwloc_bitmap_set()).
|
||||
* One should rather use existing object sets and combine them with
|
||||
* hwloc_bitmap_or(), etc.
|
||||
* For instance, binding the current thread on a pair of cores may be performed with:
|
||||
* \code
|
||||
* hwloc_obj_t core1 = ... , core2 = ... ;
|
||||
* hwloc_bitmap_t set = hwloc_bitmap_alloc();
|
||||
* hwloc_bitmap_or(set, core1->cpuset, core2->cpuset);
|
||||
* hwloc_set_cpubind(topology, set, HWLOC_CPUBIND_THREAD);
|
||||
* hwloc_bitmap_free(set);
|
||||
* \endcode
|
||||
*
|
||||
* \note Most functions below return an int that may be negative in case of
|
||||
* error. The usual error case would be an internal failure to realloc/extend
|
||||
* the storage of the bitmap (\p errno would be set to \c ENOMEM).
|
||||
*
|
||||
* \note Several examples of using the bitmap API are available under the
|
||||
* doc/examples/ directory in the source tree.
|
||||
* Regression tests such as tests/hwloc/hwloc_bitmap*.c also make intensive use
|
||||
* of this API.
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** \brief
|
||||
* Set of bits represented as an opaque pointer to an internal bitmap.
|
||||
*/
|
||||
typedef struct hwloc_bitmap_s * hwloc_bitmap_t;
|
||||
/** \brief a non-modifiable ::hwloc_bitmap_t */
|
||||
typedef const struct hwloc_bitmap_s * hwloc_const_bitmap_t;
|
||||
|
||||
|
||||
/*
|
||||
* Bitmap allocation, freeing and copying.
|
||||
*/
|
||||
|
||||
/** \brief Allocate a new empty bitmap.
|
||||
*
|
||||
* \returns A valid bitmap or \c NULL.
|
||||
*
|
||||
* The bitmap should be freed by a corresponding call to
|
||||
* hwloc_bitmap_free().
|
||||
*/
|
||||
HWLOC_DECLSPEC hwloc_bitmap_t hwloc_bitmap_alloc(void) __hwloc_attribute_malloc;
|
||||
|
||||
/** \brief Allocate a new full bitmap. */
|
||||
HWLOC_DECLSPEC hwloc_bitmap_t hwloc_bitmap_alloc_full(void) __hwloc_attribute_malloc;
|
||||
|
||||
/** \brief Free bitmap \p bitmap.
|
||||
*
|
||||
* If \p bitmap is \c NULL, no operation is performed.
|
||||
*/
|
||||
HWLOC_DECLSPEC void hwloc_bitmap_free(hwloc_bitmap_t bitmap);
|
||||
|
||||
/** \brief Duplicate bitmap \p bitmap by allocating a new bitmap and copying \p bitmap contents.
|
||||
*
|
||||
* If \p bitmap is \c NULL, \c NULL is returned.
|
||||
*/
|
||||
HWLOC_DECLSPEC hwloc_bitmap_t hwloc_bitmap_dup(hwloc_const_bitmap_t bitmap) __hwloc_attribute_malloc;
|
||||
|
||||
/** \brief Copy the contents of bitmap \p src into the already allocated bitmap \p dst */
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_copy(hwloc_bitmap_t dst, hwloc_const_bitmap_t src);
|
||||
|
||||
|
||||
/*
|
||||
* Bitmap/String Conversion
|
||||
*/
|
||||
|
||||
/** \brief Stringify a bitmap.
|
||||
*
|
||||
* Up to \p buflen characters may be written in buffer \p buf.
|
||||
*
|
||||
* If \p buflen is 0, \p buf may safely be \c NULL.
|
||||
*
|
||||
* \return the number of character that were actually written if not truncating,
|
||||
* or that would have been written (not including the ending \\0).
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);
|
||||
|
||||
/** \brief Stringify a bitmap into a newly allocated string.
|
||||
*
|
||||
* \return -1 on error.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);
|
||||
|
||||
/** \brief Parse a bitmap string and stores it in bitmap \p bitmap.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_sscanf(hwloc_bitmap_t bitmap, const char * __hwloc_restrict string);
|
||||
|
||||
/** \brief Stringify a bitmap in the list format.
|
||||
*
|
||||
* Lists are comma-separated indexes or ranges.
|
||||
* Ranges are dash separated indexes.
|
||||
* The last range may not have an ending indexes if the bitmap is infinitely set.
|
||||
*
|
||||
* Up to \p buflen characters may be written in buffer \p buf.
|
||||
*
|
||||
* If \p buflen is 0, \p buf may safely be \c NULL.
|
||||
*
|
||||
* \return the number of character that were actually written if not truncating,
|
||||
* or that would have been written (not including the ending \\0).
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_list_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);
|
||||
|
||||
/** \brief Stringify a bitmap into a newly allocated list string.
|
||||
*
|
||||
* \return -1 on error.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_list_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);
|
||||
|
||||
/** \brief Parse a list string and stores it in bitmap \p bitmap.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_list_sscanf(hwloc_bitmap_t bitmap, const char * __hwloc_restrict string);
|
||||
|
||||
/** \brief Stringify a bitmap in the taskset-specific format.
|
||||
*
|
||||
* The taskset command manipulates bitmap strings that contain a single
|
||||
* (possible very long) hexadecimal number starting with 0x.
|
||||
*
|
||||
* Up to \p buflen characters may be written in buffer \p buf.
|
||||
*
|
||||
* If \p buflen is 0, \p buf may safely be \c NULL.
|
||||
*
|
||||
* \return the number of character that were actually written if not truncating,
|
||||
* or that would have been written (not including the ending \\0).
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_taskset_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);
|
||||
|
||||
/** \brief Stringify a bitmap into a newly allocated taskset-specific string.
|
||||
*
|
||||
* \return -1 on error.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_taskset_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);
|
||||
|
||||
/** \brief Parse a taskset-specific bitmap string and stores it in bitmap \p bitmap.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_taskset_sscanf(hwloc_bitmap_t bitmap, const char * __hwloc_restrict string);
|
||||
|
||||
|
||||
/*
|
||||
* Building bitmaps.
|
||||
*/
|
||||
|
||||
/** \brief Empty the bitmap \p bitmap */
|
||||
HWLOC_DECLSPEC void hwloc_bitmap_zero(hwloc_bitmap_t bitmap);
|
||||
|
||||
/** \brief Fill bitmap \p bitmap with all possible indexes (even if those objects don't exist or are otherwise unavailable) */
|
||||
HWLOC_DECLSPEC void hwloc_bitmap_fill(hwloc_bitmap_t bitmap);
|
||||
|
||||
/** \brief Empty the bitmap \p bitmap and add bit \p id */
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_only(hwloc_bitmap_t bitmap, unsigned id);
|
||||
|
||||
/** \brief Fill the bitmap \p and clear the index \p id */
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_allbut(hwloc_bitmap_t bitmap, unsigned id);
|
||||
|
||||
/** \brief Setup bitmap \p bitmap from unsigned long \p mask */
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_from_ulong(hwloc_bitmap_t bitmap, unsigned long mask);
|
||||
|
||||
/** \brief Setup bitmap \p bitmap from unsigned long \p mask used as \p i -th subset */
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_from_ith_ulong(hwloc_bitmap_t bitmap, unsigned i, unsigned long mask);
|
||||
|
||||
/** \brief Setup bitmap \p bitmap from unsigned longs \p masks used as first \p nr subsets */
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_from_ulongs(hwloc_bitmap_t bitmap, unsigned nr, const unsigned long *masks);
|
||||
|
||||
|
||||
/*
|
||||
* Modifying bitmaps.
|
||||
*/
|
||||
|
||||
/** \brief Add index \p id in bitmap \p bitmap */
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_set(hwloc_bitmap_t bitmap, unsigned id);
|
||||
|
||||
/** \brief Add indexes from \p begin to \p end in bitmap \p bitmap.
|
||||
*
|
||||
* If \p end is \c -1, the range is infinite.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_set_range(hwloc_bitmap_t bitmap, unsigned begin, int end);
|
||||
|
||||
/** \brief Replace \p i -th subset of bitmap \p bitmap with unsigned long \p mask */
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_set_ith_ulong(hwloc_bitmap_t bitmap, unsigned i, unsigned long mask);
|
||||
|
||||
/** \brief Remove index \p id from bitmap \p bitmap */
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_clr(hwloc_bitmap_t bitmap, unsigned id);
|
||||
|
||||
/** \brief Remove indexes from \p begin to \p end in bitmap \p bitmap.
|
||||
*
|
||||
* If \p end is \c -1, the range is infinite.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_clr_range(hwloc_bitmap_t bitmap, unsigned begin, int end);
|
||||
|
||||
/** \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 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
|
||||
* of these PUs.
|
||||
* It avoids a migration overhead and cache-line ping-pongs between PUs.
|
||||
*
|
||||
* \note This function is NOT meant to distribute multiple processes
|
||||
* within a single CPU set. It always return the same single bit when
|
||||
* called multiple times on the same input set. hwloc_distrib() may
|
||||
* be used for generating CPU sets to distribute multiple tasks below
|
||||
* a single multi-PU object.
|
||||
*
|
||||
* \note This function cannot be applied to an object set directly. It
|
||||
* should be applied to a copy (which may be obtained with hwloc_bitmap_dup()).
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_singlify(hwloc_bitmap_t bitmap);
|
||||
|
||||
|
||||
/*
|
||||
* Consulting bitmaps.
|
||||
*/
|
||||
|
||||
/** \brief Convert the beginning part of bitmap \p bitmap into unsigned long \p mask */
|
||||
HWLOC_DECLSPEC unsigned long hwloc_bitmap_to_ulong(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
|
||||
|
||||
/** \brief Convert the \p i -th subset of bitmap \p bitmap into unsigned long mask */
|
||||
HWLOC_DECLSPEC unsigned long hwloc_bitmap_to_ith_ulong(hwloc_const_bitmap_t bitmap, unsigned i) __hwloc_attribute_pure;
|
||||
|
||||
/** \brief Convert the first \p nr subsets of bitmap \p bitmap into the array of \p nr unsigned long \p masks
|
||||
*
|
||||
* \p nr may be determined earlier with hwloc_bitmap_nr_ulongs().
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_to_ulongs(hwloc_const_bitmap_t bitmap, unsigned nr, unsigned long *masks);
|
||||
|
||||
/** \brief Return the number of unsigned longs required for storing bitmap \p bitmap entirely
|
||||
*
|
||||
* This is the number of contiguous unsigned longs from the very first bit of the bitmap
|
||||
* (even if unset) up to the last set bit.
|
||||
* This is useful for knowing the \p nr parameter to pass to hwloc_bitmap_to_ulongs()
|
||||
* (or which calls to hwloc_bitmap_to_ith_ulong() are needed)
|
||||
* to entirely convert a bitmap into multiple unsigned longs.
|
||||
*
|
||||
* When called on the output of hwloc_topology_get_topology_cpuset(),
|
||||
* the returned number is large enough for all cpusets of the topology.
|
||||
*
|
||||
* \return -1 if \p bitmap is infinite.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_nr_ulongs(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
|
||||
|
||||
/** \brief Test whether index \p id is part of bitmap \p bitmap.
|
||||
*
|
||||
* \return 1 if the bit at index \p id is set in bitmap \p bitmap, 0 otherwise.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_isset(hwloc_const_bitmap_t bitmap, unsigned id) __hwloc_attribute_pure;
|
||||
|
||||
/** \brief Test whether bitmap \p bitmap is empty
|
||||
*
|
||||
* \return 1 if bitmap is empty, 0 otherwise.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_iszero(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
|
||||
|
||||
/** \brief Test whether bitmap \p bitmap is completely full
|
||||
*
|
||||
* \return 1 if bitmap is full, 0 otherwise.
|
||||
*
|
||||
* \note A full bitmap is always infinitely set.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_isfull(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
|
||||
|
||||
/** \brief Compute the first index (least significant bit) in bitmap \p bitmap
|
||||
*
|
||||
* \return -1 if no index is set in \p bitmap.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_first(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
|
||||
|
||||
/** \brief Compute the next index in bitmap \p bitmap which is after index \p prev
|
||||
*
|
||||
* If \p prev is -1, the first index is returned.
|
||||
*
|
||||
* \return -1 if no index with higher index is set in \p bitmap.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_next(hwloc_const_bitmap_t bitmap, int prev) __hwloc_attribute_pure;
|
||||
|
||||
/** \brief Compute the last index (most significant bit) in bitmap \p bitmap
|
||||
*
|
||||
* \return -1 if no index is set in \p bitmap, or if \p bitmap is infinitely set.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_last(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
|
||||
|
||||
/** \brief Compute the "weight" of bitmap \p bitmap (i.e., number of
|
||||
* indexes that are in the bitmap).
|
||||
*
|
||||
* \return the number of indexes that are in the bitmap.
|
||||
*
|
||||
* \return -1 if \p bitmap is infinitely set.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_weight(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
|
||||
|
||||
/** \brief Compute the first unset index (least significant bit) in bitmap \p bitmap
|
||||
*
|
||||
* \return -1 if no index is unset in \p bitmap.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_first_unset(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
|
||||
|
||||
/** \brief Compute the next unset index in bitmap \p bitmap which is after index \p prev
|
||||
*
|
||||
* If \p prev is -1, the first unset index is returned.
|
||||
*
|
||||
* \return -1 if no index with higher index is unset in \p bitmap.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_next_unset(hwloc_const_bitmap_t bitmap, int prev) __hwloc_attribute_pure;
|
||||
|
||||
/** \brief Compute the last unset index (most significant bit) in bitmap \p bitmap
|
||||
*
|
||||
* \return -1 if no index is unset in \p bitmap, or if \p bitmap is infinitely set.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_last_unset(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
|
||||
|
||||
/** \brief Loop macro iterating on bitmap \p bitmap
|
||||
*
|
||||
* The loop must start with hwloc_bitmap_foreach_begin() and end
|
||||
* with hwloc_bitmap_foreach_end() followed by a terminating ';'.
|
||||
*
|
||||
* \p index is the loop variable; it should be an unsigned int. The
|
||||
* first iteration will set \p index to the lowest index in the bitmap.
|
||||
* Successive iterations will iterate through, in order, all remaining
|
||||
* indexes set in the bitmap. To be specific: each iteration will return a
|
||||
* value for \p index such that hwloc_bitmap_isset(bitmap, index) is true.
|
||||
*
|
||||
* The assert prevents the loop from being infinite if the bitmap is infinitely set.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define hwloc_bitmap_foreach_begin(id, bitmap) \
|
||||
do { \
|
||||
assert(hwloc_bitmap_weight(bitmap) != -1); \
|
||||
for (id = hwloc_bitmap_first(bitmap); \
|
||||
(unsigned) id != (unsigned) -1; \
|
||||
id = hwloc_bitmap_next(bitmap, id)) {
|
||||
|
||||
/** \brief End of loop macro iterating on a bitmap.
|
||||
*
|
||||
* Needs a terminating ';'.
|
||||
*
|
||||
* \sa hwloc_bitmap_foreach_begin()
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define hwloc_bitmap_foreach_end() \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*
|
||||
* Combining bitmaps.
|
||||
*/
|
||||
|
||||
/** \brief Or bitmaps \p bitmap1 and \p bitmap2 and store the result in bitmap \p res
|
||||
*
|
||||
* \p res can be the same as \p bitmap1 or \p bitmap2
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_or (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);
|
||||
|
||||
/** \brief And bitmaps \p bitmap1 and \p bitmap2 and store the result in bitmap \p res
|
||||
*
|
||||
* \p res can be the same as \p bitmap1 or \p bitmap2
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_and (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);
|
||||
|
||||
/** \brief And bitmap \p bitmap1 and the negation of \p bitmap2 and store the result in bitmap \p res
|
||||
*
|
||||
* \p res can be the same as \p bitmap1 or \p bitmap2
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_andnot (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);
|
||||
|
||||
/** \brief Xor bitmaps \p bitmap1 and \p bitmap2 and store the result in bitmap \p res
|
||||
*
|
||||
* \p res can be the same as \p bitmap1 or \p bitmap2
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_xor (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);
|
||||
|
||||
/** \brief Negate bitmap \p bitmap and store the result in bitmap \p res
|
||||
*
|
||||
* \p res can be the same as \p bitmap
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_not (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap);
|
||||
|
||||
|
||||
/*
|
||||
* Comparing bitmaps.
|
||||
*/
|
||||
|
||||
/** \brief Test whether bitmaps \p bitmap1 and \p bitmap2 intersects.
|
||||
*
|
||||
* \return 1 if bitmaps intersect, 0 otherwise.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_intersects (hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
|
||||
|
||||
/** \brief Test whether bitmap \p sub_bitmap is part of bitmap \p super_bitmap.
|
||||
*
|
||||
* \return 1 if \p sub_bitmap is included in \p super_bitmap, 0 otherwise.
|
||||
*
|
||||
* \note The empty bitmap is considered included in any other bitmap.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_isincluded (hwloc_const_bitmap_t sub_bitmap, hwloc_const_bitmap_t super_bitmap) __hwloc_attribute_pure;
|
||||
|
||||
/** \brief Test whether bitmap \p bitmap1 is equal to bitmap \p bitmap2.
|
||||
*
|
||||
* \return 1 if bitmaps are equal, 0 otherwise.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_isequal (hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
|
||||
|
||||
/** \brief Compare bitmaps \p bitmap1 and \p bitmap2 using their lowest index.
|
||||
*
|
||||
* A bitmap is considered smaller if its least significant bit is smaller.
|
||||
* The empty bitmap is considered higher than anything (because its least significant bit does not exist).
|
||||
*
|
||||
* \return -1 if \p bitmap1 is considered smaller than \p bitmap2.
|
||||
* \return 1 if \p bitmap1 is considered larger than \p bitmap2.
|
||||
*
|
||||
* For instance comparing binary bitmaps 0011 and 0110 returns -1
|
||||
* (hence 0011 is considered smaller than 0110)
|
||||
* because least significant bit of 0011 (0001) is smaller than least significant bit of 0110 (0010).
|
||||
* Comparing 01001 and 00110 would also return -1 for the same reason.
|
||||
*
|
||||
* \return 0 if bitmaps are considered equal, even if they are not strictly equal.
|
||||
* They just need to have the same least significant bit.
|
||||
* For instance, comparing binary bitmaps 0010 and 0110 returns 0 because they have the same least significant bit.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_compare_first(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
|
||||
|
||||
/** \brief Compare bitmaps \p bitmap1 and \p bitmap2 in lexicographic order.
|
||||
*
|
||||
* Lexicographic comparison of bitmaps, starting for their highest indexes.
|
||||
* Compare last indexes first, then second, etc.
|
||||
* The empty bitmap is considered lower than anything.
|
||||
*
|
||||
* \return -1 if \p bitmap1 is considered smaller than \p bitmap2.
|
||||
* \return 1 if \p bitmap1 is considered larger than \p bitmap2.
|
||||
* \return 0 if bitmaps are equal (contrary to hwloc_bitmap_compare_first()).
|
||||
*
|
||||
* For instance comparing binary bitmaps 0011 and 0110 returns -1
|
||||
* (hence 0011 is considered smaller than 0110).
|
||||
* Comparing 00101 and 01010 returns -1 too.
|
||||
*
|
||||
* \note This is different from the non-existing hwloc_bitmap_compare_last()
|
||||
* which would only compare the highest index of each bitmap.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_compare(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_BITMAP_H */
|
||||
193
src/3rdparty/hwloc/include/hwloc/cpukinds.h
vendored
193
src/3rdparty/hwloc/include/hwloc/cpukinds.h
vendored
@@ -1,193 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2020-2021 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 greater intrinsic performance
|
||||
* (and possibly less performance/power efficiency).
|
||||
* Kinds with lower efficiency values are ranked first:
|
||||
* Passing 0 as \p kind_index to hwloc_cpukinds_get_info() will
|
||||
* return information about the CPU kind with lower performance
|
||||
* but higher energy-efficiency.
|
||||
* Higher \p kind_index values would rather return information
|
||||
* about power-hungry high-performance cores.
|
||||
*
|
||||
* When available, efficiency values are gathered from the operating system.
|
||||
* If so, \p cpukind_efficiency is set in the struct hwloc_topology_discovery_support array.
|
||||
* This is currently available on Windows 10, Mac OS X (Darwin),
|
||||
* and on some Linux platforms where core "capacity" is exposed in sysfs.
|
||||
*
|
||||
* If the operating system does not expose core efficiencies natively,
|
||||
* 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 */
|
||||
220
src/3rdparty/hwloc/include/hwloc/cuda.h
vendored
220
src/3rdparty/hwloc/include/hwloc/cuda.h
vendored
@@ -1,220 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2010-2021 Inria. All rights reserved.
|
||||
* Copyright © 2010-2011 Université Bordeaux
|
||||
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Macros to help interaction between hwloc and the CUDA Driver API.
|
||||
*
|
||||
* Applications that use both hwloc and the CUDA Driver API may want to
|
||||
* include this file so as to get topology information for CUDA devices.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_CUDA_H
|
||||
#define HWLOC_CUDA_H
|
||||
|
||||
#include "hwloc.h"
|
||||
#include "hwloc/autogen/config.h"
|
||||
#include "hwloc/helper.h"
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
#include "hwloc/linux.h"
|
||||
#endif
|
||||
|
||||
#include <cuda.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup hwlocality_cuda Interoperability with the CUDA Driver API
|
||||
*
|
||||
* This interface offers ways to retrieve topology information about
|
||||
* CUDA devices when using the CUDA Driver API.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Return the domain, bus and device IDs of the CUDA device \p cudevice.
|
||||
*
|
||||
* Device \p cudevice must match the local machine.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_cuda_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused,
|
||||
CUdevice cudevice, int *domain, int *bus, int *dev)
|
||||
{
|
||||
CUresult cres;
|
||||
|
||||
#if CUDA_VERSION >= 4000
|
||||
cres = cuDeviceGetAttribute(domain, CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, cudevice);
|
||||
if (cres != CUDA_SUCCESS) {
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
*domain = 0;
|
||||
#endif
|
||||
cres = cuDeviceGetAttribute(bus, CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, cudevice);
|
||||
if (cres != CUDA_SUCCESS) {
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
cres = cuDeviceGetAttribute(dev, CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID, cudevice);
|
||||
if (cres != CUDA_SUCCESS) {
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Get the CPU set of processors that are physically
|
||||
* close to device \p cudevice.
|
||||
*
|
||||
* Store in \p set the CPU-set describing the locality of the CUDA device \p cudevice.
|
||||
*
|
||||
* Topology \p topology and device \p cudevice must match the local machine.
|
||||
* I/O devices detection and the CUDA component are not needed in the topology.
|
||||
*
|
||||
* The function only returns the locality of the device.
|
||||
* If more information about the device is needed, OS objects should
|
||||
* be used instead, see hwloc_cuda_get_device_osdev()
|
||||
* and hwloc_cuda_get_device_osdev_by_index().
|
||||
*
|
||||
* This function is currently only implemented in a meaningful way for
|
||||
* Linux; other systems will simply get a full cpuset.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_cuda_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
|
||||
CUdevice cudevice, hwloc_cpuset_t set)
|
||||
{
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
|
||||
#define HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX 128
|
||||
char path[HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX];
|
||||
int domainid, busid, deviceid;
|
||||
|
||||
if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domainid, &busid, &deviceid))
|
||||
return -1;
|
||||
|
||||
if (!hwloc_topology_is_thissystem(topology)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", domainid, busid, deviceid);
|
||||
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|
||||
|| hwloc_bitmap_iszero(set))
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
#else
|
||||
/* Non-Linux systems simply get a full cpuset */
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Get the hwloc PCI device object corresponding to the
|
||||
* CUDA device \p cudevice.
|
||||
*
|
||||
* \return The hwloc PCI device object describing the CUDA device \p cudevice.
|
||||
* \return \c NULL if none could be found.
|
||||
*
|
||||
* Topology \p topology and device \p cudevice must match the local machine.
|
||||
* I/O devices detection must be enabled in topology \p topology.
|
||||
* The CUDA component is not needed in the topology.
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_cuda_get_device_pcidev(hwloc_topology_t topology, CUdevice cudevice)
|
||||
{
|
||||
int domain, bus, dev;
|
||||
|
||||
if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev))
|
||||
return NULL;
|
||||
|
||||
return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, 0);
|
||||
}
|
||||
|
||||
/** \brief Get the hwloc OS device object corresponding to CUDA device \p cudevice.
|
||||
*
|
||||
* \return The hwloc OS device object that describes the given CUDA device \p cudevice.
|
||||
* \return \c NULL if none could be found.
|
||||
*
|
||||
* Topology \p topology and device \p cudevice must match the local machine.
|
||||
* I/O devices detection and the CUDA component must be enabled in the topology.
|
||||
* If not, the locality of the object may still be found using
|
||||
* hwloc_cuda_get_device_cpuset().
|
||||
*
|
||||
* \note This function cannot work if PCI devices are filtered out.
|
||||
*
|
||||
* \note The corresponding hwloc PCI device may be found by looking
|
||||
* at the result parent pointer (unless PCI devices are filtered out).
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_cuda_get_device_osdev(hwloc_topology_t topology, CUdevice cudevice)
|
||||
{
|
||||
hwloc_obj_t osdev = NULL;
|
||||
int domain, bus, dev;
|
||||
|
||||
if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev))
|
||||
return NULL;
|
||||
|
||||
osdev = NULL;
|
||||
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
|
||||
hwloc_obj_t pcidev = osdev->parent;
|
||||
if (strncmp(osdev->name, "cuda", 4))
|
||||
continue;
|
||||
if (pcidev
|
||||
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
|
||||
&& (int) pcidev->attr->pcidev.domain == domain
|
||||
&& (int) pcidev->attr->pcidev.bus == bus
|
||||
&& (int) pcidev->attr->pcidev.dev == dev
|
||||
&& pcidev->attr->pcidev.func == 0)
|
||||
return osdev;
|
||||
/* if PCI are filtered out, we need a info attr to match on */
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** \brief Get the hwloc OS device object corresponding to the
|
||||
* CUDA device whose index is \p idx.
|
||||
*
|
||||
* \return The hwloc OS device object describing the CUDA device whose index is \p idx.
|
||||
* \return \c NULL if none could be found.
|
||||
*
|
||||
* The topology \p topology does not necessarily have to match the current
|
||||
* machine. For instance the topology may be an XML import of a remote host.
|
||||
* I/O devices detection and the CUDA component must be enabled in the topology.
|
||||
*
|
||||
* \note The corresponding PCI device object can be obtained by looking
|
||||
* at the OS device parent object (unless PCI devices are filtered out).
|
||||
*
|
||||
* \note This function is identical to hwloc_cudart_get_device_osdev_by_index().
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_cuda_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
|
||||
{
|
||||
hwloc_obj_t osdev = NULL;
|
||||
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
|
||||
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
|
||||
&& osdev->name
|
||||
&& !strncmp("cuda", osdev->name, 4)
|
||||
&& atoi(osdev->name + 4) == (int) idx)
|
||||
return osdev;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_CUDA_H */
|
||||
177
src/3rdparty/hwloc/include/hwloc/cudart.h
vendored
177
src/3rdparty/hwloc/include/hwloc/cudart.h
vendored
@@ -1,177 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2010-2021 Inria. All rights reserved.
|
||||
* Copyright © 2010-2011 Université Bordeaux
|
||||
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Macros to help interaction between hwloc and the CUDA Runtime API.
|
||||
*
|
||||
* Applications that use both hwloc and the CUDA Runtime API may want to
|
||||
* include this file so as to get topology information for CUDA devices.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_CUDART_H
|
||||
#define HWLOC_CUDART_H
|
||||
|
||||
#include "hwloc.h"
|
||||
#include "hwloc/autogen/config.h"
|
||||
#include "hwloc/helper.h"
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
#include "hwloc/linux.h"
|
||||
#endif
|
||||
|
||||
#include <cuda.h> /* for CUDA_VERSION */
|
||||
#include <cuda_runtime_api.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup hwlocality_cudart Interoperability with the CUDA Runtime API
|
||||
*
|
||||
* This interface offers ways to retrieve topology information about
|
||||
* CUDA devices when using the CUDA Runtime API.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Return the domain, bus and device IDs of the CUDA device whose index is \p idx.
|
||||
*
|
||||
* Device index \p idx must match the local machine.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_cudart_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused,
|
||||
int idx, int *domain, int *bus, int *dev)
|
||||
{
|
||||
cudaError_t cerr;
|
||||
struct cudaDeviceProp prop;
|
||||
|
||||
cerr = cudaGetDeviceProperties(&prop, idx);
|
||||
if (cerr) {
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if CUDA_VERSION >= 4000
|
||||
*domain = prop.pciDomainID;
|
||||
#else
|
||||
*domain = 0;
|
||||
#endif
|
||||
|
||||
*bus = prop.pciBusID;
|
||||
*dev = prop.pciDeviceID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Get the CPU set of processors that are physically
|
||||
* close to device \p idx.
|
||||
*
|
||||
* Store in \p set the CPU-set describing the locality of the CUDA device
|
||||
* whose index is \p idx.
|
||||
*
|
||||
* Topology \p topology and device \p idx must match the local machine.
|
||||
* I/O devices detection and the CUDA component are not needed in the topology.
|
||||
*
|
||||
* The function only returns the locality of the device.
|
||||
* If more information about the device is needed, OS objects should
|
||||
* be used instead, see hwloc_cudart_get_device_osdev_by_index().
|
||||
*
|
||||
* This function is currently only implemented in a meaningful way for
|
||||
* Linux; other systems will simply get a full cpuset.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_cudart_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
|
||||
int idx, hwloc_cpuset_t set)
|
||||
{
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
|
||||
#define HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX 128
|
||||
char path[HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX];
|
||||
int domain, bus, dev;
|
||||
|
||||
if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev))
|
||||
return -1;
|
||||
|
||||
if (!hwloc_topology_is_thissystem(topology)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", (unsigned) domain, (unsigned) bus, (unsigned) dev);
|
||||
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|
||||
|| hwloc_bitmap_iszero(set))
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
#else
|
||||
/* Non-Linux systems simply get a full cpuset */
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Get the hwloc PCI device object corresponding to the
|
||||
* CUDA device whose index is \p idx.
|
||||
*
|
||||
* \return The hwloc PCI device object describing the CUDA device whose index is \p idx.
|
||||
* \return \c NULL if none could be found.
|
||||
*
|
||||
* Topology \p topology and device \p idx must match the local machine.
|
||||
* I/O devices detection must be enabled in topology \p topology.
|
||||
* The CUDA component is not needed in the topology.
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_cudart_get_device_pcidev(hwloc_topology_t topology, int idx)
|
||||
{
|
||||
int domain, bus, dev;
|
||||
|
||||
if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev))
|
||||
return NULL;
|
||||
|
||||
return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, 0);
|
||||
}
|
||||
|
||||
/** \brief Get the hwloc OS device object corresponding to the
|
||||
* CUDA device whose index is \p idx.
|
||||
*
|
||||
* \return The hwloc OS device object describing the CUDA device whose index is \p idx.
|
||||
* \return \c NULL if none could be found.
|
||||
*
|
||||
* The topology \p topology does not necessarily have to match the current
|
||||
* machine. For instance the topology may be an XML import of a remote host.
|
||||
* I/O devices detection and the CUDA component must be enabled in the topology.
|
||||
* If not, the locality of the object may still be found using
|
||||
* hwloc_cudart_get_device_cpuset().
|
||||
*
|
||||
* \note The corresponding PCI device object can be obtained by looking
|
||||
* at the OS device parent object (unless PCI devices are filtered out).
|
||||
*
|
||||
* \note This function is identical to hwloc_cuda_get_device_osdev_by_index().
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_cudart_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
|
||||
{
|
||||
hwloc_obj_t osdev = NULL;
|
||||
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
|
||||
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
|
||||
&& osdev->name
|
||||
&& !strncmp("cuda", osdev->name, 4)
|
||||
&& atoi(osdev->name + 4) == (int) idx)
|
||||
return osdev;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_CUDART_H */
|
||||
217
src/3rdparty/hwloc/include/hwloc/deprecated.h
vendored
217
src/3rdparty/hwloc/include/hwloc/deprecated.h
vendored
@@ -1,217 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2021 Inria. All rights reserved.
|
||||
* Copyright © 2009-2012 Université Bordeaux
|
||||
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file contains the inline code of functions declared in hwloc.h
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_DEPRECATED_H
|
||||
#define HWLOC_DEPRECATED_H
|
||||
|
||||
#ifndef HWLOC_H
|
||||
#error Please include the main hwloc.h instead
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* backward compat with v2.0 before WHOLE_SYSTEM renaming */
|
||||
#define HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED
|
||||
/* backward compat with v1.11 before System removal */
|
||||
#define HWLOC_OBJ_SYSTEM HWLOC_OBJ_MACHINE
|
||||
/* backward compat with v1.10 before Socket->Package renaming */
|
||||
#define HWLOC_OBJ_SOCKET HWLOC_OBJ_PACKAGE
|
||||
/* backward compat with v1.10 before Node->NUMANode clarification */
|
||||
#define HWLOC_OBJ_NODE HWLOC_OBJ_NUMANODE
|
||||
|
||||
/** \brief Add a distances structure.
|
||||
*
|
||||
* Superseded by hwloc_distances_add_create()+hwloc_distances_add_values()+hwloc_distances_add_commit()
|
||||
* in v2.5.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_distances_add(hwloc_topology_t topology,
|
||||
unsigned nbobjs, hwloc_obj_t *objs, hwloc_uint64_t *values,
|
||||
unsigned long kind, unsigned long flags) __hwloc_attribute_deprecated;
|
||||
|
||||
/** \brief Insert a misc object by parent.
|
||||
*
|
||||
* Identical to hwloc_topology_insert_misc_object().
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_topology_insert_misc_object_by_parent(hwloc_topology_t topology, hwloc_obj_t parent, const char *name) __hwloc_attribute_deprecated;
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_topology_insert_misc_object_by_parent(hwloc_topology_t topology, hwloc_obj_t parent, const char *name)
|
||||
{
|
||||
return hwloc_topology_insert_misc_object(topology, parent, name);
|
||||
}
|
||||
|
||||
/** \brief Stringify the cpuset containing a set of objects.
|
||||
*
|
||||
* If \p size is 0, \p string may safely be \c NULL.
|
||||
*
|
||||
* \return the number of character that were actually written if not truncating,
|
||||
* or that would have been written (not including the ending \\0).
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_obj_cpuset_snprintf(char *str, size_t size, size_t nobj, struct hwloc_obj * const *objs) __hwloc_attribute_deprecated;
|
||||
static __hwloc_inline int
|
||||
hwloc_obj_cpuset_snprintf(char *str, size_t size, size_t nobj, struct hwloc_obj * const *objs)
|
||||
{
|
||||
hwloc_bitmap_t set = hwloc_bitmap_alloc();
|
||||
int res;
|
||||
unsigned i;
|
||||
|
||||
hwloc_bitmap_zero(set);
|
||||
for(i=0; i<nobj; i++)
|
||||
if (objs[i]->cpuset)
|
||||
hwloc_bitmap_or(set, set, objs[i]->cpuset);
|
||||
|
||||
res = hwloc_bitmap_snprintf(str, size, set);
|
||||
hwloc_bitmap_free(set);
|
||||
return res;
|
||||
}
|
||||
|
||||
/** \brief Convert a type string into a type and some attributes.
|
||||
*
|
||||
* Deprecated by hwloc_type_sscanf()
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_obj_type_sscanf(const char *string, hwloc_obj_type_t *typep, int *depthattrp, void *typeattrp, size_t typeattrsize) __hwloc_attribute_deprecated;
|
||||
static __hwloc_inline int
|
||||
hwloc_obj_type_sscanf(const char *string, hwloc_obj_type_t *typep, int *depthattrp, void *typeattrp, size_t typeattrsize)
|
||||
{
|
||||
union hwloc_obj_attr_u attr;
|
||||
int err = hwloc_type_sscanf(string, typep, &attr, sizeof(attr));
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (hwloc_obj_type_is_cache(*typep)) {
|
||||
if (depthattrp)
|
||||
*depthattrp = (int) attr.cache.depth;
|
||||
if (typeattrp && typeattrsize >= sizeof(hwloc_obj_cache_type_t))
|
||||
memcpy(typeattrp, &attr.cache.type, sizeof(hwloc_obj_cache_type_t));
|
||||
} else if (*typep == HWLOC_OBJ_GROUP) {
|
||||
if (depthattrp)
|
||||
*depthattrp = (int) attr.group.depth;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set the default memory binding policy of the current
|
||||
* process or thread to prefer the NUMA node(s) specified by physical \p nodeset
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_set_membind_nodeset(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_deprecated;
|
||||
static __hwloc_inline int
|
||||
hwloc_set_membind_nodeset(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
|
||||
{
|
||||
return hwloc_set_membind(topology, nodeset, policy, flags | HWLOC_MEMBIND_BYNODESET);
|
||||
}
|
||||
|
||||
/** \brief Query the default memory binding policy and physical locality of the
|
||||
* current process or thread.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_get_membind_nodeset(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags) __hwloc_attribute_deprecated;
|
||||
static __hwloc_inline int
|
||||
hwloc_get_membind_nodeset(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
|
||||
{
|
||||
return hwloc_get_membind(topology, nodeset, policy, flags | HWLOC_MEMBIND_BYNODESET);
|
||||
}
|
||||
|
||||
/** \brief Set the default memory binding policy of the specified
|
||||
* process to prefer the NUMA node(s) specified by physical \p nodeset
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_set_proc_membind_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_deprecated;
|
||||
static __hwloc_inline int
|
||||
hwloc_set_proc_membind_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
|
||||
{
|
||||
return hwloc_set_proc_membind(topology, pid, nodeset, policy, flags | HWLOC_MEMBIND_BYNODESET);
|
||||
}
|
||||
|
||||
/** \brief Query the default memory binding policy and physical locality of the
|
||||
* specified process.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_get_proc_membind_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags) __hwloc_attribute_deprecated;
|
||||
static __hwloc_inline int
|
||||
hwloc_get_proc_membind_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
|
||||
{
|
||||
return hwloc_get_proc_membind(topology, pid, nodeset, policy, flags | HWLOC_MEMBIND_BYNODESET);
|
||||
}
|
||||
|
||||
/** \brief Bind the already-allocated memory identified by (addr, len)
|
||||
* to the NUMA node(s) in physical \p nodeset.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_set_area_membind_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_deprecated;
|
||||
static __hwloc_inline int
|
||||
hwloc_set_area_membind_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
|
||||
{
|
||||
return hwloc_set_area_membind(topology, addr, len, nodeset, policy, flags | HWLOC_MEMBIND_BYNODESET);
|
||||
}
|
||||
|
||||
/** \brief Query the physical NUMA node(s) and binding policy of the memory
|
||||
* identified by (\p addr, \p len ).
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_get_area_membind_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags) __hwloc_attribute_deprecated;
|
||||
static __hwloc_inline int
|
||||
hwloc_get_area_membind_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
|
||||
{
|
||||
return hwloc_get_area_membind(topology, addr, len, nodeset, policy, flags | HWLOC_MEMBIND_BYNODESET);
|
||||
}
|
||||
|
||||
/** \brief Allocate some memory on the given physical nodeset \p nodeset
|
||||
*/
|
||||
static __hwloc_inline void *
|
||||
hwloc_alloc_membind_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_malloc __hwloc_attribute_deprecated;
|
||||
static __hwloc_inline void *
|
||||
hwloc_alloc_membind_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
|
||||
{
|
||||
return hwloc_alloc_membind(topology, len, nodeset, policy, flags | HWLOC_MEMBIND_BYNODESET);
|
||||
}
|
||||
|
||||
/** \brief Allocate some memory on the given nodeset \p nodeset.
|
||||
*/
|
||||
static __hwloc_inline void *
|
||||
hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_malloc __hwloc_attribute_deprecated;
|
||||
static __hwloc_inline void *
|
||||
hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
|
||||
{
|
||||
return hwloc_alloc_membind_policy(topology, len, nodeset, policy, flags | HWLOC_MEMBIND_BYNODESET);
|
||||
}
|
||||
|
||||
/** \brief Convert a CPU set into a NUMA node set and handle non-NUMA cases
|
||||
*/
|
||||
static __hwloc_inline void
|
||||
hwloc_cpuset_to_nodeset_strict(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset) __hwloc_attribute_deprecated;
|
||||
static __hwloc_inline void
|
||||
hwloc_cpuset_to_nodeset_strict(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset)
|
||||
{
|
||||
hwloc_cpuset_to_nodeset(topology, _cpuset, nodeset);
|
||||
}
|
||||
|
||||
/** \brief Convert a NUMA node set into a CPU set and handle non-NUMA cases
|
||||
*/
|
||||
static __hwloc_inline void
|
||||
hwloc_cpuset_from_nodeset_strict(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset) __hwloc_attribute_deprecated;
|
||||
static __hwloc_inline void
|
||||
hwloc_cpuset_from_nodeset_strict(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset)
|
||||
{
|
||||
hwloc_cpuset_from_nodeset(topology, _cpuset, nodeset);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_DEPRECATED_H */
|
||||
289
src/3rdparty/hwloc/include/hwloc/diff.h
vendored
289
src/3rdparty/hwloc/include/hwloc/diff.h
vendored
@@ -1,289 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013-2020 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Topology differences.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_DIFF_H
|
||||
#define HWLOC_DIFF_H
|
||||
|
||||
#ifndef HWLOC_H
|
||||
#error Please include the main hwloc.h instead
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#elif 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup hwlocality_diff Topology differences
|
||||
*
|
||||
* Applications that manipulate many similar topologies, for instance
|
||||
* one for each node of a homogeneous cluster, may want to compress
|
||||
* topologies to reduce the memory footprint.
|
||||
*
|
||||
* This file offers a way to manipulate the difference between topologies
|
||||
* and export/import it to/from XML.
|
||||
* Compression may therefore be achieved by storing one topology
|
||||
* entirely while the others are only described by their differences
|
||||
* with the former.
|
||||
* The actual topology can be reconstructed when actually needed by
|
||||
* applying the precomputed difference to the reference topology.
|
||||
*
|
||||
* This interface targets very similar nodes.
|
||||
* Only very simple differences between topologies are actually
|
||||
* supported, for instance a change in the memory size, the name
|
||||
* of the object, or some info attribute.
|
||||
* More complex differences such as adding or removing objects cannot
|
||||
* be represented in the difference structures and therefore return
|
||||
* errors.
|
||||
* Differences between object sets or topology-wide allowed sets,
|
||||
* cannot be represented either.
|
||||
*
|
||||
* It means that there is no need to apply the difference when
|
||||
* looking at the tree organization (how many levels, how many
|
||||
* objects per level, what kind of objects, CPU and node sets, etc)
|
||||
* and when binding to objects.
|
||||
* However the difference must be applied when looking at object
|
||||
* attributes such as the name, the memory size or info attributes.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** \brief Type of one object attribute difference.
|
||||
*/
|
||||
typedef enum hwloc_topology_diff_obj_attr_type_e {
|
||||
/** \brief The object local memory is modified.
|
||||
* The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_uint64_s
|
||||
* (and the index field is ignored).
|
||||
*/
|
||||
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE,
|
||||
|
||||
/** \brief The object name is modified.
|
||||
* The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_string_s
|
||||
* (and the name field is ignored).
|
||||
*/
|
||||
|
||||
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME,
|
||||
/** \brief the value of an info attribute is modified.
|
||||
* The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_string_s.
|
||||
*/
|
||||
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO
|
||||
} hwloc_topology_diff_obj_attr_type_t;
|
||||
|
||||
/** \brief One object attribute difference.
|
||||
*/
|
||||
union hwloc_topology_diff_obj_attr_u {
|
||||
struct hwloc_topology_diff_obj_attr_generic_s {
|
||||
/* each part of the union must start with these */
|
||||
hwloc_topology_diff_obj_attr_type_t type;
|
||||
} generic;
|
||||
|
||||
/** \brief Integer attribute modification with an optional index. */
|
||||
struct hwloc_topology_diff_obj_attr_uint64_s {
|
||||
/* used for storing integer attributes */
|
||||
hwloc_topology_diff_obj_attr_type_t type;
|
||||
hwloc_uint64_t index; /* not used for SIZE */
|
||||
hwloc_uint64_t oldvalue;
|
||||
hwloc_uint64_t newvalue;
|
||||
} uint64;
|
||||
|
||||
/** \brief String attribute modification with an optional name */
|
||||
struct hwloc_topology_diff_obj_attr_string_s {
|
||||
/* used for storing name and info pairs */
|
||||
hwloc_topology_diff_obj_attr_type_t type;
|
||||
char *name; /* not used for NAME */
|
||||
char *oldvalue;
|
||||
char *newvalue;
|
||||
} string;
|
||||
};
|
||||
|
||||
|
||||
/** \brief Type of one element of a difference list.
|
||||
*/
|
||||
typedef enum hwloc_topology_diff_type_e {
|
||||
/** \brief An object attribute was changed.
|
||||
* The union is a hwloc_topology_diff_u::hwloc_topology_diff_obj_attr_s.
|
||||
*/
|
||||
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR,
|
||||
|
||||
/** \brief The difference is too complex,
|
||||
* it cannot be represented. The difference below
|
||||
* this object has not been checked.
|
||||
* hwloc_topology_diff_build() will return 1.
|
||||
*
|
||||
* The union is a hwloc_topology_diff_u::hwloc_topology_diff_too_complex_s.
|
||||
*/
|
||||
HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX
|
||||
} hwloc_topology_diff_type_t;
|
||||
|
||||
/** \brief One element of a difference list between two topologies.
|
||||
*/
|
||||
typedef union hwloc_topology_diff_u {
|
||||
struct hwloc_topology_diff_generic_s {
|
||||
/* each part of the union must start with these */
|
||||
hwloc_topology_diff_type_t type;
|
||||
union hwloc_topology_diff_u * next; /* pointer to the next element of the list, or NULL */
|
||||
} generic;
|
||||
|
||||
/* A difference in an object attribute. */
|
||||
struct hwloc_topology_diff_obj_attr_s {
|
||||
hwloc_topology_diff_type_t type; /* must be ::HWLOC_TOPOLOGY_DIFF_OBJ_ATTR */
|
||||
union hwloc_topology_diff_u * next;
|
||||
/* List of attribute differences for a single object */
|
||||
int obj_depth;
|
||||
unsigned obj_index;
|
||||
union hwloc_topology_diff_obj_attr_u diff;
|
||||
} obj_attr;
|
||||
|
||||
/* A difference that is too complex. */
|
||||
struct hwloc_topology_diff_too_complex_s {
|
||||
hwloc_topology_diff_type_t type; /* must be ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX */
|
||||
union hwloc_topology_diff_u * next;
|
||||
/* Where we had to stop computing the diff in the first topology */
|
||||
int obj_depth;
|
||||
unsigned obj_index;
|
||||
} too_complex;
|
||||
} * hwloc_topology_diff_t;
|
||||
|
||||
|
||||
/** \brief Compute the difference between 2 topologies.
|
||||
*
|
||||
* The difference is stored as a list of ::hwloc_topology_diff_t entries
|
||||
* starting at \p diff.
|
||||
* It is computed by doing a depth-first traversal of both topology trees
|
||||
* simultaneously.
|
||||
*
|
||||
* If the difference between 2 objects is too complex to be represented
|
||||
* (for instance if some objects have different types, or different numbers
|
||||
* of children), a special diff entry of type ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX
|
||||
* is queued.
|
||||
* The computation of the diff does not continue below these objects.
|
||||
* So each such diff entry means that the difference between two subtrees
|
||||
* could not be computed.
|
||||
*
|
||||
* \return 0 if the difference can be represented properly.
|
||||
*
|
||||
* \return 0 with \p diff pointing to NULL if there is no difference
|
||||
* between the topologies.
|
||||
*
|
||||
* \return 1 if the difference is too complex (see above). Some entries in
|
||||
* the list will be of type ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX.
|
||||
*
|
||||
* \return -1 on any other error.
|
||||
*
|
||||
* \note \p flags is currently not used. It should be 0.
|
||||
*
|
||||
* \note The output diff has to be freed with hwloc_topology_diff_destroy().
|
||||
*
|
||||
* \note The output diff can only be exported to XML or passed to
|
||||
* hwloc_topology_diff_apply() if 0 was returned, i.e. if no entry of type
|
||||
* ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX is listed.
|
||||
*
|
||||
* \note The output diff may be modified by removing some entries from
|
||||
* the list. The removed entries should be freed by passing them to
|
||||
* to hwloc_topology_diff_destroy() (possible as another list).
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_topology_diff_build(hwloc_topology_t topology, hwloc_topology_t newtopology, unsigned long flags, hwloc_topology_diff_t *diff);
|
||||
|
||||
/** \brief Flags to be given to hwloc_topology_diff_apply().
|
||||
*/
|
||||
enum hwloc_topology_diff_apply_flags_e {
|
||||
/** \brief Apply topology diff in reverse direction.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE = (1UL<<0)
|
||||
};
|
||||
|
||||
/** \brief Apply a topology diff to an existing topology.
|
||||
*
|
||||
* \p flags is an OR'ed set of ::hwloc_topology_diff_apply_flags_e.
|
||||
*
|
||||
* The new topology is modified in place. hwloc_topology_dup()
|
||||
* may be used to duplicate it before patching.
|
||||
*
|
||||
* If the difference cannot be applied entirely, all previous applied
|
||||
* elements are unapplied before returning.
|
||||
*
|
||||
* \return 0 on success.
|
||||
*
|
||||
* \return -N if applying the difference failed while trying
|
||||
* to apply the N-th part of the difference. For instance -1
|
||||
* is returned if the very first difference element could not
|
||||
* be applied.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_topology_diff_apply(hwloc_topology_t topology, hwloc_topology_diff_t diff, unsigned long flags);
|
||||
|
||||
/** \brief Destroy a list of topology differences.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_topology_diff_destroy(hwloc_topology_diff_t diff);
|
||||
|
||||
/** \brief Load a list of topology differences from a XML file.
|
||||
*
|
||||
* If not \c NULL, \p refname will be filled with the identifier
|
||||
* string of the reference topology for the difference file,
|
||||
* if any was specified in the XML file.
|
||||
* This identifier is usually the name of the other XML file
|
||||
* that contains the reference topology.
|
||||
*
|
||||
* \note the pointer returned in refname should later be freed
|
||||
* by the caller.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_topology_diff_load_xml(const char *xmlpath, hwloc_topology_diff_t *diff, char **refname);
|
||||
|
||||
/** \brief Export a list of topology differences to a XML file.
|
||||
*
|
||||
* If not \c NULL, \p refname defines an identifier string
|
||||
* for the reference topology which was used as a base when
|
||||
* computing this difference.
|
||||
* This identifier is usually the name of the other XML file
|
||||
* that contains the reference topology.
|
||||
* This attribute is given back when reading the diff from XML.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_topology_diff_export_xml(hwloc_topology_diff_t diff, const char *refname, const char *xmlpath);
|
||||
|
||||
/** \brief Load a list of topology differences from a XML buffer.
|
||||
*
|
||||
* If not \c NULL, \p refname will be filled with the identifier
|
||||
* string of the reference topology for the difference file,
|
||||
* if any was specified in the XML file.
|
||||
* This identifier is usually the name of the other XML file
|
||||
* that contains the reference topology.
|
||||
*
|
||||
* \note the pointer returned in refname should later be freed
|
||||
* by the caller.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_topology_diff_load_xmlbuffer(const char *xmlbuffer, int buflen, hwloc_topology_diff_t *diff, char **refname);
|
||||
|
||||
/** \brief Export a list of topology differences to a XML buffer.
|
||||
*
|
||||
* If not \c NULL, \p refname defines an identifier string
|
||||
* for the reference topology which was used as a base when
|
||||
* computing this difference.
|
||||
* This identifier is usually the name of the other XML file
|
||||
* that contains the reference topology.
|
||||
* This attribute is given back when reading the diff from XML.
|
||||
*
|
||||
* The returned buffer ends with a \0 that is included in the returned
|
||||
* length.
|
||||
*
|
||||
* \note The XML buffer should later be freed with hwloc_free_xmlbuffer().
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_topology_diff_export_xmlbuffer(hwloc_topology_diff_t diff, const char *refname, char **xmlbuffer, int *buflen);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_DIFF_H */
|
||||
471
src/3rdparty/hwloc/include/hwloc/distances.h
vendored
471
src/3rdparty/hwloc/include/hwloc/distances.h
vendored
@@ -1,471 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2010-2021 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Object distances.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_DISTANCES_H
|
||||
#define HWLOC_DISTANCES_H
|
||||
|
||||
#ifndef HWLOC_H
|
||||
#error Please include the main hwloc.h instead
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#elif 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup hwlocality_distances_get Retrieve distances between objects
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Matrix of distances between a set of objects.
|
||||
*
|
||||
* This matrix often contains latencies between NUMA nodes
|
||||
* (as reported in the System Locality Distance Information Table (SLIT)
|
||||
* in the ACPI specification), which may or may not be physically accurate.
|
||||
* 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".
|
||||
* Others distance structures include and "XGMIBandwidth", "XGMIHops"
|
||||
* and "NVLinkBandwidth".
|
||||
*
|
||||
* The matrix may also contain bandwidths between random sets of objects,
|
||||
* possibly provided by the user, as specified in the \p kind attribute.
|
||||
*
|
||||
* Pointers \p objs and \p values should not be replaced, reallocated, freed, etc.
|
||||
* However callers are allowed to modify \p kind as well as the contents
|
||||
* of \p objs and \p values arrays.
|
||||
* For instance, if there is a single NUMA node per Package,
|
||||
* hwloc_get_obj_with_same_locality() may be used to convert between them
|
||||
* and replace NUMA nodes in the \p objs array with the corresponding Packages.
|
||||
* See also hwloc_distances_transform() for applying some transformations
|
||||
* to the structure.
|
||||
*/
|
||||
struct hwloc_distances_s {
|
||||
unsigned nbobjs; /**< \brief Number of objects described by the distance matrix. */
|
||||
hwloc_obj_t *objs; /**< \brief Array of objects described by the distance matrix.
|
||||
* These objects are not in any particular order,
|
||||
* see hwloc_distances_obj_index() and hwloc_distances_obj_pair_values()
|
||||
* for easy ways to find objects in this array and their corresponding values.
|
||||
*/
|
||||
unsigned long kind; /**< \brief OR'ed set of ::hwloc_distances_kind_e. */
|
||||
hwloc_uint64_t *values; /**< \brief Matrix of distances between objects, stored as a one-dimension array.
|
||||
*
|
||||
* Distance from i-th to j-th object is stored in slot i*nbobjs+j.
|
||||
* The meaning of the value depends on the \p kind attribute.
|
||||
*/
|
||||
};
|
||||
|
||||
/** \brief Kinds of distance matrices.
|
||||
*
|
||||
* The \p kind attribute of struct hwloc_distances_s is a OR'ed set
|
||||
* of kinds.
|
||||
*
|
||||
* A kind of format HWLOC_DISTANCES_KIND_FROM_* specifies where the
|
||||
* distance information comes from, if known.
|
||||
*
|
||||
* A kind of format HWLOC_DISTANCES_KIND_MEANS_* specifies whether
|
||||
* values are latencies or bandwidths, if applicable.
|
||||
*/
|
||||
enum hwloc_distances_kind_e {
|
||||
/** \brief These distances were obtained from the operating system or hardware.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_DISTANCES_KIND_FROM_OS = (1UL<<0),
|
||||
/** \brief These distances were provided by the user.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_DISTANCES_KIND_FROM_USER = (1UL<<1),
|
||||
|
||||
/** \brief Distance values are similar to latencies between objects.
|
||||
* Values are smaller for closer objects, hence minimal on the diagonal
|
||||
* of the matrix (distance between an object and itself).
|
||||
* It could also be the number of network hops between objects, etc.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_DISTANCES_KIND_MEANS_LATENCY = (1UL<<2),
|
||||
/** \brief Distance values are similar to bandwidths between objects.
|
||||
* Values are higher for closer objects, hence maximal on the diagonal
|
||||
* of the matrix (distance between an object and itself).
|
||||
* Such values are currently ignored for distance-based grouping.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_DISTANCES_KIND_MEANS_BANDWIDTH = (1UL<<3),
|
||||
|
||||
/** \brief This distances structure covers objects of different types.
|
||||
* This may apply to the "NVLinkBandwidth" structure in presence
|
||||
* of a NVSwitch or POWER processor NVLink port.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_DISTANCES_KIND_HETEROGENEOUS_TYPES = (1UL<<4)
|
||||
};
|
||||
|
||||
/** \brief Retrieve distance matrices.
|
||||
*
|
||||
* Retrieve distance matrices from the topology into the \p distances array.
|
||||
*
|
||||
* \p flags is currently unused, should be \c 0.
|
||||
*
|
||||
* \p kind serves as a filter. If \c 0, all distance matrices are returned.
|
||||
* If it contains some HWLOC_DISTANCES_KIND_FROM_*, only distance matrices
|
||||
* whose kind matches one of these are returned.
|
||||
* If it contains some HWLOC_DISTANCES_KIND_MEANS_*, only distance matrices
|
||||
* whose kind matches one of these are returned.
|
||||
*
|
||||
* On input, \p nr points to the number of distance matrices that may be stored
|
||||
* in \p distances.
|
||||
* On output, \p nr points to the number of distance matrices that were actually
|
||||
* found, even if some of them couldn't be stored in \p distances.
|
||||
* Distance matrices 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.
|
||||
*
|
||||
* Each distance matrix returned in the \p distances array should be released
|
||||
* by the caller using hwloc_distances_release().
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_distances_get(hwloc_topology_t topology,
|
||||
unsigned *nr, struct hwloc_distances_s **distances,
|
||||
unsigned long kind, unsigned long flags);
|
||||
|
||||
/** \brief Retrieve distance matrices for object at a specific depth in the topology.
|
||||
*
|
||||
* Identical to hwloc_distances_get() with the additional \p depth filter.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_distances_get_by_depth(hwloc_topology_t topology, int depth,
|
||||
unsigned *nr, struct hwloc_distances_s **distances,
|
||||
unsigned long kind, unsigned long flags);
|
||||
|
||||
/** \brief Retrieve distance matrices for object of a specific type.
|
||||
*
|
||||
* Identical to hwloc_distances_get() with the additional \p type filter.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_distances_get_by_type(hwloc_topology_t topology, hwloc_obj_type_t type,
|
||||
unsigned *nr, struct hwloc_distances_s **distances,
|
||||
unsigned long kind, unsigned long flags);
|
||||
|
||||
/** \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".
|
||||
* Others include "XGMIBandwidth", "XGMIHops" and "NVLinkBandwidth".
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_distances_get_by_name(hwloc_topology_t topology, const char *name,
|
||||
unsigned *nr, struct hwloc_distances_s **distances,
|
||||
unsigned long flags);
|
||||
|
||||
/** \brief Get a description of what a distances structure contains.
|
||||
*
|
||||
* For instance "NUMALatency" for hardware-provided NUMA distances (ACPI SLIT),
|
||||
* or NULL if unknown.
|
||||
*/
|
||||
HWLOC_DECLSPEC const char *
|
||||
hwloc_distances_get_name(hwloc_topology_t topology, struct hwloc_distances_s *distances);
|
||||
|
||||
/** \brief Release a distance matrix structure previously returned by hwloc_distances_get().
|
||||
*
|
||||
* \note This function is not required if the structure is removed with hwloc_distances_release_remove().
|
||||
*/
|
||||
HWLOC_DECLSPEC void
|
||||
hwloc_distances_release(hwloc_topology_t topology, struct hwloc_distances_s *distances);
|
||||
|
||||
/** \brief Transformations of distances structures. */
|
||||
enum hwloc_distances_transform_e {
|
||||
/** \brief Remove \c NULL objects from the distances structure.
|
||||
*
|
||||
* Every object that was replaced with \c NULL in the \p objs array
|
||||
* is removed and the \p values array is updated accordingly.
|
||||
*
|
||||
* At least \c 2 objects must remain, otherwise hwloc_distances_transform()
|
||||
* will return \c -1 with \p errno set to \c EINVAL.
|
||||
*
|
||||
* \p kind will be updated with or without ::HWLOC_DISTANCES_KIND_HETEROGENEOUS_TYPES
|
||||
* according to the remaining objects.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_DISTANCES_TRANSFORM_REMOVE_NULL = 0,
|
||||
|
||||
/** \brief Replace bandwidth values with a number of links.
|
||||
*
|
||||
* Usually all values will be either \c 0 (no link) or \c 1 (one link).
|
||||
* However some matrices could get larger values if some pairs of
|
||||
* peers are connected by different numbers of links.
|
||||
*
|
||||
* Values on the diagonal are set to \c 0.
|
||||
*
|
||||
* This transformation only applies to bandwidth matrices.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_DISTANCES_TRANSFORM_LINKS = 1,
|
||||
|
||||
/** \brief Merge switches with multiple ports into a single object.
|
||||
* This currently only applies to NVSwitches where GPUs seem connected to different
|
||||
* separate switch ports in the NVLinkBandwidth matrix. This transformation will
|
||||
* replace all of them with the same port connected to all GPUs.
|
||||
* Other ports are removed by applying ::HWLOC_DISTANCES_TRANSFORM_REMOVE_NULL internally.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_DISTANCES_TRANSFORM_MERGE_SWITCH_PORTS = 2,
|
||||
|
||||
/** \brief Apply a transitive closure to the matrix to connect objects across switches.
|
||||
* This currently only applies to GPUs and NVSwitches in the NVLinkBandwidth matrix.
|
||||
* All pairs of GPUs will be reported as directly connected.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_DISTANCES_TRANSFORM_TRANSITIVE_CLOSURE = 3
|
||||
};
|
||||
|
||||
/** \brief Apply a transformation to a distances structure.
|
||||
*
|
||||
* Modify a distances structure that was previously obtained with
|
||||
* hwloc_distances_get() or one of its variants.
|
||||
*
|
||||
* This modifies the local copy of the distances structures but does
|
||||
* not modify the distances information stored inside the topology
|
||||
* (retrieved by another call to hwloc_distances_get() or exported to XML).
|
||||
* To do so, one should add a new distances structure with same
|
||||
* name, kind, objects and values (see \ref hwlocality_distances_add)
|
||||
* and then remove this old one with hwloc_distances_release_remove().
|
||||
*
|
||||
* \p transform must be one of the transformations listed
|
||||
* in ::hwloc_distances_transform_e.
|
||||
*
|
||||
* These transformations may modify the contents of the \p objs or \p values arrays.
|
||||
*
|
||||
* \p transform_attr must be \c NULL for now.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* \note Objects in distances array \p objs may be directly modified
|
||||
* in place without using hwloc_distances_transform().
|
||||
* One may use hwloc_get_obj_with_same_locality() to easily convert
|
||||
* between similar objects of different types.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_distances_transform(hwloc_topology_t topology, struct hwloc_distances_s *distances,
|
||||
enum hwloc_distances_transform_e transform,
|
||||
void *transform_attr,
|
||||
unsigned long flags);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
/** \defgroup hwlocality_distances_consult Helpers for consulting distance matrices
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Find the index of an object in a distances structure.
|
||||
*
|
||||
* \return -1 if object \p obj is not involved in structure \p distances.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_distances_obj_index(struct hwloc_distances_s *distances, hwloc_obj_t obj)
|
||||
{
|
||||
unsigned i;
|
||||
for(i=0; i<distances->nbobjs; i++)
|
||||
if (distances->objs[i] == obj)
|
||||
return (int)i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** \brief Find the values between two objects in a distance matrices.
|
||||
*
|
||||
* The distance from \p obj1 to \p obj2 is stored in the value pointed by
|
||||
* \p value1to2 and reciprocally.
|
||||
*
|
||||
* \return -1 if object \p obj1 or \p obj2 is not involved in structure \p distances.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_distances_obj_pair_values(struct hwloc_distances_s *distances,
|
||||
hwloc_obj_t obj1, hwloc_obj_t obj2,
|
||||
hwloc_uint64_t *value1to2, hwloc_uint64_t *value2to1)
|
||||
{
|
||||
int i1 = hwloc_distances_obj_index(distances, obj1);
|
||||
int i2 = hwloc_distances_obj_index(distances, obj2);
|
||||
if (i1 < 0 || i2 < 0)
|
||||
return -1;
|
||||
*value1to2 = distances->values[i1 * distances->nbobjs + i2];
|
||||
*value2to1 = distances->values[i2 * distances->nbobjs + i1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
/** \defgroup hwlocality_distances_add Add distances between objects
|
||||
*
|
||||
* The usual way to add distances is:
|
||||
* \code
|
||||
* hwloc_distances_add_handle_t handle;
|
||||
* int err = -1;
|
||||
* handle = hwloc_distances_add_create(topology, "name", kind, 0);
|
||||
* if (handle) {
|
||||
* err = hwloc_distances_add_values(topology, handle, nbobjs, objs, values, 0);
|
||||
* if (!err)
|
||||
* err = hwloc_distances_add_commit(topology, handle, flags);
|
||||
* }
|
||||
* \endcode
|
||||
* If \p err is \c 0 at the end, then addition was successful.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Handle to a new distances structure during its addition to the topology. */
|
||||
typedef void * hwloc_distances_add_handle_t;
|
||||
|
||||
/** \brief Create a new empty distances structure.
|
||||
*
|
||||
* Create an empty distances structure
|
||||
* to be filled with hwloc_distances_add_values()
|
||||
* and then committed with hwloc_distances_add_commit().
|
||||
*
|
||||
* Parameter \p name is optional, it may be \c NULL.
|
||||
* Otherwise, it will be copied internally and may later be freed by the caller.
|
||||
*
|
||||
* \p kind specifies the kind of distance as a OR'ed set of ::hwloc_distances_kind_e.
|
||||
* Kind ::HWLOC_DISTANCES_KIND_HETEROGENEOUS_TYPES will be automatically set
|
||||
* according to objects having different types in hwloc_distances_add_values().
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* \return A hwloc_distances_add_handle_t that should then be passed
|
||||
* to hwloc_distances_add_values() and hwloc_distances_add_commit().
|
||||
*
|
||||
* \return \c NULL on error.
|
||||
*/
|
||||
HWLOC_DECLSPEC hwloc_distances_add_handle_t
|
||||
hwloc_distances_add_create(hwloc_topology_t topology,
|
||||
const char *name, unsigned long kind,
|
||||
unsigned long flags);
|
||||
|
||||
/** \brief Specify the objects and values in a new empty distances structure.
|
||||
*
|
||||
* Specify the objects and values for a new distances structure
|
||||
* that was returned as a handle by hwloc_distances_add_create().
|
||||
* The structure must then be committed with hwloc_distances_add_commit().
|
||||
*
|
||||
* The number of objects is \p nbobjs and the array of objects is \p objs.
|
||||
* Distance values are stored as a one-dimension array in \p values.
|
||||
* The distance from object i to object j is in slot i*nbobjs+j.
|
||||
*
|
||||
* \p nbobjs must be at least 2.
|
||||
*
|
||||
* Arrays \p objs and \p values will be copied internally,
|
||||
* they may later be freed by the caller.
|
||||
*
|
||||
* On error, the temporary distances structure and its content are destroyed.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c -1 on error.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_distances_add_values(hwloc_topology_t topology,
|
||||
hwloc_distances_add_handle_t handle,
|
||||
unsigned nbobjs, hwloc_obj_t *objs,
|
||||
hwloc_uint64_t *values,
|
||||
unsigned long flags);
|
||||
|
||||
/** \brief Flags for adding a new distances to a topology. */
|
||||
enum hwloc_distances_add_flag_e {
|
||||
/** \brief Try to group objects based on the newly provided distance information.
|
||||
* This is ignored for distances between objects of different types.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_DISTANCES_ADD_FLAG_GROUP = (1UL<<0),
|
||||
/** \brief If grouping, consider the distance values as inaccurate and relax the
|
||||
* comparisons during the grouping algorithms. The actual accuracy may be modified
|
||||
* through the HWLOC_GROUPING_ACCURACY environment variable (see \ref envvar).
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_DISTANCES_ADD_FLAG_GROUP_INACCURATE = (1UL<<1)
|
||||
};
|
||||
|
||||
/** \brief Commit a new distances structure.
|
||||
*
|
||||
* This function finalizes the distances structure and inserts in it the topology.
|
||||
*
|
||||
* Parameter \p handle was previously returned by hwloc_distances_add_create().
|
||||
* Then objects and values were specified with hwloc_distances_add_values().
|
||||
*
|
||||
* \p flags configures the behavior of the function using an optional OR'ed set of
|
||||
* ::hwloc_distances_add_flag_e.
|
||||
* It may be used to request the grouping of existing objects based on distances.
|
||||
*
|
||||
* On error, the temporary distances structure and its content are destroyed.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c -1 on error.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_distances_add_commit(hwloc_topology_t topology,
|
||||
hwloc_distances_add_handle_t handle,
|
||||
unsigned long flags);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
/** \defgroup hwlocality_distances_remove Remove distances between objects
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Remove all distance matrices from a topology.
|
||||
*
|
||||
* Remove all distance matrices, either provided by the user or
|
||||
* gathered through the OS.
|
||||
*
|
||||
* If these distances were used to group objects, these additional
|
||||
* Group objects are not removed from the topology.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_distances_remove(hwloc_topology_t topology);
|
||||
|
||||
/** \brief Remove distance matrices for objects at a specific depth in the topology.
|
||||
*
|
||||
* Identical to hwloc_distances_remove() but only applies to one level of the topology.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_distances_remove_by_depth(hwloc_topology_t topology, int depth);
|
||||
|
||||
/** \brief Remove distance matrices for objects of a specific type in the topology.
|
||||
*
|
||||
* Identical to hwloc_distances_remove() but only applies to one level of the topology.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_distances_remove_by_type(hwloc_topology_t topology, hwloc_obj_type_t type)
|
||||
{
|
||||
int depth = hwloc_get_type_depth(topology, type);
|
||||
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
|
||||
return 0;
|
||||
return hwloc_distances_remove_by_depth(topology, depth);
|
||||
}
|
||||
|
||||
/** \brief Release and remove the given distance matrice from the topology.
|
||||
*
|
||||
* This function includes a call to hwloc_distances_release().
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_distances_release_remove(hwloc_topology_t topology, struct hwloc_distances_s *distances);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_DISTANCES_H */
|
||||
278
src/3rdparty/hwloc/include/hwloc/export.h
vendored
278
src/3rdparty/hwloc/include/hwloc/export.h
vendored
@@ -1,278 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009-2018 Inria. All rights reserved.
|
||||
* Copyright © 2009-2012 Université Bordeaux
|
||||
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Exporting Topologies to XML or to Synthetic strings.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_EXPORT_H
|
||||
#define HWLOC_EXPORT_H
|
||||
|
||||
#ifndef HWLOC_H
|
||||
#error Please include the main hwloc.h instead
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#elif 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup hwlocality_xmlexport Exporting Topologies to XML
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Flags for exporting XML topologies.
|
||||
*
|
||||
* Flags to be given as a OR'ed set to hwloc_topology_export_xml().
|
||||
*/
|
||||
enum hwloc_topology_export_xml_flags_e {
|
||||
/** \brief Export XML that is loadable by hwloc v1.x.
|
||||
* However, the export may miss some details about the topology.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1 = (1UL<<0)
|
||||
};
|
||||
|
||||
/** \brief Export the topology into an XML file.
|
||||
*
|
||||
* This file may be loaded later through hwloc_topology_set_xml().
|
||||
*
|
||||
* By default, the latest export format is used, which means older hwloc
|
||||
* releases (e.g. v1.x) will not be able to import it.
|
||||
* Exporting to v1.x specific XML format is possible using flag
|
||||
* ::HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1 but it may miss some details
|
||||
* about the topology.
|
||||
* If there is any chance that the exported file may ever be imported
|
||||
* back by a process using hwloc 1.x, one should consider detecting
|
||||
* it at runtime and using the corresponding export format.
|
||||
*
|
||||
* \p flags is a OR'ed set of ::hwloc_topology_export_xml_flags_e.
|
||||
*
|
||||
* \return -1 if a failure occured.
|
||||
*
|
||||
* \note See also hwloc_topology_set_userdata_export_callback()
|
||||
* for exporting application-specific object userdata.
|
||||
*
|
||||
* \note The topology-specific userdata pointer is ignored when exporting to XML.
|
||||
*
|
||||
* \note Only printable characters may be exported to XML string attributes.
|
||||
* Any other character, especially any non-ASCII character, will be silently
|
||||
* dropped.
|
||||
*
|
||||
* \note If \p name is "-", the XML output is sent to the standard output.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_topology_export_xml(hwloc_topology_t topology, const char *xmlpath, unsigned long flags);
|
||||
|
||||
/** \brief Export the topology into a newly-allocated XML memory buffer.
|
||||
*
|
||||
* \p xmlbuffer is allocated by the callee and should be freed with
|
||||
* hwloc_free_xmlbuffer() later in the caller.
|
||||
*
|
||||
* This memory buffer may be loaded later through hwloc_topology_set_xmlbuffer().
|
||||
*
|
||||
* By default, the latest export format is used, which means older hwloc
|
||||
* releases (e.g. v1.x) will not be able to import it.
|
||||
* Exporting to v1.x specific XML format is possible using flag
|
||||
* ::HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1 but it may miss some details
|
||||
* about the topology.
|
||||
* If there is any chance that the exported buffer may ever be imported
|
||||
* back by a process using hwloc 1.x, one should consider detecting
|
||||
* it at runtime and using the corresponding export format.
|
||||
*
|
||||
* The returned buffer ends with a \0 that is included in the returned
|
||||
* length.
|
||||
*
|
||||
* \p flags is a OR'ed set of ::hwloc_topology_export_xml_flags_e.
|
||||
*
|
||||
* \return -1 if a failure occured.
|
||||
*
|
||||
* \note See also hwloc_topology_set_userdata_export_callback()
|
||||
* for exporting application-specific object userdata.
|
||||
*
|
||||
* \note The topology-specific userdata pointer is ignored when exporting to XML.
|
||||
*
|
||||
* \note Only printable characters may be exported to XML string attributes.
|
||||
* Any other character, especially any non-ASCII character, will be silently
|
||||
* dropped.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_topology_export_xmlbuffer(hwloc_topology_t topology, char **xmlbuffer, int *buflen, unsigned long flags);
|
||||
|
||||
/** \brief Free a buffer allocated by hwloc_topology_export_xmlbuffer() */
|
||||
HWLOC_DECLSPEC void hwloc_free_xmlbuffer(hwloc_topology_t topology, char *xmlbuffer);
|
||||
|
||||
/** \brief Set the application-specific callback for exporting object userdata
|
||||
*
|
||||
* The object userdata pointer is not exported to XML by default because hwloc
|
||||
* does not know what it contains.
|
||||
*
|
||||
* This function lets applications set \p export_cb to a callback function
|
||||
* that converts this opaque userdata into an exportable string.
|
||||
*
|
||||
* \p export_cb is invoked during XML export for each object whose
|
||||
* \p userdata pointer is not \c NULL.
|
||||
* The callback should use hwloc_export_obj_userdata() or
|
||||
* hwloc_export_obj_userdata_base64() to actually export
|
||||
* something to XML (possibly multiple times per object).
|
||||
*
|
||||
* \p export_cb may be set to \c NULL if userdata should not be exported to XML.
|
||||
*
|
||||
* \note The topology-specific userdata pointer is ignored when exporting to XML.
|
||||
*/
|
||||
HWLOC_DECLSPEC void hwloc_topology_set_userdata_export_callback(hwloc_topology_t topology,
|
||||
void (*export_cb)(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj));
|
||||
|
||||
/** \brief Export some object userdata to XML
|
||||
*
|
||||
* This function may only be called from within the export() callback passed
|
||||
* to hwloc_topology_set_userdata_export_callback().
|
||||
* It may be invoked one of multiple times to export some userdata to XML.
|
||||
* The \p buffer content of length \p length is stored with optional name
|
||||
* \p name.
|
||||
*
|
||||
* When importing this XML file, the import() callback (if set) will be
|
||||
* called exactly as many times as hwloc_export_obj_userdata() was called
|
||||
* during export(). It will receive the corresponding \p name, \p buffer
|
||||
* and \p length arguments.
|
||||
*
|
||||
* \p reserved, \p topology and \p obj must be the first three parameters
|
||||
* that were given to the export callback.
|
||||
*
|
||||
* Only printable characters may be exported to XML string attributes.
|
||||
* If a non-printable character is passed in \p name or \p buffer,
|
||||
* the function returns -1 with errno set to EINVAL.
|
||||
*
|
||||
* If exporting binary data, the application should first encode into
|
||||
* printable characters only (or use hwloc_export_obj_userdata_base64()).
|
||||
* It should also take care of portability issues if the export may
|
||||
* be reimported on a different architecture.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_export_obj_userdata(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length);
|
||||
|
||||
/** \brief Encode and export some object userdata to XML
|
||||
*
|
||||
* This function is similar to hwloc_export_obj_userdata() but it encodes
|
||||
* the input buffer into printable characters before exporting.
|
||||
* On import, decoding is automatically performed before the data is given
|
||||
* to the import() callback if any.
|
||||
*
|
||||
* This function may only be called from within the export() callback passed
|
||||
* to hwloc_topology_set_userdata_export_callback().
|
||||
*
|
||||
* The function does not take care of portability issues if the export
|
||||
* may be reimported on a different architecture.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_export_obj_userdata_base64(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length);
|
||||
|
||||
/** \brief Set the application-specific callback for importing userdata
|
||||
*
|
||||
* On XML import, userdata is ignored by default because hwloc does not know
|
||||
* how to store it in memory.
|
||||
*
|
||||
* This function lets applications set \p import_cb to a callback function
|
||||
* that will get the XML-stored userdata and store it in the object as expected
|
||||
* by the application.
|
||||
*
|
||||
* \p import_cb is called during hwloc_topology_load() as many times as
|
||||
* hwloc_export_obj_userdata() was called during export. The topology
|
||||
* is not entirely setup yet. Object attributes are ready to consult,
|
||||
* but links between objects are not.
|
||||
*
|
||||
* \p import_cb may be \c NULL if userdata should be ignored during import.
|
||||
*
|
||||
* \note \p buffer contains \p length characters followed by a null byte ('\0').
|
||||
*
|
||||
* \note This function should be called before hwloc_topology_load().
|
||||
*
|
||||
* \note The topology-specific userdata pointer is ignored when importing from XML.
|
||||
*/
|
||||
HWLOC_DECLSPEC void hwloc_topology_set_userdata_import_callback(hwloc_topology_t topology,
|
||||
void (*import_cb)(hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length));
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/** \defgroup hwlocality_syntheticexport Exporting Topologies to Synthetic
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Flags for exporting synthetic topologies.
|
||||
*
|
||||
* Flags to be given as a OR'ed set to hwloc_topology_export_synthetic().
|
||||
*/
|
||||
enum hwloc_topology_export_synthetic_flags_e {
|
||||
/** \brief Export extended types such as L2dcache as basic types such as Cache.
|
||||
*
|
||||
* This is required if loading the synthetic description with hwloc < 1.9.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES = (1UL<<0),
|
||||
|
||||
/** \brief Do not export level attributes.
|
||||
*
|
||||
* Ignore level attributes such as memory/cache sizes or PU indexes.
|
||||
* This is required if loading the synthetic description with hwloc < 1.10.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS = (1UL<<1),
|
||||
|
||||
/** \brief Export the memory hierarchy as expected in hwloc 1.x.
|
||||
*
|
||||
* Instead of attaching memory children to levels, export single NUMA node child
|
||||
* as normal intermediate levels, when possible.
|
||||
* This is required if loading the synthetic description with hwloc 1.x.
|
||||
* However this may fail if some objects have multiple local NUMA nodes.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_V1 = (1UL<<2),
|
||||
|
||||
/** \brief Do not export memory information.
|
||||
*
|
||||
* Only export the actual hierarchy of normal CPU-side objects and ignore
|
||||
* where memory is attached.
|
||||
* This is useful for when the hierarchy of CPUs is what really matters,
|
||||
* but it behaves as if there was a single machine-wide NUMA node.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_IGNORE_MEMORY = (1UL<<3)
|
||||
};
|
||||
|
||||
/** \brief Export the topology as a synthetic string.
|
||||
*
|
||||
* At most \p buflen characters will be written in \p buffer,
|
||||
* including the terminating \0.
|
||||
*
|
||||
* This exported string may be given back to hwloc_topology_set_synthetic().
|
||||
*
|
||||
* \p flags is a OR'ed set of ::hwloc_topology_export_synthetic_flags_e.
|
||||
*
|
||||
* \return The number of characters that were written,
|
||||
* not including the terminating \0.
|
||||
*
|
||||
* \return -1 if the topology could not be exported,
|
||||
* for instance if it is not symmetric.
|
||||
*
|
||||
* \note I/O and Misc children are ignored, the synthetic string only
|
||||
* describes normal children.
|
||||
*
|
||||
* \note A 1024-byte buffer should be large enough for exporting
|
||||
* topologies in the vast majority of cases.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_topology_export_synthetic(hwloc_topology_t topology, char *buffer, size_t buflen, unsigned long flags);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_EXPORT_H */
|
||||
136
src/3rdparty/hwloc/include/hwloc/gl.h
vendored
136
src/3rdparty/hwloc/include/hwloc/gl.h
vendored
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Blue Brain Project, EPFL. All rights reserved.
|
||||
* Copyright © 2012-2021 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Macros to help interaction between hwloc and OpenGL displays.
|
||||
*
|
||||
* Applications that use both hwloc and OpenGL may want to include
|
||||
* this file so as to get topology information for OpenGL displays.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_GL_H
|
||||
#define HWLOC_GL_H
|
||||
|
||||
#include "hwloc.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup hwlocality_gl Interoperability with OpenGL displays
|
||||
*
|
||||
* This interface offers ways to retrieve topology information about
|
||||
* OpenGL displays.
|
||||
*
|
||||
* Only the NVIDIA display locality information is currently available,
|
||||
* using the NV-CONTROL X11 extension and the NVCtrl library.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Get the hwloc OS device object corresponding to the
|
||||
* OpenGL display given by port and device index.
|
||||
*
|
||||
* \return The hwloc OS device object describing the OpenGL display
|
||||
* whose port (server) is \p port and device (screen) is \p device.
|
||||
* \return \c NULL if none could be found.
|
||||
*
|
||||
* The topology \p topology does not necessarily have to match the current
|
||||
* machine. For instance the topology may be an XML import of a remote host.
|
||||
* I/O devices detection and the GL component must be enabled in the topology.
|
||||
*
|
||||
* \note The corresponding PCI device object can be obtained by looking
|
||||
* at the OS device parent object (unless PCI devices are filtered out).
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_gl_get_display_osdev_by_port_device(hwloc_topology_t topology,
|
||||
unsigned port, unsigned device)
|
||||
{
|
||||
unsigned x = (unsigned) -1, y = (unsigned) -1;
|
||||
hwloc_obj_t osdev = NULL;
|
||||
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
|
||||
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
|
||||
&& osdev->name
|
||||
&& sscanf(osdev->name, ":%u.%u", &x, &y) == 2
|
||||
&& port == x && device == y)
|
||||
return osdev;
|
||||
}
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** \brief Get the hwloc OS device object corresponding to the
|
||||
* OpenGL display given by name.
|
||||
*
|
||||
* \return The hwloc OS device object describing the OpenGL display
|
||||
* whose name is \p name, built as ":port.device" such as ":0.0" .
|
||||
* \return \c NULL if none could be found.
|
||||
*
|
||||
* The topology \p topology does not necessarily have to match the current
|
||||
* machine. For instance the topology may be an XML import of a remote host.
|
||||
* I/O devices detection and the GL component must be enabled in the topology.
|
||||
*
|
||||
* \note The corresponding PCI device object can be obtained by looking
|
||||
* at the OS device parent object (unless PCI devices are filtered out).
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_gl_get_display_osdev_by_name(hwloc_topology_t topology,
|
||||
const char *name)
|
||||
{
|
||||
hwloc_obj_t osdev = NULL;
|
||||
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
|
||||
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
|
||||
&& osdev->name
|
||||
&& !strcmp(name, osdev->name))
|
||||
return osdev;
|
||||
}
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** \brief Get the OpenGL display port and device corresponding
|
||||
* to the given hwloc OS object.
|
||||
*
|
||||
* Retrieves the OpenGL display port (server) in \p port and device (screen)
|
||||
* in \p screen that correspond to the given hwloc OS device object.
|
||||
*
|
||||
* \return \c -1 if none could be found.
|
||||
*
|
||||
* The topology \p topology does not necessarily have to match the current
|
||||
* machine. For instance the topology may be an XML import of a remote host.
|
||||
* I/O devices detection and the GL component must be enabled in the topology.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_gl_get_display_by_osdev(hwloc_topology_t topology __hwloc_attribute_unused,
|
||||
hwloc_obj_t osdev,
|
||||
unsigned *port, unsigned *device)
|
||||
{
|
||||
unsigned x = -1, y = -1;
|
||||
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
|
||||
&& sscanf(osdev->name, ":%u.%u", &x, &y) == 2) {
|
||||
*port = x;
|
||||
*device = y;
|
||||
return 0;
|
||||
}
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_GL_H */
|
||||
|
||||
126
src/3rdparty/hwloc/include/hwloc/glibc-sched.h
vendored
126
src/3rdparty/hwloc/include/hwloc/glibc-sched.h
vendored
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Macros to help interaction between hwloc and glibc scheduling routines.
|
||||
*
|
||||
* Applications that use both hwloc and glibc scheduling routines such as
|
||||
* sched_getaffinity() or pthread_attr_setaffinity_np() may want to include
|
||||
* this file so as to ease conversion between their respective types.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_GLIBC_SCHED_H
|
||||
#define HWLOC_GLIBC_SCHED_H
|
||||
|
||||
#include "hwloc.h"
|
||||
#include "hwloc/helper.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#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
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HWLOC_HAVE_CPU_SET
|
||||
|
||||
|
||||
/** \defgroup hwlocality_glibc_sched Interoperability with glibc sched affinity
|
||||
*
|
||||
* This interface offers ways to convert between hwloc cpusets and glibc cpusets
|
||||
* such as those manipulated by sched_getaffinity() or pthread_attr_setaffinity_np().
|
||||
*
|
||||
* \note Topology \p topology must match the current machine.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** \brief Convert hwloc CPU set \p toposet into glibc sched affinity CPU set \p schedset
|
||||
*
|
||||
* This function may be used before calling sched_setaffinity or any other function
|
||||
* that takes a cpu_set_t as input parameter.
|
||||
*
|
||||
* \p schedsetsize should be sizeof(cpu_set_t) unless \p schedset was dynamically allocated with CPU_ALLOC
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_cpuset_to_glibc_sched_affinity(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t hwlocset,
|
||||
cpu_set_t *schedset, size_t schedsetsize)
|
||||
{
|
||||
#ifdef CPU_ZERO_S
|
||||
unsigned cpu;
|
||||
CPU_ZERO_S(schedsetsize, schedset);
|
||||
hwloc_bitmap_foreach_begin(cpu, hwlocset)
|
||||
CPU_SET_S(cpu, schedsetsize, schedset);
|
||||
hwloc_bitmap_foreach_end();
|
||||
#else /* !CPU_ZERO_S */
|
||||
unsigned cpu;
|
||||
CPU_ZERO(schedset);
|
||||
assert(schedsetsize == sizeof(cpu_set_t));
|
||||
hwloc_bitmap_foreach_begin(cpu, hwlocset)
|
||||
CPU_SET(cpu, schedset);
|
||||
hwloc_bitmap_foreach_end();
|
||||
#endif /* !CPU_ZERO_S */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Convert glibc sched affinity CPU set \p schedset into hwloc CPU set
|
||||
*
|
||||
* This function may be used before calling sched_setaffinity or any other function
|
||||
* that takes a cpu_set_t as input parameter.
|
||||
*
|
||||
* \p schedsetsize should be sizeof(cpu_set_t) unless \p schedset was dynamically allocated with CPU_ALLOC
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_cpuset_from_glibc_sched_affinity(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_cpuset_t hwlocset,
|
||||
const cpu_set_t *schedset, size_t schedsetsize)
|
||||
{
|
||||
int cpu;
|
||||
#ifdef CPU_ZERO_S
|
||||
int count;
|
||||
#endif
|
||||
hwloc_bitmap_zero(hwlocset);
|
||||
#ifdef CPU_ZERO_S
|
||||
count = CPU_COUNT_S(schedsetsize, schedset);
|
||||
cpu = 0;
|
||||
while (count) {
|
||||
if (CPU_ISSET_S(cpu, schedsetsize, schedset)) {
|
||||
hwloc_bitmap_set(hwlocset, cpu);
|
||||
count--;
|
||||
}
|
||||
cpu++;
|
||||
}
|
||||
#else /* !CPU_ZERO_S */
|
||||
/* sched.h does not support dynamic cpu_set_t (introduced in glibc 2.7),
|
||||
* assume we have a very old interface without CPU_COUNT (added in 2.6)
|
||||
*/
|
||||
assert(schedsetsize == sizeof(cpu_set_t));
|
||||
for(cpu=0; cpu<CPU_SETSIZE; cpu++)
|
||||
if (CPU_ISSET(cpu, schedset))
|
||||
hwloc_bitmap_set(hwlocset, cpu);
|
||||
#endif /* !CPU_ZERO_S */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#endif /* CPU_SET */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_GLIBC_SCHED_H */
|
||||
1231
src/3rdparty/hwloc/include/hwloc/helper.h
vendored
1231
src/3rdparty/hwloc/include/hwloc/helper.h
vendored
File diff suppressed because it is too large
Load Diff
146
src/3rdparty/hwloc/include/hwloc/inlines.h
vendored
146
src/3rdparty/hwloc/include/hwloc/inlines.h
vendored
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2018 Inria. All rights reserved.
|
||||
* Copyright © 2009-2012 Université Bordeaux
|
||||
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file contains the inline code of functions declared in hwloc.h
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_INLINES_H
|
||||
#define HWLOC_INLINES_H
|
||||
|
||||
#ifndef HWLOC_H
|
||||
#error Please include the main hwloc.h instead
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static __hwloc_inline int
|
||||
hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
|
||||
{
|
||||
int depth = hwloc_get_type_depth(topology, type);
|
||||
|
||||
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
|
||||
return depth;
|
||||
|
||||
/* find the highest existing level with type order >= */
|
||||
for(depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU); ; depth--)
|
||||
if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0)
|
||||
return depth+1;
|
||||
|
||||
/* Shouldn't ever happen, as there is always a Machine level with lower order and known depth. */
|
||||
/* abort(); */
|
||||
}
|
||||
|
||||
static __hwloc_inline int
|
||||
hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
|
||||
{
|
||||
int depth = hwloc_get_type_depth(topology, type);
|
||||
|
||||
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
|
||||
return depth;
|
||||
|
||||
/* find the lowest existing level with type order <= */
|
||||
for(depth = 0; ; depth++)
|
||||
if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) > 0)
|
||||
return depth-1;
|
||||
|
||||
/* Shouldn't ever happen, as there is always a PU level with higher order and known depth. */
|
||||
/* abort(); */
|
||||
}
|
||||
|
||||
static __hwloc_inline int
|
||||
hwloc_get_nbobjs_by_type (hwloc_topology_t topology, hwloc_obj_type_t type)
|
||||
{
|
||||
int depth = hwloc_get_type_depth(topology, type);
|
||||
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
|
||||
return 0;
|
||||
if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
|
||||
return -1; /* FIXME: agregate nbobjs from different levels? */
|
||||
return (int) hwloc_get_nbobjs_by_depth(topology, depth);
|
||||
}
|
||||
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_get_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type, unsigned idx)
|
||||
{
|
||||
int depth = hwloc_get_type_depth(topology, type);
|
||||
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
|
||||
return NULL;
|
||||
if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
|
||||
return NULL;
|
||||
return hwloc_get_obj_by_depth(topology, depth, idx);
|
||||
}
|
||||
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_get_next_obj_by_depth (hwloc_topology_t topology, int depth, hwloc_obj_t prev)
|
||||
{
|
||||
if (!prev)
|
||||
return hwloc_get_obj_by_depth (topology, depth, 0);
|
||||
if (prev->depth != depth)
|
||||
return NULL;
|
||||
return prev->next_cousin;
|
||||
}
|
||||
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
|
||||
hwloc_obj_t prev)
|
||||
{
|
||||
int depth = hwloc_get_type_depth(topology, type);
|
||||
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
|
||||
return NULL;
|
||||
return hwloc_get_next_obj_by_depth (topology, depth, prev);
|
||||
}
|
||||
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_get_root_obj (hwloc_topology_t topology)
|
||||
{
|
||||
return hwloc_get_obj_by_depth (topology, 0, 0);
|
||||
}
|
||||
|
||||
static __hwloc_inline const char *
|
||||
hwloc_obj_get_info_by_name(hwloc_obj_t obj, const char *name)
|
||||
{
|
||||
unsigned i;
|
||||
for(i=0; i<obj->infos_count; i++) {
|
||||
struct hwloc_info_s *info = &obj->infos[i];
|
||||
if (!strcmp(info->name, name))
|
||||
return info->value;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static __hwloc_inline void *
|
||||
hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t set, hwloc_membind_policy_t policy, int flags)
|
||||
{
|
||||
void *p = hwloc_alloc_membind(topology, len, set, policy, flags);
|
||||
if (p)
|
||||
return p;
|
||||
|
||||
if (hwloc_set_membind(topology, set, policy, flags) < 0)
|
||||
/* hwloc_set_membind() takes care of ignoring errors if non-STRICT */
|
||||
return NULL;
|
||||
|
||||
p = hwloc_alloc(topology, len);
|
||||
if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
|
||||
/* Enforce the binding by touching the data */
|
||||
memset(p, 0, len);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_INLINES_H */
|
||||
136
src/3rdparty/hwloc/include/hwloc/intel-mic.h
vendored
136
src/3rdparty/hwloc/include/hwloc/intel-mic.h
vendored
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013-2016 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Macros to help interaction between hwloc and Intel Xeon Phi (MIC).
|
||||
*
|
||||
* Applications that use both hwloc and Intel Xeon Phi (MIC) may want to
|
||||
* include this file so as to get topology information for MIC devices.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_INTEL_MIC_H
|
||||
#define HWLOC_INTEL_MIC_H
|
||||
|
||||
#include "hwloc.h"
|
||||
#include "hwloc/autogen/config.h"
|
||||
#include "hwloc/helper.h"
|
||||
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
#include "hwloc/linux.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup hwlocality_intel_mic Interoperability with Intel Xeon Phi (MIC)
|
||||
*
|
||||
* This interface offers ways to retrieve topology information about
|
||||
* Intel Xeon Phi (MIC) devices.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Get the CPU set of logical processors that are physically
|
||||
* close to MIC device whose index is \p idx.
|
||||
*
|
||||
* Return the CPU set describing the locality of the MIC device whose index is \p idx.
|
||||
*
|
||||
* Topology \p topology and device index \p idx must match the local machine.
|
||||
* I/O devices detection is not needed in the topology.
|
||||
*
|
||||
* The function only returns the locality of the device.
|
||||
* If more information about the device is needed, OS objects should
|
||||
* be used instead, see hwloc_intel_mic_get_device_osdev_by_index().
|
||||
*
|
||||
* This function is currently only implemented in a meaningful way for
|
||||
* Linux; other systems will simply get a full cpuset.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_intel_mic_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
|
||||
int idx __hwloc_attribute_unused,
|
||||
hwloc_cpuset_t set)
|
||||
{
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
|
||||
#define HWLOC_INTEL_MIC_DEVICE_SYSFS_PATH_MAX 128
|
||||
char path[HWLOC_INTEL_MIC_DEVICE_SYSFS_PATH_MAX];
|
||||
DIR *sysdir = NULL;
|
||||
struct dirent *dirent;
|
||||
unsigned pcibus, pcidev, pcifunc;
|
||||
|
||||
if (!hwloc_topology_is_thissystem(topology)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(path, "/sys/class/mic/mic%d", idx);
|
||||
sysdir = opendir(path);
|
||||
if (!sysdir)
|
||||
return -1;
|
||||
|
||||
while ((dirent = readdir(sysdir)) != NULL) {
|
||||
if (sscanf(dirent->d_name, "pci_%02x:%02x.%02x", &pcibus, &pcidev, &pcifunc) == 3) {
|
||||
sprintf(path, "/sys/class/mic/mic%d/pci_%02x:%02x.%02x/local_cpus", idx, pcibus, pcidev, pcifunc);
|
||||
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|
||||
|| hwloc_bitmap_iszero(set))
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(sysdir);
|
||||
#else
|
||||
/* Non-Linux systems simply get a full cpuset */
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Get the hwloc OS device object corresponding to the
|
||||
* MIC device for the given index.
|
||||
*
|
||||
* Return the OS device object describing the MIC device whose index is \p idx.
|
||||
* Return NULL if there is none.
|
||||
*
|
||||
* The topology \p topology does not necessarily have to match the current
|
||||
* machine. For instance the topology may be an XML import of a remote host.
|
||||
* I/O devices detection must be enabled in the topology.
|
||||
*
|
||||
* \note The corresponding PCI device object can be obtained by looking
|
||||
* at the OS device parent object.
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_intel_mic_get_device_osdev_by_index(hwloc_topology_t topology,
|
||||
unsigned idx)
|
||||
{
|
||||
hwloc_obj_t osdev = NULL;
|
||||
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
|
||||
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
|
||||
&& osdev->name
|
||||
&& !strncmp("mic", osdev->name, 3)
|
||||
&& atoi(osdev->name + 3) == (int) idx)
|
||||
return osdev;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_INTEL_MIC_H */
|
||||
157
src/3rdparty/hwloc/include/hwloc/levelzero.h
vendored
157
src/3rdparty/hwloc/include/hwloc/levelzero.h
vendored
@@ -1,157 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2021 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Macros to help interaction between hwloc and the oneAPI Level Zero interface.
|
||||
*
|
||||
* Applications that use both hwloc and Level Zero may want to
|
||||
* include this file so as to get topology information for L0 devices.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_LEVELZERO_H
|
||||
#define HWLOC_LEVELZERO_H
|
||||
|
||||
#include "hwloc.h"
|
||||
#include "hwloc/autogen/config.h"
|
||||
#include "hwloc/helper.h"
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
#include "hwloc/linux.h"
|
||||
#endif
|
||||
|
||||
#include <level_zero/ze_api.h>
|
||||
#include <level_zero/zes_api.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup hwlocality_levelzero Interoperability with the oneAPI Level Zero interface.
|
||||
*
|
||||
* This interface offers ways to retrieve topology information about
|
||||
* devices managed by the Level Zero API.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Get the CPU set of logical processors that are physically
|
||||
* close to the Level Zero device \p device
|
||||
*
|
||||
* Store in \p set the CPU-set describing the locality of
|
||||
* the Level Zero device \p device.
|
||||
*
|
||||
* Topology \p topology and device \p device must match the local machine.
|
||||
* The Level Zero must have been initialized with Sysman enabled
|
||||
* (ZES_ENABLE_SYSMAN=1 in the environment).
|
||||
* I/O devices detection and the Level Zero component are not needed in the
|
||||
* topology.
|
||||
*
|
||||
* The function only returns the locality of the device.
|
||||
* If more information about the device is needed, OS objects should
|
||||
* be used instead, see hwloc_levelzero_get_device_osdev().
|
||||
*
|
||||
* This function is currently only implemented in a meaningful way for
|
||||
* Linux; other systems will simply get a full cpuset.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_levelzero_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
|
||||
ze_device_handle_t device, hwloc_cpuset_t set)
|
||||
{
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
|
||||
#define HWLOC_LEVELZERO_DEVICE_SYSFS_PATH_MAX 128
|
||||
char path[HWLOC_LEVELZERO_DEVICE_SYSFS_PATH_MAX];
|
||||
zes_pci_properties_t pci;
|
||||
zes_device_handle_t sdevice = device;
|
||||
ze_result_t res;
|
||||
|
||||
if (!hwloc_topology_is_thissystem(topology)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = zesDevicePciGetProperties(sdevice, &pci);
|
||||
if (res != ZE_RESULT_SUCCESS) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/local_cpus",
|
||||
pci.address.domain, pci.address.bus, pci.address.device, pci.address.function);
|
||||
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|
||||
|| hwloc_bitmap_iszero(set))
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
#else
|
||||
/* Non-Linux systems simply get a full cpuset */
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Get the hwloc OS device object corresponding to Level Zero device
|
||||
* \p device.
|
||||
*
|
||||
* \return The hwloc OS device object that describes the given Level Zero device \p device.
|
||||
* \return \c NULL if none could be found.
|
||||
*
|
||||
* Topology \p topology and device \p dv_ind must match the local machine.
|
||||
* I/O devices detection and the Level Zero component must be enabled in the
|
||||
* topology. If not, the locality of the object may still be found using
|
||||
* hwloc_levelzero_get_device_cpuset().
|
||||
*
|
||||
* \note The corresponding hwloc PCI device may be found by looking
|
||||
* at the result parent pointer (unless PCI devices are filtered out).
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_levelzero_get_device_osdev(hwloc_topology_t topology, ze_device_handle_t device)
|
||||
{
|
||||
zes_device_handle_t sdevice = device;
|
||||
zes_pci_properties_t pci;
|
||||
ze_result_t res;
|
||||
hwloc_obj_t osdev;
|
||||
|
||||
if (!hwloc_topology_is_thissystem(topology)) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res = zesDevicePciGetProperties(sdevice, &pci);
|
||||
if (res != ZE_RESULT_SUCCESS) {
|
||||
/* L0 was likely initialized without sysman, don't bother */
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
osdev = NULL;
|
||||
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
|
||||
hwloc_obj_t pcidev = osdev->parent;
|
||||
|
||||
if (strncmp(osdev->name, "ze", 2))
|
||||
continue;
|
||||
|
||||
if (pcidev
|
||||
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
|
||||
&& pcidev->attr->pcidev.domain == pci.address.domain
|
||||
&& pcidev->attr->pcidev.bus == pci.address.bus
|
||||
&& pcidev->attr->pcidev.dev == pci.address.device
|
||||
&& pcidev->attr->pcidev.func == pci.address.function)
|
||||
return osdev;
|
||||
|
||||
/* FIXME: when we'll have serialnumber, try it in case PCI is filtered-out */
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_LEVELZERO_H */
|
||||
274
src/3rdparty/hwloc/include/hwloc/linux-libnuma.h
vendored
274
src/3rdparty/hwloc/include/hwloc/linux-libnuma.h
vendored
@@ -1,274 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2017 Inria. All rights reserved.
|
||||
* Copyright © 2009-2010, 2012 Université Bordeaux
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Macros to help interaction between hwloc and Linux libnuma.
|
||||
*
|
||||
* Applications that use both Linux libnuma and hwloc may want to
|
||||
* include this file so as to ease conversion between their respective types.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_LINUX_LIBNUMA_H
|
||||
#define HWLOC_LINUX_LIBNUMA_H
|
||||
|
||||
#include "hwloc.h"
|
||||
|
||||
#include <numa.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup hwlocality_linux_libnuma_ulongs Interoperability with Linux libnuma unsigned long masks
|
||||
*
|
||||
* This interface helps converting between Linux libnuma unsigned long masks
|
||||
* and hwloc cpusets and nodesets.
|
||||
*
|
||||
* \note Topology \p topology must match the current machine.
|
||||
*
|
||||
* \note The behavior of libnuma is undefined if the kernel is not NUMA-aware.
|
||||
* (when CONFIG_NUMA is not set in the kernel configuration).
|
||||
* This helper and libnuma may thus not be strictly compatible in this case,
|
||||
* which may be detected by checking whether numa_available() returns -1.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** \brief Convert hwloc CPU set \p cpuset into the array of unsigned long \p mask
|
||||
*
|
||||
* \p mask is the array of unsigned long that will be filled.
|
||||
* \p maxnode contains the maximal node number that may be stored in \p mask.
|
||||
* \p maxnode will be set to the maximal node number that was found, plus one.
|
||||
*
|
||||
* This function may be used before calling set_mempolicy, mbind, migrate_pages
|
||||
* or any other function that takes an array of unsigned long and a maximal
|
||||
* node number as input parameter.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_cpuset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset,
|
||||
unsigned long *mask, unsigned long *maxnode)
|
||||
{
|
||||
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
|
||||
unsigned long outmaxnode = -1;
|
||||
hwloc_obj_t node = NULL;
|
||||
|
||||
/* round-up to the next ulong and clear all bytes */
|
||||
*maxnode = (*maxnode + 8*sizeof(*mask) - 1) & ~(8*sizeof(*mask) - 1);
|
||||
memset(mask, 0, *maxnode/8);
|
||||
|
||||
while ((node = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, node)) != NULL) {
|
||||
if (node->os_index >= *maxnode)
|
||||
continue;
|
||||
mask[node->os_index/sizeof(*mask)/8] |= 1UL << (node->os_index % (sizeof(*mask)*8));
|
||||
if (outmaxnode == (unsigned long) -1 || outmaxnode < node->os_index)
|
||||
outmaxnode = node->os_index;
|
||||
}
|
||||
|
||||
*maxnode = outmaxnode+1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Convert hwloc NUMA node set \p nodeset into the array of unsigned long \p mask
|
||||
*
|
||||
* \p mask is the array of unsigned long that will be filled.
|
||||
* \p maxnode contains the maximal node number that may be stored in \p mask.
|
||||
* \p maxnode will be set to the maximal node number that was found, plus one.
|
||||
*
|
||||
* This function may be used before calling set_mempolicy, mbind, migrate_pages
|
||||
* or any other function that takes an array of unsigned long and a maximal
|
||||
* node number as input parameter.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_nodeset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset,
|
||||
unsigned long *mask, unsigned long *maxnode)
|
||||
{
|
||||
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
|
||||
unsigned long outmaxnode = -1;
|
||||
hwloc_obj_t node = NULL;
|
||||
|
||||
/* round-up to the next ulong and clear all bytes */
|
||||
*maxnode = (*maxnode + 8*sizeof(*mask) - 1) & ~(8*sizeof(*mask) - 1);
|
||||
memset(mask, 0, *maxnode/8);
|
||||
|
||||
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL) {
|
||||
if (node->os_index >= *maxnode)
|
||||
continue;
|
||||
if (!hwloc_bitmap_isset(nodeset, node->os_index))
|
||||
continue;
|
||||
mask[node->os_index/sizeof(*mask)/8] |= 1UL << (node->os_index % (sizeof(*mask)*8));
|
||||
if (outmaxnode == (unsigned long) -1 || outmaxnode < node->os_index)
|
||||
outmaxnode = node->os_index;
|
||||
}
|
||||
|
||||
*maxnode = outmaxnode+1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Convert the array of unsigned long \p mask into hwloc CPU set
|
||||
*
|
||||
* \p mask is a array of unsigned long that will be read.
|
||||
* \p maxnode contains the maximal node number that may be read in \p mask.
|
||||
*
|
||||
* This function may be used after calling get_mempolicy or any other function
|
||||
* that takes an array of unsigned long as output parameter (and possibly
|
||||
* a maximal node number as input parameter).
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
|
||||
const unsigned long *mask, unsigned long maxnode)
|
||||
{
|
||||
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
|
||||
hwloc_obj_t node = NULL;
|
||||
hwloc_bitmap_zero(cpuset);
|
||||
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
|
||||
if (node->os_index < maxnode
|
||||
&& (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))
|
||||
hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Convert the array of unsigned long \p mask into hwloc NUMA node set
|
||||
*
|
||||
* \p mask is a array of unsigned long that will be read.
|
||||
* \p maxnode contains the maximal node number that may be read in \p mask.
|
||||
*
|
||||
* This function may be used after calling get_mempolicy or any other function
|
||||
* that takes an array of unsigned long as output parameter (and possibly
|
||||
* a maximal node number as input parameter).
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
|
||||
const unsigned long *mask, unsigned long maxnode)
|
||||
{
|
||||
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
|
||||
hwloc_obj_t node = NULL;
|
||||
hwloc_bitmap_zero(nodeset);
|
||||
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
|
||||
if (node->os_index < maxnode
|
||||
&& (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))
|
||||
hwloc_bitmap_set(nodeset, node->os_index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
/** \defgroup hwlocality_linux_libnuma_bitmask Interoperability with Linux libnuma bitmask
|
||||
*
|
||||
* This interface helps converting between Linux libnuma bitmasks
|
||||
* and hwloc cpusets and nodesets.
|
||||
*
|
||||
* \note Topology \p topology must match the current machine.
|
||||
*
|
||||
* \note The behavior of libnuma is undefined if the kernel is not NUMA-aware.
|
||||
* (when CONFIG_NUMA is not set in the kernel configuration).
|
||||
* This helper and libnuma may thus not be strictly compatible in this case,
|
||||
* which may be detected by checking whether numa_available() returns -1.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** \brief Convert hwloc CPU set \p cpuset into the returned libnuma bitmask
|
||||
*
|
||||
* The returned bitmask should later be freed with numa_bitmask_free.
|
||||
*
|
||||
* This function may be used before calling many numa_ functions
|
||||
* that use a struct bitmask as an input parameter.
|
||||
*
|
||||
* \return newly allocated struct bitmask.
|
||||
*/
|
||||
static __hwloc_inline struct bitmask *
|
||||
hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset) __hwloc_attribute_malloc;
|
||||
static __hwloc_inline struct bitmask *
|
||||
hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset)
|
||||
{
|
||||
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
|
||||
hwloc_obj_t node = NULL;
|
||||
struct bitmask *bitmask = numa_allocate_cpumask();
|
||||
if (!bitmask)
|
||||
return NULL;
|
||||
while ((node = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, node)) != NULL)
|
||||
if (node->attr->numanode.local_memory)
|
||||
numa_bitmask_setbit(bitmask, node->os_index);
|
||||
return bitmask;
|
||||
}
|
||||
|
||||
/** \brief Convert hwloc NUMA node set \p nodeset into the returned libnuma bitmask
|
||||
*
|
||||
* The returned bitmask should later be freed with numa_bitmask_free.
|
||||
*
|
||||
* This function may be used before calling many numa_ functions
|
||||
* that use a struct bitmask as an input parameter.
|
||||
*
|
||||
* \return newly allocated struct bitmask.
|
||||
*/
|
||||
static __hwloc_inline struct bitmask *
|
||||
hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset) __hwloc_attribute_malloc;
|
||||
static __hwloc_inline struct bitmask *
|
||||
hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset)
|
||||
{
|
||||
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
|
||||
hwloc_obj_t node = NULL;
|
||||
struct bitmask *bitmask = numa_allocate_cpumask();
|
||||
if (!bitmask)
|
||||
return NULL;
|
||||
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
|
||||
if (hwloc_bitmap_isset(nodeset, node->os_index) && node->attr->numanode.local_memory)
|
||||
numa_bitmask_setbit(bitmask, node->os_index);
|
||||
return bitmask;
|
||||
}
|
||||
|
||||
/** \brief Convert libnuma bitmask \p bitmask into hwloc CPU set \p cpuset
|
||||
*
|
||||
* This function may be used after calling many numa_ functions
|
||||
* that use a struct bitmask as an output parameter.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
|
||||
const struct bitmask *bitmask)
|
||||
{
|
||||
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
|
||||
hwloc_obj_t node = NULL;
|
||||
hwloc_bitmap_zero(cpuset);
|
||||
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
|
||||
if (numa_bitmask_isbitset(bitmask, node->os_index))
|
||||
hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Convert libnuma bitmask \p bitmask into hwloc NUMA node set \p nodeset
|
||||
*
|
||||
* This function may be used after calling many numa_ functions
|
||||
* that use a struct bitmask as an output parameter.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_nodeset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
|
||||
const struct bitmask *bitmask)
|
||||
{
|
||||
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
|
||||
hwloc_obj_t node = NULL;
|
||||
hwloc_bitmap_zero(nodeset);
|
||||
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
|
||||
if (numa_bitmask_isbitset(bitmask, node->os_index))
|
||||
hwloc_bitmap_set(nodeset, node->os_index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_LINUX_NUMA_H */
|
||||
87
src/3rdparty/hwloc/include/hwloc/linux.h
vendored
87
src/3rdparty/hwloc/include/hwloc/linux.h
vendored
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2021 Inria. All rights reserved.
|
||||
* Copyright © 2009-2011 Université Bordeaux
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Macros to help interaction between hwloc and Linux.
|
||||
*
|
||||
* Applications that use hwloc on Linux may want to include this file
|
||||
* if using some low-level Linux features.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_LINUX_H
|
||||
#define HWLOC_LINUX_H
|
||||
|
||||
#include "hwloc.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup hwlocality_linux Linux-specific helpers
|
||||
*
|
||||
* This includes helpers for manipulating Linux kernel cpumap files, and hwloc
|
||||
* equivalents of the Linux sched_setaffinity and sched_getaffinity system calls.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Bind a thread \p tid on cpus given in cpuset \p set
|
||||
*
|
||||
* The behavior is exactly the same as the Linux sched_setaffinity system call,
|
||||
* but uses a hwloc cpuset.
|
||||
*
|
||||
* \note This is equivalent to calling hwloc_set_proc_cpubind() with
|
||||
* HWLOC_CPUBIND_THREAD as flags.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_linux_set_tid_cpubind(hwloc_topology_t topology, pid_t tid, hwloc_const_cpuset_t set);
|
||||
|
||||
/** \brief Get the current binding of thread \p tid
|
||||
*
|
||||
* The CPU-set \p set (previously allocated by the caller)
|
||||
* is filled with the list of PUs which the thread
|
||||
* was last bound to.
|
||||
*
|
||||
* The behavior is exactly the same as the Linux sched_getaffinity system call,
|
||||
* but uses a hwloc cpuset.
|
||||
*
|
||||
* \note This is equivalent to calling hwloc_get_proc_cpubind() with
|
||||
* ::HWLOC_CPUBIND_THREAD as flags.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_linux_get_tid_cpubind(hwloc_topology_t topology, pid_t tid, hwloc_cpuset_t set);
|
||||
|
||||
/** \brief Get the last physical CPU where thread \p tid ran.
|
||||
*
|
||||
* The CPU-set \p set (previously allocated by the caller)
|
||||
* is filled with the PU which the thread last ran on.
|
||||
*
|
||||
* \note This is equivalent to calling hwloc_get_proc_last_cpu_location() with
|
||||
* ::HWLOC_CPUBIND_THREAD as flags.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_linux_get_tid_last_cpu_location(hwloc_topology_t topology, pid_t tid, hwloc_bitmap_t set);
|
||||
|
||||
/** \brief Convert a linux kernel cpumask file \p path into a hwloc bitmap \p set.
|
||||
*
|
||||
* Might be used when reading CPU set from sysfs attributes such as topology
|
||||
* and caches for processors, or local_cpus for devices.
|
||||
*
|
||||
* \note This function ignores the HWLOC_FSROOT environment variable.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_linux_read_path_as_cpumask(const char *path, hwloc_bitmap_t set);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_LINUX_H */
|
||||
455
src/3rdparty/hwloc/include/hwloc/memattrs.h
vendored
455
src/3rdparty/hwloc/include/hwloc/memattrs.h
vendored
@@ -1,455 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019-2022 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 referring 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 referring 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 *nr, 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 */
|
||||
181
src/3rdparty/hwloc/include/hwloc/nvml.h
vendored
181
src/3rdparty/hwloc/include/hwloc/nvml.h
vendored
@@ -1,181 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012-2021 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Macros to help interaction between hwloc and the NVIDIA Management Library.
|
||||
*
|
||||
* Applications that use both hwloc and the NVIDIA Management Library may want to
|
||||
* include this file so as to get topology information for NVML devices.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_NVML_H
|
||||
#define HWLOC_NVML_H
|
||||
|
||||
#include "hwloc.h"
|
||||
#include "hwloc/autogen/config.h"
|
||||
#include "hwloc/helper.h"
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
#include "hwloc/linux.h"
|
||||
#endif
|
||||
|
||||
#include <nvml.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup hwlocality_nvml Interoperability with the NVIDIA Management Library
|
||||
*
|
||||
* This interface offers ways to retrieve topology information about
|
||||
* devices managed by the NVIDIA Management Library (NVML).
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Get the CPU set of processors that are physically
|
||||
* close to NVML device \p device.
|
||||
*
|
||||
* Store in \p set the CPU-set describing the locality of the NVML device \p device.
|
||||
*
|
||||
* Topology \p topology and device \p device must match the local machine.
|
||||
* I/O devices detection and the NVML component are not needed in the topology.
|
||||
*
|
||||
* The function only returns the locality of the device.
|
||||
* If more information about the device is needed, OS objects should
|
||||
* be used instead, see hwloc_nvml_get_device_osdev()
|
||||
* and hwloc_nvml_get_device_osdev_by_index().
|
||||
*
|
||||
* This function is currently only implemented in a meaningful way for
|
||||
* Linux; other systems will simply get a full cpuset.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_nvml_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
|
||||
nvmlDevice_t device, hwloc_cpuset_t set)
|
||||
{
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
|
||||
#define HWLOC_NVML_DEVICE_SYSFS_PATH_MAX 128
|
||||
char path[HWLOC_NVML_DEVICE_SYSFS_PATH_MAX];
|
||||
nvmlReturn_t nvres;
|
||||
nvmlPciInfo_t pci;
|
||||
|
||||
if (!hwloc_topology_is_thissystem(topology)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
nvres = nvmlDeviceGetPciInfo(device, &pci);
|
||||
if (NVML_SUCCESS != nvres) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", pci.domain, pci.bus, pci.device);
|
||||
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|
||||
|| hwloc_bitmap_iszero(set))
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
#else
|
||||
/* Non-Linux systems simply get a full cpuset */
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Get the hwloc OS device object corresponding to the
|
||||
* NVML device whose index is \p idx.
|
||||
*
|
||||
* \return The hwloc OS device object describing the NVML device whose index is \p idx.
|
||||
* \return \c NULL if none could be found.
|
||||
*
|
||||
* The topology \p topology does not necessarily have to match the current
|
||||
* machine. For instance the topology may be an XML import of a remote host.
|
||||
* I/O devices detection and the NVML component must be enabled in the topology.
|
||||
*
|
||||
* \note The corresponding PCI device object can be obtained by looking
|
||||
* at the OS device parent object (unless PCI devices are filtered out).
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_nvml_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
|
||||
{
|
||||
hwloc_obj_t osdev = NULL;
|
||||
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
|
||||
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
|
||||
&& osdev->name
|
||||
&& !strncmp("nvml", osdev->name, 4)
|
||||
&& atoi(osdev->name + 4) == (int) idx)
|
||||
return osdev;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** \brief Get the hwloc OS device object corresponding to NVML device \p device.
|
||||
*
|
||||
* \return The hwloc OS device object that describes the given NVML device \p device.
|
||||
* \return \c NULL if none could be found.
|
||||
*
|
||||
* Topology \p topology and device \p device must match the local machine.
|
||||
* I/O devices detection and the NVML component must be enabled in the topology.
|
||||
* If not, the locality of the object may still be found using
|
||||
* hwloc_nvml_get_device_cpuset().
|
||||
*
|
||||
* \note The corresponding hwloc PCI device may be found by looking
|
||||
* at the result parent pointer (unless PCI devices are filtered out).
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_nvml_get_device_osdev(hwloc_topology_t topology, nvmlDevice_t device)
|
||||
{
|
||||
hwloc_obj_t osdev;
|
||||
nvmlReturn_t nvres;
|
||||
nvmlPciInfo_t pci;
|
||||
char uuid[64];
|
||||
|
||||
if (!hwloc_topology_is_thissystem(topology)) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nvres = nvmlDeviceGetPciInfo(device, &pci);
|
||||
if (NVML_SUCCESS != nvres)
|
||||
return NULL;
|
||||
|
||||
nvres = nvmlDeviceGetUUID(device, uuid, sizeof(uuid));
|
||||
if (NVML_SUCCESS != nvres)
|
||||
uuid[0] = '\0';
|
||||
|
||||
osdev = NULL;
|
||||
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
|
||||
hwloc_obj_t pcidev = osdev->parent;
|
||||
const char *info;
|
||||
|
||||
if (strncmp(osdev->name, "nvml", 4))
|
||||
continue;
|
||||
|
||||
if (pcidev
|
||||
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
|
||||
&& pcidev->attr->pcidev.domain == pci.domain
|
||||
&& pcidev->attr->pcidev.bus == pci.bus
|
||||
&& pcidev->attr->pcidev.dev == pci.device
|
||||
&& pcidev->attr->pcidev.func == 0)
|
||||
return osdev;
|
||||
|
||||
info = hwloc_obj_get_info_by_name(osdev, "NVIDIAUUID");
|
||||
if (info && !strcmp(info, uuid))
|
||||
return osdev;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_NVML_H */
|
||||
252
src/3rdparty/hwloc/include/hwloc/opencl.h
vendored
252
src/3rdparty/hwloc/include/hwloc/opencl.h
vendored
@@ -1,252 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012-2021 Inria. All rights reserved.
|
||||
* Copyright © 2013, 2018 Université Bordeaux. All right reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Macros to help interaction between hwloc and the OpenCL interface.
|
||||
*
|
||||
* Applications that use both hwloc and OpenCL may want to
|
||||
* include this file so as to get topology information for OpenCL devices.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_OPENCL_H
|
||||
#define HWLOC_OPENCL_H
|
||||
|
||||
#include "hwloc.h"
|
||||
#include "hwloc/autogen/config.h"
|
||||
#include "hwloc/helper.h"
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
#include "hwloc/linux.h"
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/cl.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* OpenCL extensions aren't always shipped with default headers, and
|
||||
* they don't always reflect what the installed implementations support.
|
||||
* Try everything and let the implementation return errors when non supported.
|
||||
*/
|
||||
/* Copyright (c) 2008-2018 The Khronos Group Inc. */
|
||||
|
||||
/* needs "cl_amd_device_attribute_query" device extension, but not strictly required for clGetDeviceInfo() */
|
||||
#define HWLOC_CL_DEVICE_TOPOLOGY_AMD 0x4037
|
||||
typedef union {
|
||||
struct { cl_uint type; cl_uint data[5]; } raw;
|
||||
struct { cl_uint type; cl_char unused[17]; cl_char bus; cl_char device; cl_char function; } pcie;
|
||||
} hwloc_cl_device_topology_amd;
|
||||
#define HWLOC_CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD 1
|
||||
|
||||
/* needs "cl_nv_device_attribute_query" device extension, but not strictly required for clGetDeviceInfo() */
|
||||
#define HWLOC_CL_DEVICE_PCI_BUS_ID_NV 0x4008
|
||||
#define HWLOC_CL_DEVICE_PCI_SLOT_ID_NV 0x4009
|
||||
#define HWLOC_CL_DEVICE_PCI_DOMAIN_ID_NV 0x400A
|
||||
|
||||
|
||||
/** \defgroup hwlocality_opencl Interoperability with OpenCL
|
||||
*
|
||||
* This interface offers ways to retrieve topology information about
|
||||
* OpenCL devices.
|
||||
*
|
||||
* Only AMD and NVIDIA OpenCL implementations currently offer useful locality
|
||||
* information about their devices.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Return the domain, bus and device IDs of the OpenCL device \p device.
|
||||
*
|
||||
* Device \p device must match the local machine.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_opencl_get_device_pci_busid(cl_device_id device,
|
||||
unsigned *domain, unsigned *bus, unsigned *dev, unsigned *func)
|
||||
{
|
||||
hwloc_cl_device_topology_amd amdtopo;
|
||||
cl_uint nvbus, nvslot, nvdomain;
|
||||
cl_int clret;
|
||||
|
||||
clret = clGetDeviceInfo(device, HWLOC_CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL);
|
||||
if (CL_SUCCESS == clret
|
||||
&& HWLOC_CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD == amdtopo.raw.type) {
|
||||
*domain = 0; /* can't do anything better */
|
||||
/* cl_device_topology_amd stores bus ID in cl_char, dont convert those signed char directly to unsigned int */
|
||||
*bus = (unsigned) (unsigned char) amdtopo.pcie.bus;
|
||||
*dev = (unsigned) (unsigned char) amdtopo.pcie.device;
|
||||
*func = (unsigned) (unsigned char) amdtopo.pcie.function;
|
||||
return 0;
|
||||
}
|
||||
|
||||
clret = clGetDeviceInfo(device, HWLOC_CL_DEVICE_PCI_BUS_ID_NV, sizeof(nvbus), &nvbus, NULL);
|
||||
if (CL_SUCCESS == clret) {
|
||||
clret = clGetDeviceInfo(device, HWLOC_CL_DEVICE_PCI_SLOT_ID_NV, sizeof(nvslot), &nvslot, NULL);
|
||||
if (CL_SUCCESS == clret) {
|
||||
clret = clGetDeviceInfo(device, HWLOC_CL_DEVICE_PCI_DOMAIN_ID_NV, sizeof(nvdomain), &nvdomain, NULL);
|
||||
if (CL_SUCCESS == clret) { /* available since CUDA 10.2 */
|
||||
*domain = nvdomain;
|
||||
} else {
|
||||
*domain = 0;
|
||||
}
|
||||
*bus = nvbus & 0xff;
|
||||
/* non-documented but used in many other projects */
|
||||
*dev = nvslot >> 3;
|
||||
*func = nvslot & 0x7;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** \brief Get the CPU set of processors that are physically
|
||||
* close to OpenCL device \p device.
|
||||
*
|
||||
* Store in \p set the CPU-set describing the locality of the OpenCL device \p device.
|
||||
*
|
||||
* Topology \p topology and device \p device must match the local machine.
|
||||
* I/O devices detection and the OpenCL component are not needed in the topology.
|
||||
*
|
||||
* The function only returns the locality of the device.
|
||||
* If more information about the device is needed, OS objects should
|
||||
* be used instead, see hwloc_opencl_get_device_osdev()
|
||||
* and hwloc_opencl_get_device_osdev_by_index().
|
||||
*
|
||||
* This function is currently only implemented in a meaningful way for
|
||||
* Linux with the AMD or NVIDIA OpenCL implementation; other systems will simply
|
||||
* get a full cpuset.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_opencl_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
|
||||
cl_device_id device __hwloc_attribute_unused,
|
||||
hwloc_cpuset_t set)
|
||||
{
|
||||
#if (defined HWLOC_LINUX_SYS)
|
||||
/* If we're on Linux, try AMD/NVIDIA extensions + the sysfs mechanism to get the local cpus */
|
||||
#define HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX 128
|
||||
char path[HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX];
|
||||
unsigned pcidomain, pcibus, pcidev, pcifunc;
|
||||
|
||||
if (!hwloc_topology_is_thissystem(topology)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hwloc_opencl_get_device_pci_busid(device, &pcidomain, &pcibus, &pcidev, &pcifunc) < 0) {
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
return 0;
|
||||
}
|
||||
|
||||
sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/local_cpus", pcidomain, pcibus, pcidev, pcifunc);
|
||||
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|
||||
|| hwloc_bitmap_iszero(set))
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
#else
|
||||
/* Non-Linux systems simply get a full cpuset */
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Get the hwloc OS device object corresponding to the
|
||||
* OpenCL device for the given indexes.
|
||||
*
|
||||
* \return The hwloc OS device object describing the OpenCL device
|
||||
* whose platform index is \p platform_index,
|
||||
* and whose device index within this platform if \p device_index.
|
||||
* \return \c NULL if there is none.
|
||||
*
|
||||
* The topology \p topology does not necessarily have to match the current
|
||||
* machine. For instance the topology may be an XML import of a remote host.
|
||||
* I/O devices detection and the OpenCL component must be enabled in the topology.
|
||||
*
|
||||
* \note The corresponding PCI device object can be obtained by looking
|
||||
* at the OS device parent object (unless PCI devices are filtered out).
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_opencl_get_device_osdev_by_index(hwloc_topology_t topology,
|
||||
unsigned platform_index, unsigned device_index)
|
||||
{
|
||||
unsigned x = (unsigned) -1, y = (unsigned) -1;
|
||||
hwloc_obj_t osdev = NULL;
|
||||
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
|
||||
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
|
||||
&& osdev->name
|
||||
&& sscanf(osdev->name, "opencl%ud%u", &x, &y) == 2
|
||||
&& platform_index == x && device_index == y)
|
||||
return osdev;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** \brief Get the hwloc OS device object corresponding to OpenCL device \p deviceX.
|
||||
*
|
||||
* \return The hwloc OS device object corresponding to the given OpenCL device \p device.
|
||||
* \return \c NULL if none could be found, for instance
|
||||
* if required OpenCL attributes are not available.
|
||||
*
|
||||
* This function currently only works on AMD and NVIDIA OpenCL devices that support
|
||||
* relevant OpenCL extensions. hwloc_opencl_get_device_osdev_by_index()
|
||||
* should be preferred whenever possible, i.e. when platform and device index
|
||||
* are known.
|
||||
*
|
||||
* Topology \p topology and device \p device must match the local machine.
|
||||
* I/O devices detection and the OpenCL component must be enabled in the topology.
|
||||
* If not, the locality of the object may still be found using
|
||||
* hwloc_opencl_get_device_cpuset().
|
||||
*
|
||||
* \note This function cannot work if PCI devices are filtered out.
|
||||
*
|
||||
* \note The corresponding hwloc PCI device may be found by looking
|
||||
* at the result parent pointer (unless PCI devices are filtered out).
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_opencl_get_device_osdev(hwloc_topology_t topology __hwloc_attribute_unused,
|
||||
cl_device_id device __hwloc_attribute_unused)
|
||||
{
|
||||
hwloc_obj_t osdev;
|
||||
unsigned pcidomain, pcibus, pcidevice, pcifunc;
|
||||
|
||||
if (hwloc_opencl_get_device_pci_busid(device, &pcidomain, &pcibus, &pcidevice, &pcifunc) < 0) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
osdev = NULL;
|
||||
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
|
||||
hwloc_obj_t pcidev = osdev->parent;
|
||||
if (strncmp(osdev->name, "opencl", 6))
|
||||
continue;
|
||||
if (pcidev
|
||||
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
|
||||
&& pcidev->attr->pcidev.domain == pcidomain
|
||||
&& pcidev->attr->pcidev.bus == pcibus
|
||||
&& pcidev->attr->pcidev.dev == pcidevice
|
||||
&& pcidev->attr->pcidev.func == pcifunc)
|
||||
return osdev;
|
||||
/* if PCI are filtered out, we need a info attr to match on */
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_OPENCL_H */
|
||||
152
src/3rdparty/hwloc/include/hwloc/openfabrics-verbs.h
vendored
152
src/3rdparty/hwloc/include/hwloc/openfabrics-verbs.h
vendored
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2021 Inria. All rights reserved.
|
||||
* Copyright © 2009-2010 Université Bordeaux
|
||||
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Macros to help interaction between hwloc and OpenFabrics
|
||||
* verbs.
|
||||
*
|
||||
* Applications that use both hwloc and OpenFabrics verbs may want to
|
||||
* include this file so as to get topology information for OpenFabrics
|
||||
* hardware (InfiniBand, etc).
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_OPENFABRICS_VERBS_H
|
||||
#define HWLOC_OPENFABRICS_VERBS_H
|
||||
|
||||
#include "hwloc.h"
|
||||
#include "hwloc/autogen/config.h"
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
#include "hwloc/linux.h"
|
||||
#endif
|
||||
|
||||
#include <infiniband/verbs.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup hwlocality_openfabrics Interoperability with OpenFabrics
|
||||
*
|
||||
* This interface offers ways to retrieve topology information about
|
||||
* OpenFabrics devices (InfiniBand, Omni-Path, usNIC, etc).
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Get the CPU set of processors that are physically
|
||||
* close to device \p ibdev.
|
||||
*
|
||||
* Store in \p set the CPU-set describing the locality of the OpenFabrics
|
||||
* device \p ibdev (InfiniBand, etc).
|
||||
*
|
||||
* Topology \p topology and device \p ibdev must match the local machine.
|
||||
* I/O devices detection is not needed in the topology.
|
||||
*
|
||||
* The function only returns the locality of the device.
|
||||
* If more information about the device is needed, OS objects should
|
||||
* be used instead, see hwloc_ibv_get_device_osdev()
|
||||
* and hwloc_ibv_get_device_osdev_by_name().
|
||||
*
|
||||
* This function is currently only implemented in a meaningful way for
|
||||
* Linux; other systems will simply get a full cpuset.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_ibv_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
|
||||
struct ibv_device *ibdev, hwloc_cpuset_t set)
|
||||
{
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
/* If we're on Linux, use the verbs-provided sysfs mechanism to
|
||||
get the local cpus */
|
||||
#define HWLOC_OPENFABRICS_VERBS_SYSFS_PATH_MAX 128
|
||||
char path[HWLOC_OPENFABRICS_VERBS_SYSFS_PATH_MAX];
|
||||
|
||||
if (!hwloc_topology_is_thissystem(topology)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(path, "/sys/class/infiniband/%s/device/local_cpus",
|
||||
ibv_get_device_name(ibdev));
|
||||
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|
||||
|| hwloc_bitmap_iszero(set))
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
#else
|
||||
/* Non-Linux systems simply get a full cpuset */
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Get the hwloc OS device object corresponding to the OpenFabrics
|
||||
* device named \p ibname.
|
||||
*
|
||||
* \return The hwloc OS device object describing the OpenFabrics device
|
||||
* (InfiniBand, Omni-Path, usNIC, etc) whose name is \p ibname
|
||||
* (mlx5_0, hfi1_0, usnic_0, qib0, etc).
|
||||
* \return \c NULL if none could be found.
|
||||
*
|
||||
* The name \p ibname is usually obtained from ibv_get_device_name().
|
||||
*
|
||||
* The topology \p topology does not necessarily have to match the current
|
||||
* machine. For instance the topology may be an XML import of a remote host.
|
||||
* I/O devices detection must be enabled in the topology.
|
||||
*
|
||||
* \note The corresponding PCI device object can be obtained by looking
|
||||
* at the OS device parent object.
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_ibv_get_device_osdev_by_name(hwloc_topology_t topology,
|
||||
const char *ibname)
|
||||
{
|
||||
hwloc_obj_t osdev = NULL;
|
||||
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
|
||||
if (HWLOC_OBJ_OSDEV_OPENFABRICS == osdev->attr->osdev.type
|
||||
&& osdev->name && !strcmp(ibname, osdev->name))
|
||||
return osdev;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** \brief Get the hwloc OS device object corresponding to the OpenFabrics
|
||||
* device \p ibdev.
|
||||
*
|
||||
* \return The hwloc OS device object describing the OpenFabrics
|
||||
* device \p ibdev (InfiniBand, etc).
|
||||
* \return \c NULL if none could be found.
|
||||
*
|
||||
* Topology \p topology and device \p ibdev must match the local machine.
|
||||
* I/O devices detection must be enabled in the topology.
|
||||
* If not, the locality of the object may still be found using
|
||||
* hwloc_ibv_get_device_cpuset().
|
||||
*
|
||||
* \note The corresponding PCI device object can be obtained by looking
|
||||
* at the OS device parent object.
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_ibv_get_device_osdev(hwloc_topology_t topology,
|
||||
struct ibv_device *ibdev)
|
||||
{
|
||||
if (!hwloc_topology_is_thissystem(topology)) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
return hwloc_ibv_get_device_osdev_by_name(topology, ibv_get_device_name(ibdev));
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_OPENFABRICS_VERBS_H */
|
||||
689
src/3rdparty/hwloc/include/hwloc/plugins.h
vendored
689
src/3rdparty/hwloc/include/hwloc/plugins.h
vendored
@@ -1,689 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013-2021 Inria. All rights reserved.
|
||||
* Copyright © 2016 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_PLUGINS_H
|
||||
#define HWLOC_PLUGINS_H
|
||||
|
||||
/** \file
|
||||
* \brief Public interface for building hwloc plugins.
|
||||
*/
|
||||
|
||||
struct hwloc_backend;
|
||||
|
||||
#include "hwloc.h"
|
||||
|
||||
#ifdef HWLOC_INSIDE_PLUGIN
|
||||
/* needed for hwloc_plugin_check_namespace() */
|
||||
#ifdef HWLOC_HAVE_LTDL
|
||||
#include <ltdl.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/** \defgroup hwlocality_disc_components Components and Plugins: Discovery components
|
||||
*
|
||||
* \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Discovery component structure
|
||||
*
|
||||
* This is the major kind of components, taking care of the discovery.
|
||||
* They are registered by generic components, either statically-built or as plugins.
|
||||
*/
|
||||
struct hwloc_disc_component {
|
||||
/** \brief Name.
|
||||
* If this component is built as a plugin, this name does not have to match the plugin filename.
|
||||
*/
|
||||
const char *name;
|
||||
|
||||
/** \brief Discovery phases performed by this component.
|
||||
* OR'ed set of ::hwloc_disc_phase_t
|
||||
*/
|
||||
unsigned phases;
|
||||
|
||||
/** \brief Component phases to exclude, as an OR'ed set of ::hwloc_disc_phase_t.
|
||||
*
|
||||
* For a GLOBAL component, this usually includes all other phases (\c ~UL).
|
||||
*
|
||||
* Other components only exclude types that may bring conflicting
|
||||
* topology information. MISC components should likely not be excluded
|
||||
* since they usually bring non-primary additional information.
|
||||
*/
|
||||
unsigned excluded_phases;
|
||||
|
||||
/** \brief Instantiate callback to create a backend from the component.
|
||||
* Parameters data1, data2, data3 are NULL except for components
|
||||
* that have special enabling routines such as hwloc_topology_set_xml(). */
|
||||
struct hwloc_backend * (*instantiate)(struct hwloc_topology *topology, struct hwloc_disc_component *component, unsigned excluded_phases, const void *data1, const void *data2, const void *data3);
|
||||
|
||||
/** \brief Component priority.
|
||||
* Used to sort topology->components, higher priority first.
|
||||
* Also used to decide between two components with the same name.
|
||||
*
|
||||
* Usual values are
|
||||
* 50 for native OS (or platform) components,
|
||||
* 45 for x86,
|
||||
* 40 for no-OS fallback,
|
||||
* 30 for global components (xml, synthetic),
|
||||
* 20 for pci,
|
||||
* 10 for other misc components (opencl etc.).
|
||||
*/
|
||||
unsigned priority;
|
||||
|
||||
/** \brief Enabled by default.
|
||||
* If unset, if will be disabled unless explicitly requested.
|
||||
*/
|
||||
unsigned enabled_by_default;
|
||||
|
||||
/** \private Used internally to list components by priority on topology->components
|
||||
* (the component structure is usually read-only,
|
||||
* the core copies it before using this field for queueing)
|
||||
*/
|
||||
struct hwloc_disc_component * next;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
|
||||
/** \defgroup hwlocality_disc_backends Components and Plugins: Discovery backends
|
||||
*
|
||||
* \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Discovery phase */
|
||||
typedef enum hwloc_disc_phase_e {
|
||||
/** \brief xml or synthetic, platform-specific components such as bgq.
|
||||
* Discovers everything including CPU, memory, I/O and everything else.
|
||||
* A component with a Global phase usually excludes all other phases.
|
||||
* \hideinitializer */
|
||||
HWLOC_DISC_PHASE_GLOBAL = (1U<<0),
|
||||
|
||||
/** \brief CPU discovery.
|
||||
* \hideinitializer */
|
||||
HWLOC_DISC_PHASE_CPU = (1U<<1),
|
||||
|
||||
/** \brief Attach memory to existing CPU objects.
|
||||
* \hideinitializer */
|
||||
HWLOC_DISC_PHASE_MEMORY = (1U<<2),
|
||||
|
||||
/** \brief Attach PCI devices and bridges to existing CPU objects.
|
||||
* \hideinitializer */
|
||||
HWLOC_DISC_PHASE_PCI = (1U<<3),
|
||||
|
||||
/** \brief I/O discovery that requires PCI devices (OS devices such as OpenCL, CUDA, etc.).
|
||||
* \hideinitializer */
|
||||
HWLOC_DISC_PHASE_IO = (1U<<4),
|
||||
|
||||
/** \brief Misc objects that gets added below anything else.
|
||||
* \hideinitializer */
|
||||
HWLOC_DISC_PHASE_MISC = (1U<<5),
|
||||
|
||||
/** \brief Annotating existing objects, adding distances, etc.
|
||||
* \hideinitializer */
|
||||
HWLOC_DISC_PHASE_ANNOTATE = (1U<<6),
|
||||
|
||||
/** \brief Final tweaks to a ready-to-use topology.
|
||||
* This phase runs once the topology is loaded, before it is returned to the topology.
|
||||
* Hence it may only use the main hwloc API for modifying the topology,
|
||||
* for instance by restricting it, adding info attributes, etc.
|
||||
* \hideinitializer */
|
||||
HWLOC_DISC_PHASE_TWEAK = (1U<<7)
|
||||
} hwloc_disc_phase_t;
|
||||
|
||||
/** \brief Discovery status flags */
|
||||
enum hwloc_disc_status_flag_e {
|
||||
/** \brief The sets of allowed resources were already retrieved \hideinitializer */
|
||||
HWLOC_DISC_STATUS_FLAG_GOT_ALLOWED_RESOURCES = (1UL<<1)
|
||||
};
|
||||
|
||||
/** \brief Discovery status structure
|
||||
*
|
||||
* Used by the core and backends to inform about what has been/is being done
|
||||
* during the discovery process.
|
||||
*/
|
||||
struct hwloc_disc_status {
|
||||
/** \brief The current discovery phase that is performed.
|
||||
* Must match one of the phases in the component phases field.
|
||||
*/
|
||||
hwloc_disc_phase_t phase;
|
||||
|
||||
/** \brief Dynamically excluded phases.
|
||||
* If a component decides during discovery that some phases are no longer needed.
|
||||
*/
|
||||
unsigned excluded_phases;
|
||||
|
||||
/** \brief OR'ed set of hwloc_disc_status_flag_e */
|
||||
unsigned long flags;
|
||||
};
|
||||
|
||||
/** \brief Discovery backend structure
|
||||
*
|
||||
* A backend is the instantiation of a discovery component.
|
||||
* When a component gets enabled for a topology,
|
||||
* its instantiate() callback creates a backend.
|
||||
*
|
||||
* hwloc_backend_alloc() initializes all fields to default values
|
||||
* that the component may change (except "component" and "next")
|
||||
* before enabling the backend with hwloc_backend_enable().
|
||||
*
|
||||
* Most backends assume that the topology is_thissystem flag is
|
||||
* set because they talk to the underlying operating system.
|
||||
* However they may still be used in topologies without the
|
||||
* is_thissystem flag for debugging reasons.
|
||||
* In practice, they are usually auto-disabled in such cases
|
||||
* (excluded by xml or synthetic backends, or by environment
|
||||
* variables when changing the Linux fsroot or the x86 cpuid path).
|
||||
*/
|
||||
struct hwloc_backend {
|
||||
/** \private Reserved for the core, set by hwloc_backend_alloc() */
|
||||
struct hwloc_disc_component * component;
|
||||
/** \private Reserved for the core, set by hwloc_backend_enable() */
|
||||
struct hwloc_topology * topology;
|
||||
/** \private Reserved for the core. Set to 1 if forced through envvar, 0 otherwise. */
|
||||
int envvar_forced;
|
||||
/** \private Reserved for the core. Used internally to list backends topology->backends. */
|
||||
struct hwloc_backend * next;
|
||||
|
||||
/** \brief Discovery phases performed by this component, possibly without some of them if excluded by other components.
|
||||
* OR'ed set of ::hwloc_disc_phase_t
|
||||
*/
|
||||
unsigned phases;
|
||||
|
||||
/** \brief Backend flags, currently always 0. */
|
||||
unsigned long flags;
|
||||
|
||||
/** \brief Backend-specific 'is_thissystem' property.
|
||||
* Set to 0 if the backend disables the thissystem flag for this topology
|
||||
* (e.g. loading from xml or synthetic string,
|
||||
* or using a different fsroot on Linux, or a x86 CPUID dump).
|
||||
* Set to -1 if the backend doesn't care (default).
|
||||
*/
|
||||
int is_thissystem;
|
||||
|
||||
/** \brief Backend private data, or NULL if none. */
|
||||
void * private_data;
|
||||
/** \brief Callback for freeing the private_data.
|
||||
* May be NULL.
|
||||
*/
|
||||
void (*disable)(struct hwloc_backend *backend);
|
||||
|
||||
/** \brief Main discovery callback.
|
||||
* returns -1 on error, either because it couldn't add its objects ot the existing topology,
|
||||
* or because of an actual discovery/gathering failure.
|
||||
* May be NULL.
|
||||
*/
|
||||
int (*discover)(struct hwloc_backend *backend, struct hwloc_disc_status *status);
|
||||
|
||||
/** \brief Callback to retrieve the locality of a PCI object.
|
||||
* Called by the PCI core when attaching PCI hierarchy to CPU objects.
|
||||
* May be NULL.
|
||||
*/
|
||||
int (*get_pci_busid_cpuset)(struct hwloc_backend *backend, struct hwloc_pcidev_attr_s *busid, hwloc_bitmap_t cpuset);
|
||||
};
|
||||
|
||||
/** \brief Allocate a backend structure, set good default values, initialize backend->component and topology, etc.
|
||||
* The caller will then modify whatever needed, and call hwloc_backend_enable().
|
||||
*/
|
||||
HWLOC_DECLSPEC struct hwloc_backend * hwloc_backend_alloc(struct hwloc_topology *topology, struct hwloc_disc_component *component);
|
||||
|
||||
/** \brief Enable a previously allocated and setup backend. */
|
||||
HWLOC_DECLSPEC int hwloc_backend_enable(struct hwloc_backend *backend);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
|
||||
/** \defgroup hwlocality_generic_components Components and Plugins: Generic components
|
||||
*
|
||||
* \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Generic component type */
|
||||
typedef enum hwloc_component_type_e {
|
||||
/** \brief The data field must point to a struct hwloc_disc_component. */
|
||||
HWLOC_COMPONENT_TYPE_DISC,
|
||||
|
||||
/** \brief The data field must point to a struct hwloc_xml_component. */
|
||||
HWLOC_COMPONENT_TYPE_XML
|
||||
} hwloc_component_type_t;
|
||||
|
||||
/** \brief Generic component structure
|
||||
*
|
||||
* Generic components structure, either statically listed by configure in static-components.h
|
||||
* or dynamically loaded as a plugin.
|
||||
*/
|
||||
struct hwloc_component {
|
||||
/** \brief Component ABI version, set to ::HWLOC_COMPONENT_ABI */
|
||||
unsigned abi;
|
||||
|
||||
/** \brief Process-wide component initialization callback.
|
||||
*
|
||||
* This optional callback is called when the component is registered
|
||||
* to the hwloc core (after loading the plugin).
|
||||
*
|
||||
* When the component is built as a plugin, this callback
|
||||
* should call hwloc_check_plugin_namespace()
|
||||
* and return an negative error code on error.
|
||||
*
|
||||
* \p flags is always 0 for now.
|
||||
*
|
||||
* \return 0 on success, or a negative code on error.
|
||||
*
|
||||
* \note If the component uses ltdl for loading its own plugins,
|
||||
* it should load/unload them only in init() and finalize(),
|
||||
* to avoid race conditions with hwloc's use of ltdl.
|
||||
*/
|
||||
int (*init)(unsigned long flags);
|
||||
|
||||
/** \brief Process-wide component termination callback.
|
||||
*
|
||||
* This optional callback is called after unregistering the component
|
||||
* from the hwloc core (before unloading the plugin).
|
||||
*
|
||||
* \p flags is always 0 for now.
|
||||
*
|
||||
* \note If the component uses ltdl for loading its own plugins,
|
||||
* it should load/unload them only in init() and finalize(),
|
||||
* to avoid race conditions with hwloc's use of ltdl.
|
||||
*/
|
||||
void (*finalize)(unsigned long flags);
|
||||
|
||||
/** \brief Component type */
|
||||
hwloc_component_type_t type;
|
||||
|
||||
/** \brief Component flags, unused for now */
|
||||
unsigned long flags;
|
||||
|
||||
/** \brief Component data, pointing to a struct hwloc_disc_component or struct hwloc_xml_component. */
|
||||
void * data;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
|
||||
/** \defgroup hwlocality_components_core_funcs Components and Plugins: Core functions to be used by components
|
||||
*
|
||||
* \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Check whether error messages are hidden.
|
||||
*
|
||||
* Callers should print critical error messages
|
||||
* (e.g. invalid hw topo info, invalid config)
|
||||
* only if this function returns strictly less than 2.
|
||||
*
|
||||
* Callers should print non-critical error messages
|
||||
* (e.g. failure to initialize CUDA)
|
||||
* if this function returns 0.
|
||||
*
|
||||
* This function return 1 by default (show critical only),
|
||||
* 0 in lstopo (show all),
|
||||
* or anything set in HWLOC_HIDE_ERRORS in the environment.
|
||||
*/
|
||||
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
|
||||
* this object.
|
||||
*
|
||||
* If the cpuset is empty, the type of the object (and maybe some attributes)
|
||||
* must be enough to find where to insert the object. This is especially true
|
||||
* for NUMA nodes with memory and no CPUs.
|
||||
*
|
||||
* The given object should not have children.
|
||||
*
|
||||
* This shall only be called before levels are built.
|
||||
*
|
||||
* 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 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.
|
||||
*
|
||||
* It is added as the last child of the given parent.
|
||||
* The cpuset is completely ignored, so strange objects such as I/O devices should
|
||||
* preferably be inserted with this.
|
||||
*
|
||||
* When used for "normal" children with cpusets (when importing from XML
|
||||
* when duplicating a topology), the caller should make sure that:
|
||||
* - children are inserted in order,
|
||||
* - children cpusets do not intersect.
|
||||
*
|
||||
* The given object may have normal, I/O or Misc children, as long as they are in order as well.
|
||||
* These children must have valid parent and next_sibling pointers.
|
||||
*
|
||||
* The caller should check whether the object type is filtered-out before calling this function.
|
||||
*/
|
||||
HWLOC_DECLSPEC void hwloc_insert_object_by_parent(struct hwloc_topology *topology, hwloc_obj_t parent, hwloc_obj_t obj);
|
||||
|
||||
/** \brief Allocate and initialize an object of the given type and physical index.
|
||||
*
|
||||
* If \p os_index is unknown or irrelevant, use \c HWLOC_UNKNOWN_INDEX.
|
||||
*/
|
||||
HWLOC_DECLSPEC hwloc_obj_t hwloc_alloc_setup_object(hwloc_topology_t topology, hwloc_obj_type_t type, unsigned os_index);
|
||||
|
||||
/** \brief Setup object cpusets/nodesets by OR'ing its children.
|
||||
*
|
||||
* Used when adding an object late in the topology.
|
||||
* Will update the new object by OR'ing all its new children sets.
|
||||
*
|
||||
* Used when PCI backend adds a hostbridge parent, when distances
|
||||
* add a new Group, etc.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_obj_add_children_sets(hwloc_obj_t obj);
|
||||
|
||||
/** \brief Request a reconnection of children and levels in the topology.
|
||||
*
|
||||
* May be used by backends during discovery if they need arrays or lists
|
||||
* of object within levels or children to be fully connected.
|
||||
*
|
||||
* \p flags is currently unused, must 0.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_topology_reconnect(hwloc_topology_t topology, unsigned long flags __hwloc_attribute_unused);
|
||||
|
||||
/** \brief Make sure that plugins can lookup core symbols.
|
||||
*
|
||||
* This is a sanity check to avoid lazy-lookup failures when libhwloc
|
||||
* is loaded within a plugin, and later tries to load its own plugins.
|
||||
* This may fail (and abort the program) if libhwloc symbols are in a
|
||||
* private namespace.
|
||||
*
|
||||
* \return 0 on success.
|
||||
* \return -1 if the plugin cannot be successfully loaded. The caller
|
||||
* plugin init() callback should return a negative error code as well.
|
||||
*
|
||||
* Plugins should call this function in their init() callback to avoid
|
||||
* later crashes if lazy symbol resolution is used by the upper layer that
|
||||
* loaded hwloc (e.g. OpenCL implementations using dlopen with RTLD_LAZY).
|
||||
*
|
||||
* \note The build system must define HWLOC_INSIDE_PLUGIN if and only if
|
||||
* building the caller as a plugin.
|
||||
*
|
||||
* \note This function should remain inline so plugins can call it even
|
||||
* when they cannot find libhwloc symbols.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_plugin_check_namespace(const char *pluginname __hwloc_attribute_unused, const char *symbol __hwloc_attribute_unused)
|
||||
{
|
||||
#ifdef HWLOC_INSIDE_PLUGIN
|
||||
void *sym;
|
||||
#ifdef HWLOC_HAVE_LTDL
|
||||
lt_dlhandle handle = lt_dlopen(NULL);
|
||||
#else
|
||||
void *handle = dlopen(NULL, RTLD_NOW|RTLD_LOCAL);
|
||||
#endif
|
||||
if (!handle)
|
||||
/* cannot check, assume things will work */
|
||||
return 0;
|
||||
#ifdef HWLOC_HAVE_LTDL
|
||||
sym = lt_dlsym(handle, symbol);
|
||||
lt_dlclose(handle);
|
||||
#else
|
||||
sym = dlsym(handle, symbol);
|
||||
dlclose(handle);
|
||||
#endif
|
||||
if (!sym) {
|
||||
static int verboseenv_checked = 0;
|
||||
static int verboseenv_value = 0;
|
||||
if (!verboseenv_checked) {
|
||||
const char *verboseenv = getenv("HWLOC_PLUGINS_VERBOSE");
|
||||
verboseenv_value = verboseenv ? atoi(verboseenv) : 0;
|
||||
verboseenv_checked = 1;
|
||||
}
|
||||
if (verboseenv_value)
|
||||
fprintf(stderr, "Plugin `%s' disabling itself because it cannot find the `%s' core symbol.\n",
|
||||
pluginname, symbol);
|
||||
return -1;
|
||||
}
|
||||
#endif /* HWLOC_INSIDE_PLUGIN */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
|
||||
/** \defgroup hwlocality_components_filtering Components and Plugins: Filtering objects
|
||||
*
|
||||
* \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Check whether the given PCI device classid is important.
|
||||
*
|
||||
* \return 1 if important, 0 otherwise.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_filter_check_pcidev_subtype_important(unsigned classid)
|
||||
{
|
||||
unsigned baseclass = classid >> 8;
|
||||
return (baseclass == 0x03 /* PCI_BASE_CLASS_DISPLAY */
|
||||
|| baseclass == 0x02 /* PCI_BASE_CLASS_NETWORK */
|
||||
|| baseclass == 0x01 /* PCI_BASE_CLASS_STORAGE */
|
||||
|| baseclass == 0x00 /* Unclassified, for Atos/Bull BXI */
|
||||
|| baseclass == 0x0b /* PCI_BASE_CLASS_PROCESSOR */
|
||||
|| classid == 0x0c04 /* PCI_CLASS_SERIAL_FIBER */
|
||||
|| classid == 0x0c06 /* PCI_CLASS_SERIAL_INFINIBAND */
|
||||
|| baseclass == 0x06 /* PCI_BASE_CLASS_BRIDGE with non-PCI downstream. the core will drop the useless ones later */
|
||||
|| baseclass == 0x12 /* Processing Accelerators */);
|
||||
}
|
||||
|
||||
/** \brief Check whether the given OS device subtype is important.
|
||||
*
|
||||
* \return 1 if important, 0 otherwise.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_filter_check_osdev_subtype_important(hwloc_obj_osdev_type_t subtype)
|
||||
{
|
||||
return (subtype != HWLOC_OBJ_OSDEV_DMA);
|
||||
}
|
||||
|
||||
/** \brief Check whether a non-I/O object type should be filtered-out.
|
||||
*
|
||||
* Cannot be used for I/O objects.
|
||||
*
|
||||
* \return 1 if the object type should be kept, 0 otherwise.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_filter_check_keep_object_type(hwloc_topology_t topology, hwloc_obj_type_t type)
|
||||
{
|
||||
enum hwloc_type_filter_e filter = HWLOC_TYPE_FILTER_KEEP_NONE;
|
||||
hwloc_topology_get_type_filter(topology, type, &filter);
|
||||
assert(filter != HWLOC_TYPE_FILTER_KEEP_IMPORTANT); /* IMPORTANT only used for I/O */
|
||||
return filter == HWLOC_TYPE_FILTER_KEEP_NONE ? 0 : 1;
|
||||
}
|
||||
|
||||
/** \brief Check whether the given object should be filtered-out.
|
||||
*
|
||||
* \return 1 if the object type should be kept, 0 otherwise.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_filter_check_keep_object(hwloc_topology_t topology, hwloc_obj_t obj)
|
||||
{
|
||||
hwloc_obj_type_t type = obj->type;
|
||||
enum hwloc_type_filter_e filter = HWLOC_TYPE_FILTER_KEEP_NONE;
|
||||
hwloc_topology_get_type_filter(topology, type, &filter);
|
||||
if (filter == HWLOC_TYPE_FILTER_KEEP_NONE)
|
||||
return 0;
|
||||
if (filter == HWLOC_TYPE_FILTER_KEEP_IMPORTANT) {
|
||||
if (type == HWLOC_OBJ_PCI_DEVICE)
|
||||
return hwloc_filter_check_pcidev_subtype_important(obj->attr->pcidev.class_id);
|
||||
if (type == HWLOC_OBJ_OS_DEVICE)
|
||||
return hwloc_filter_check_osdev_subtype_important(obj->attr->osdev.type);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
|
||||
/** \defgroup hwlocality_components_pcidisc Components and Plugins: helpers for PCI discovery
|
||||
*
|
||||
* \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Return the offset of the given capability in the PCI config space buffer
|
||||
*
|
||||
* This function requires a 256-bytes config space. Unknown/unavailable bytes should be set to 0xff.
|
||||
*/
|
||||
HWLOC_DECLSPEC unsigned hwloc_pcidisc_find_cap(const unsigned char *config, unsigned cap);
|
||||
|
||||
/** \brief Fill linkspeed by reading the PCI config space where PCI_CAP_ID_EXP is at position offset.
|
||||
*
|
||||
* Needs 20 bytes of EXP capability block starting at offset in the config space
|
||||
* for registers up to link status.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_pcidisc_find_linkspeed(const unsigned char *config, unsigned offset, float *linkspeed);
|
||||
|
||||
/** \brief Return the hwloc object type (PCI device or Bridge) for the given class and configuration space.
|
||||
*
|
||||
* This function requires 16 bytes of common configuration header at the beginning of config.
|
||||
*/
|
||||
HWLOC_DECLSPEC hwloc_obj_type_t hwloc_pcidisc_check_bridge_type(unsigned device_class, const unsigned char *config);
|
||||
|
||||
/** \brief Fills the attributes of the given PCI bridge using the given PCI config space.
|
||||
*
|
||||
* This function requires 32 bytes of common configuration header at the beginning of config.
|
||||
*
|
||||
* Returns -1 and destroys /p obj if bridge fields are invalid.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_pcidisc_find_bridge_buses(unsigned domain, unsigned bus, unsigned dev, unsigned func,
|
||||
unsigned *secondary_busp, unsigned *subordinate_busp,
|
||||
const unsigned char *config);
|
||||
|
||||
/** \brief Insert a PCI object in the given PCI tree by looking at PCI bus IDs.
|
||||
*
|
||||
* If \p treep points to \c NULL, the new object is inserted there.
|
||||
*/
|
||||
HWLOC_DECLSPEC void hwloc_pcidisc_tree_insert_by_busid(struct hwloc_obj **treep, struct hwloc_obj *obj);
|
||||
|
||||
/** \brief Add some hostbridges on top of the given tree of PCI objects and attach them to the topology.
|
||||
*
|
||||
* Other backends may lookup PCI objects or localities (for instance to attach OS devices)
|
||||
* by using hwloc_pcidisc_find_by_busid() or hwloc_pcidisc_find_busid_parent().
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_pcidisc_tree_attach(struct hwloc_topology *topology, struct hwloc_obj *tree);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
|
||||
/** \defgroup hwlocality_components_pcifind Components and Plugins: finding PCI objects during other discoveries
|
||||
*
|
||||
* \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Find the object or a parent of a PCI bus ID.
|
||||
*
|
||||
* When attaching a new object (typically an OS device) whose locality
|
||||
* is specified by PCI bus ID, this function returns the PCI object
|
||||
* to use as a parent for attaching.
|
||||
*
|
||||
* If the exact PCI device with this bus ID exists, it is returned.
|
||||
* Otherwise (for instance if it was filtered out), the function returns
|
||||
* another object with similar locality (for instance a parent bridge,
|
||||
* or the local CPU Package).
|
||||
*/
|
||||
HWLOC_DECLSPEC struct hwloc_obj * hwloc_pci_find_parent_by_busid(struct hwloc_topology *topology, unsigned domain, unsigned bus, unsigned dev, unsigned func);
|
||||
|
||||
/** \brief Find the PCI device or bridge matching a PCI bus ID exactly.
|
||||
*
|
||||
* This is useful for adding specific information about some objects
|
||||
* based on their PCI id. When it comes to attaching objects based on
|
||||
* PCI locality, hwloc_pci_find_parent_by_busid() should be preferred.
|
||||
*/
|
||||
HWLOC_DECLSPEC struct hwloc_obj * hwloc_pci_find_by_busid(struct hwloc_topology *topology, unsigned domain, unsigned bus, unsigned dev, unsigned func);
|
||||
|
||||
/** \brief Handle to a new distances structure during its addition to the topology. */
|
||||
typedef void * hwloc_backend_distances_add_handle_t;
|
||||
|
||||
/** \brief Create a new empty distances structure.
|
||||
*
|
||||
* This is identical to hwloc_distances_add_create()
|
||||
* but this variant is designed for backend inserting
|
||||
* distances during topology discovery.
|
||||
*/
|
||||
HWLOC_DECLSPEC hwloc_backend_distances_add_handle_t
|
||||
hwloc_backend_distances_add_create(hwloc_topology_t topology,
|
||||
const char *name, unsigned long kind,
|
||||
unsigned long flags);
|
||||
|
||||
/** \brief Specify the objects and values in a new empty distances structure.
|
||||
*
|
||||
* This is similar to hwloc_distances_add_values()
|
||||
* but this variant is designed for backend inserting
|
||||
* distances during topology discovery.
|
||||
*
|
||||
* The only semantical difference is that \p objs and \p values
|
||||
* are not duplicated, but directly attached to the topology.
|
||||
* On success, these arrays are given to the core and should not
|
||||
* ever be freed by the caller anymore.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_backend_distances_add_values(hwloc_topology_t topology,
|
||||
hwloc_backend_distances_add_handle_t handle,
|
||||
unsigned nbobjs, hwloc_obj_t *objs,
|
||||
hwloc_uint64_t *values,
|
||||
unsigned long flags);
|
||||
|
||||
/** \brief Commit a new distances structure.
|
||||
*
|
||||
* This is similar to hwloc_distances_add_commit()
|
||||
* but this variant is designed for backend inserting
|
||||
* distances during topology discovery.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_backend_distances_add_commit(hwloc_topology_t topology,
|
||||
hwloc_backend_distances_add_handle_t handle,
|
||||
unsigned long flags);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* HWLOC_PLUGINS_H */
|
||||
901
src/3rdparty/hwloc/include/hwloc/rename.h
vendored
901
src/3rdparty/hwloc/include/hwloc/rename.h
vendored
@@ -1,901 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright © 2010-2021 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_RENAME_H
|
||||
#define HWLOC_RENAME_H
|
||||
|
||||
#include "hwloc/autogen/config.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Only enact these defines if we're actually renaming the symbols
|
||||
(i.e., avoid trying to have no-op defines if we're *not*
|
||||
renaming). */
|
||||
|
||||
#if HWLOC_SYM_TRANSFORM
|
||||
|
||||
/* Use a preprocessor two-step in order to get the prefixing right.
|
||||
Make 2 macros: HWLOC_NAME and HWLOC_NAME_CAPS for renaming
|
||||
things. */
|
||||
|
||||
#define HWLOC_MUNGE_NAME(a, b) HWLOC_MUNGE_NAME2(a, b)
|
||||
#define HWLOC_MUNGE_NAME2(a, b) a ## b
|
||||
#define HWLOC_NAME(name) HWLOC_MUNGE_NAME(HWLOC_SYM_PREFIX, hwloc_ ## name)
|
||||
/* FIXME: should be "HWLOC_ ## name" below, unchanged because it doesn't matter much and could break some embedders hacks */
|
||||
#define HWLOC_NAME_CAPS(name) HWLOC_MUNGE_NAME(HWLOC_SYM_PREFIX_CAPS, hwloc_ ## name)
|
||||
|
||||
/* Now define all the "real" names to be the prefixed names. This
|
||||
allows us to use the real names throughout the code base (i.e.,
|
||||
"hwloc_<foo>"); the preprocessor will adjust to have the prefixed
|
||||
name under the covers. */
|
||||
|
||||
/* Names from hwloc.h */
|
||||
|
||||
#define hwloc_get_api_version HWLOC_NAME(get_api_version)
|
||||
|
||||
#define hwloc_topology HWLOC_NAME(topology)
|
||||
#define hwloc_topology_t HWLOC_NAME(topology_t)
|
||||
|
||||
#define hwloc_cpuset_t HWLOC_NAME(cpuset_t)
|
||||
#define hwloc_const_cpuset_t HWLOC_NAME(const_cpuset_t)
|
||||
#define hwloc_nodeset_t HWLOC_NAME(nodeset_t)
|
||||
#define hwloc_const_nodeset_t HWLOC_NAME(const_nodeset_t)
|
||||
|
||||
#define HWLOC_OBJ_MACHINE HWLOC_NAME_CAPS(OBJ_MACHINE)
|
||||
#define HWLOC_OBJ_NUMANODE HWLOC_NAME_CAPS(OBJ_NUMANODE)
|
||||
#define HWLOC_OBJ_MEMCACHE HWLOC_NAME_CAPS(OBJ_MEMCACHE)
|
||||
#define HWLOC_OBJ_PACKAGE HWLOC_NAME_CAPS(OBJ_PACKAGE)
|
||||
#define HWLOC_OBJ_DIE HWLOC_NAME_CAPS(OBJ_DIE)
|
||||
#define HWLOC_OBJ_CORE HWLOC_NAME_CAPS(OBJ_CORE)
|
||||
#define HWLOC_OBJ_PU HWLOC_NAME_CAPS(OBJ_PU)
|
||||
#define HWLOC_OBJ_L1CACHE HWLOC_NAME_CAPS(OBJ_L1CACHE)
|
||||
#define HWLOC_OBJ_L2CACHE HWLOC_NAME_CAPS(OBJ_L2CACHE)
|
||||
#define HWLOC_OBJ_L3CACHE HWLOC_NAME_CAPS(OBJ_L3CACHE)
|
||||
#define HWLOC_OBJ_L4CACHE HWLOC_NAME_CAPS(OBJ_L4CACHE)
|
||||
#define HWLOC_OBJ_L5CACHE HWLOC_NAME_CAPS(OBJ_L5CACHE)
|
||||
#define HWLOC_OBJ_L1ICACHE HWLOC_NAME_CAPS(OBJ_L1ICACHE)
|
||||
#define HWLOC_OBJ_L2ICACHE HWLOC_NAME_CAPS(OBJ_L2ICACHE)
|
||||
#define HWLOC_OBJ_L3ICACHE HWLOC_NAME_CAPS(OBJ_L3ICACHE)
|
||||
#define HWLOC_OBJ_MISC HWLOC_NAME_CAPS(OBJ_MISC)
|
||||
#define HWLOC_OBJ_GROUP HWLOC_NAME_CAPS(OBJ_GROUP)
|
||||
#define HWLOC_OBJ_BRIDGE HWLOC_NAME_CAPS(OBJ_BRIDGE)
|
||||
#define HWLOC_OBJ_PCI_DEVICE HWLOC_NAME_CAPS(OBJ_PCI_DEVICE)
|
||||
#define HWLOC_OBJ_OS_DEVICE HWLOC_NAME_CAPS(OBJ_OS_DEVICE)
|
||||
#define HWLOC_OBJ_TYPE_MAX HWLOC_NAME_CAPS(OBJ_TYPE_MAX)
|
||||
#define hwloc_obj_type_t HWLOC_NAME(obj_type_t)
|
||||
|
||||
#define hwloc_obj_cache_type_e HWLOC_NAME(obj_cache_type_e)
|
||||
#define hwloc_obj_cache_type_t HWLOC_NAME(obj_cache_type_t)
|
||||
#define HWLOC_OBJ_CACHE_UNIFIED HWLOC_NAME_CAPS(OBJ_CACHE_UNIFIED)
|
||||
#define HWLOC_OBJ_CACHE_DATA HWLOC_NAME_CAPS(OBJ_CACHE_DATA)
|
||||
#define HWLOC_OBJ_CACHE_INSTRUCTION HWLOC_NAME_CAPS(OBJ_CACHE_INSTRUCTION)
|
||||
|
||||
#define hwloc_obj_bridge_type_e HWLOC_NAME(obj_bridge_type_e)
|
||||
#define hwloc_obj_bridge_type_t HWLOC_NAME(obj_bridge_type_t)
|
||||
#define HWLOC_OBJ_BRIDGE_HOST HWLOC_NAME_CAPS(OBJ_BRIDGE_HOST)
|
||||
#define HWLOC_OBJ_BRIDGE_PCI HWLOC_NAME_CAPS(OBJ_BRIDGE_PCI)
|
||||
|
||||
#define hwloc_obj_osdev_type_e HWLOC_NAME(obj_osdev_type_e)
|
||||
#define hwloc_obj_osdev_type_t HWLOC_NAME(obj_osdev_type_t)
|
||||
#define HWLOC_OBJ_OSDEV_BLOCK HWLOC_NAME_CAPS(OBJ_OSDEV_BLOCK)
|
||||
#define HWLOC_OBJ_OSDEV_GPU HWLOC_NAME_CAPS(OBJ_OSDEV_GPU)
|
||||
#define HWLOC_OBJ_OSDEV_NETWORK HWLOC_NAME_CAPS(OBJ_OSDEV_NETWORK)
|
||||
#define HWLOC_OBJ_OSDEV_OPENFABRICS HWLOC_NAME_CAPS(OBJ_OSDEV_OPENFABRICS)
|
||||
#define HWLOC_OBJ_OSDEV_DMA HWLOC_NAME_CAPS(OBJ_OSDEV_DMA)
|
||||
#define HWLOC_OBJ_OSDEV_COPROC HWLOC_NAME_CAPS(OBJ_OSDEV_COPROC)
|
||||
|
||||
#define hwloc_compare_types HWLOC_NAME(compare_types)
|
||||
|
||||
#define hwloc_obj HWLOC_NAME(obj)
|
||||
#define hwloc_obj_t HWLOC_NAME(obj_t)
|
||||
|
||||
#define hwloc_info_s HWLOC_NAME(info_s)
|
||||
|
||||
#define hwloc_obj_attr_u HWLOC_NAME(obj_attr_u)
|
||||
#define hwloc_numanode_attr_s HWLOC_NAME(numanode_attr_s)
|
||||
#define hwloc_memory_page_type_s HWLOC_NAME(memory_page_type_s)
|
||||
#define hwloc_cache_attr_s HWLOC_NAME(cache_attr_s)
|
||||
#define hwloc_group_attr_s HWLOC_NAME(group_attr_s)
|
||||
#define hwloc_pcidev_attr_s HWLOC_NAME(pcidev_attr_s)
|
||||
#define hwloc_bridge_attr_s HWLOC_NAME(bridge_attr_s)
|
||||
#define hwloc_osdev_attr_s HWLOC_NAME(osdev_attr_s)
|
||||
|
||||
#define hwloc_topology_init HWLOC_NAME(topology_init)
|
||||
#define hwloc_topology_load HWLOC_NAME(topology_load)
|
||||
#define hwloc_topology_destroy HWLOC_NAME(topology_destroy)
|
||||
#define hwloc_topology_dup HWLOC_NAME(topology_dup)
|
||||
#define hwloc_topology_abi_check HWLOC_NAME(topology_abi_check)
|
||||
#define hwloc_topology_check HWLOC_NAME(topology_check)
|
||||
|
||||
#define hwloc_topology_flags_e HWLOC_NAME(topology_flags_e)
|
||||
|
||||
#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_FLAG_RESTRICT_TO_CPUBINDING HWLOC_NAME_CAPS(TOPOLOGY_FLAG_RESTRICT_TO_CPUBINDING)
|
||||
#define HWLOC_TOPOLOGY_FLAG_RESTRICT_TO_MEMBINDING HWLOC_NAME_CAPS(TOPOLOGY_FLAG_RESTRICT_TO_MEMBINDING)
|
||||
#define HWLOC_TOPOLOGY_FLAG_DONT_CHANGE_BINDING HWLOC_NAME_CAPS(TOPOLOGY_FLAG_DONT_CHANGE_BINDING)
|
||||
|
||||
#define hwloc_topology_set_pid HWLOC_NAME(topology_set_pid)
|
||||
#define hwloc_topology_set_synthetic HWLOC_NAME(topology_set_synthetic)
|
||||
#define hwloc_topology_set_xml HWLOC_NAME(topology_set_xml)
|
||||
#define hwloc_topology_set_xmlbuffer HWLOC_NAME(topology_set_xmlbuffer)
|
||||
#define hwloc_topology_components_flag_e HWLOC_NAME(hwloc_topology_components_flag_e)
|
||||
#define HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST HWLOC_NAME_CAPS(TOPOLOGY_COMPONENTS_FLAG_BLACKLIST)
|
||||
#define hwloc_topology_set_components HWLOC_NAME(topology_set_components)
|
||||
|
||||
#define hwloc_topology_set_flags HWLOC_NAME(topology_set_flags)
|
||||
#define hwloc_topology_is_thissystem HWLOC_NAME(topology_is_thissystem)
|
||||
#define hwloc_topology_get_flags HWLOC_NAME(topology_get_flags)
|
||||
#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)
|
||||
|
||||
#define hwloc_type_filter_e HWLOC_NAME(type_filter_e)
|
||||
#define HWLOC_TYPE_FILTER_KEEP_ALL HWLOC_NAME_CAPS(TYPE_FILTER_KEEP_ALL)
|
||||
#define HWLOC_TYPE_FILTER_KEEP_NONE HWLOC_NAME_CAPS(TYPE_FILTER_KEEP_NONE)
|
||||
#define HWLOC_TYPE_FILTER_KEEP_STRUCTURE HWLOC_NAME_CAPS(TYPE_FILTER_KEEP_STRUCTURE)
|
||||
#define HWLOC_TYPE_FILTER_KEEP_IMPORTANT HWLOC_NAME_CAPS(TYPE_FILTER_KEEP_IMPORTANT)
|
||||
#define hwloc_topology_set_type_filter HWLOC_NAME(topology_set_type_filter)
|
||||
#define hwloc_topology_get_type_filter HWLOC_NAME(topology_get_type_filter)
|
||||
#define hwloc_topology_set_all_types_filter HWLOC_NAME(topology_set_all_types_filter)
|
||||
#define hwloc_topology_set_cache_types_filter HWLOC_NAME(topology_set_cache_types_filter)
|
||||
#define hwloc_topology_set_icache_types_filter HWLOC_NAME(topology_set_icache_types_filter)
|
||||
#define hwloc_topology_set_io_types_filter HWLOC_NAME(topology_set_io_types_filter)
|
||||
|
||||
#define hwloc_topology_set_userdata HWLOC_NAME(topology_set_userdata)
|
||||
#define hwloc_topology_get_userdata HWLOC_NAME(topology_get_userdata)
|
||||
|
||||
#define hwloc_restrict_flags_e HWLOC_NAME(restrict_flags_e)
|
||||
#define HWLOC_RESTRICT_FLAG_REMOVE_CPULESS HWLOC_NAME_CAPS(RESTRICT_FLAG_REMOVE_CPULESS)
|
||||
#define HWLOC_RESTRICT_FLAG_BYNODESET HWLOC_NAME_CAPS(RESTRICT_FLAG_BYNODESET)
|
||||
#define HWLOC_RESTRICT_FLAG_REMOVE_MEMLESS HWLOC_NAME_CAPS(RESTRICT_FLAG_REMOVE_MEMLESS)
|
||||
#define HWLOC_RESTRICT_FLAG_ADAPT_MISC HWLOC_NAME_CAPS(RESTRICT_FLAG_ADAPT_MISC)
|
||||
#define HWLOC_RESTRICT_FLAG_ADAPT_IO HWLOC_NAME_CAPS(RESTRICT_FLAG_ADAPT_IO)
|
||||
#define hwloc_topology_restrict HWLOC_NAME(topology_restrict)
|
||||
|
||||
#define hwloc_allow_flags_e HWLOC_NAME(allow_flags_e)
|
||||
#define HWLOC_ALLOW_FLAG_ALL HWLOC_NAME_CAPS(ALLOW_FLAG_ALL)
|
||||
#define HWLOC_ALLOW_FLAG_LOCAL_RESTRICTIONS HWLOC_NAME_CAPS(ALLOW_FLAG_LOCAL_RESTRICTIONS)
|
||||
#define HWLOC_ALLOW_FLAG_CUSTOM HWLOC_NAME_CAPS(ALLOW_FLAG_CUSTOM)
|
||||
#define hwloc_topology_allow HWLOC_NAME(topology_allow)
|
||||
|
||||
#define hwloc_topology_insert_misc_object HWLOC_NAME(topology_insert_misc_object)
|
||||
#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)
|
||||
#define hwloc_get_memory_parents_depth HWLOC_NAME(get_memory_parents_depth)
|
||||
|
||||
#define hwloc_get_type_depth_e HWLOC_NAME(get_type_depth_e)
|
||||
#define HWLOC_TYPE_DEPTH_UNKNOWN HWLOC_NAME_CAPS(TYPE_DEPTH_UNKNOWN)
|
||||
#define HWLOC_TYPE_DEPTH_MULTIPLE HWLOC_NAME_CAPS(TYPE_DEPTH_MULTIPLE)
|
||||
#define HWLOC_TYPE_DEPTH_BRIDGE HWLOC_NAME_CAPS(TYPE_DEPTH_BRIDGE)
|
||||
#define HWLOC_TYPE_DEPTH_PCI_DEVICE HWLOC_NAME_CAPS(TYPE_DEPTH_PCI_DEVICE)
|
||||
#define HWLOC_TYPE_DEPTH_OS_DEVICE HWLOC_NAME_CAPS(TYPE_DEPTH_OS_DEVICE)
|
||||
#define HWLOC_TYPE_DEPTH_MISC HWLOC_NAME_CAPS(TYPE_DEPTH_MISC)
|
||||
#define HWLOC_TYPE_DEPTH_NUMANODE HWLOC_NAME_CAPS(TYPE_DEPTH_NUMANODE)
|
||||
#define HWLOC_TYPE_DEPTH_MEMCACHE HWLOC_NAME_CAPS(TYPE_DEPTH_MEMCACHE)
|
||||
|
||||
#define hwloc_get_depth_type HWLOC_NAME(get_depth_type)
|
||||
#define hwloc_get_nbobjs_by_depth HWLOC_NAME(get_nbobjs_by_depth)
|
||||
#define hwloc_get_nbobjs_by_type HWLOC_NAME(get_nbobjs_by_type)
|
||||
|
||||
#define hwloc_get_obj_by_depth HWLOC_NAME(get_obj_by_depth )
|
||||
#define hwloc_get_obj_by_type HWLOC_NAME(get_obj_by_type )
|
||||
|
||||
#define hwloc_obj_type_string HWLOC_NAME(obj_type_string )
|
||||
#define hwloc_obj_type_snprintf HWLOC_NAME(obj_type_snprintf )
|
||||
#define hwloc_obj_attr_snprintf HWLOC_NAME(obj_attr_snprintf )
|
||||
#define hwloc_type_sscanf HWLOC_NAME(type_sscanf)
|
||||
#define hwloc_type_sscanf_as_depth HWLOC_NAME(type_sscanf_as_depth)
|
||||
|
||||
#define hwloc_obj_get_info_by_name HWLOC_NAME(obj_get_info_by_name)
|
||||
#define hwloc_obj_add_info HWLOC_NAME(obj_add_info)
|
||||
|
||||
#define HWLOC_CPUBIND_PROCESS HWLOC_NAME_CAPS(CPUBIND_PROCESS)
|
||||
#define HWLOC_CPUBIND_THREAD HWLOC_NAME_CAPS(CPUBIND_THREAD)
|
||||
#define HWLOC_CPUBIND_STRICT HWLOC_NAME_CAPS(CPUBIND_STRICT)
|
||||
#define HWLOC_CPUBIND_NOMEMBIND HWLOC_NAME_CAPS(CPUBIND_NOMEMBIND)
|
||||
|
||||
#define hwloc_cpubind_flags_t HWLOC_NAME(cpubind_flags_t)
|
||||
|
||||
#define hwloc_set_cpubind HWLOC_NAME(set_cpubind)
|
||||
#define hwloc_get_cpubind HWLOC_NAME(get_cpubind)
|
||||
#define hwloc_set_proc_cpubind HWLOC_NAME(set_proc_cpubind)
|
||||
#define hwloc_get_proc_cpubind HWLOC_NAME(get_proc_cpubind)
|
||||
#define hwloc_set_thread_cpubind HWLOC_NAME(set_thread_cpubind)
|
||||
#define hwloc_get_thread_cpubind HWLOC_NAME(get_thread_cpubind)
|
||||
|
||||
#define hwloc_get_last_cpu_location HWLOC_NAME(get_last_cpu_location)
|
||||
#define hwloc_get_proc_last_cpu_location HWLOC_NAME(get_proc_last_cpu_location)
|
||||
|
||||
#define HWLOC_MEMBIND_DEFAULT HWLOC_NAME_CAPS(MEMBIND_DEFAULT)
|
||||
#define HWLOC_MEMBIND_FIRSTTOUCH HWLOC_NAME_CAPS(MEMBIND_FIRSTTOUCH)
|
||||
#define HWLOC_MEMBIND_BIND HWLOC_NAME_CAPS(MEMBIND_BIND)
|
||||
#define HWLOC_MEMBIND_INTERLEAVE HWLOC_NAME_CAPS(MEMBIND_INTERLEAVE)
|
||||
#define HWLOC_MEMBIND_NEXTTOUCH HWLOC_NAME_CAPS(MEMBIND_NEXTTOUCH)
|
||||
#define HWLOC_MEMBIND_MIXED HWLOC_NAME_CAPS(MEMBIND_MIXED)
|
||||
|
||||
#define hwloc_membind_policy_t HWLOC_NAME(membind_policy_t)
|
||||
|
||||
#define HWLOC_MEMBIND_PROCESS HWLOC_NAME_CAPS(MEMBIND_PROCESS)
|
||||
#define HWLOC_MEMBIND_THREAD HWLOC_NAME_CAPS(MEMBIND_THREAD)
|
||||
#define HWLOC_MEMBIND_STRICT HWLOC_NAME_CAPS(MEMBIND_STRICT)
|
||||
#define HWLOC_MEMBIND_MIGRATE HWLOC_NAME_CAPS(MEMBIND_MIGRATE)
|
||||
#define HWLOC_MEMBIND_NOCPUBIND HWLOC_NAME_CAPS(MEMBIND_NOCPUBIND)
|
||||
#define HWLOC_MEMBIND_BYNODESET HWLOC_NAME_CAPS(MEMBIND_BYNODESET)
|
||||
|
||||
#define hwloc_membind_flags_t HWLOC_NAME(membind_flags_t)
|
||||
|
||||
#define hwloc_set_membind HWLOC_NAME(set_membind)
|
||||
#define hwloc_get_membind HWLOC_NAME(get_membind)
|
||||
#define hwloc_set_proc_membind HWLOC_NAME(set_proc_membind)
|
||||
#define hwloc_get_proc_membind HWLOC_NAME(get_proc_membind)
|
||||
#define hwloc_set_area_membind HWLOC_NAME(set_area_membind)
|
||||
#define hwloc_get_area_membind HWLOC_NAME(get_area_membind)
|
||||
#define hwloc_get_area_memlocation HWLOC_NAME(get_area_memlocation)
|
||||
#define hwloc_alloc_membind HWLOC_NAME(alloc_membind)
|
||||
#define hwloc_alloc HWLOC_NAME(alloc)
|
||||
#define hwloc_free HWLOC_NAME(free)
|
||||
|
||||
#define hwloc_get_non_io_ancestor_obj HWLOC_NAME(get_non_io_ancestor_obj)
|
||||
#define hwloc_get_next_pcidev HWLOC_NAME(get_next_pcidev)
|
||||
#define hwloc_get_pcidev_by_busid HWLOC_NAME(get_pcidev_by_busid)
|
||||
#define hwloc_get_pcidev_by_busidstring HWLOC_NAME(get_pcidev_by_busidstring)
|
||||
#define hwloc_get_next_osdev HWLOC_NAME(get_next_osdev)
|
||||
#define hwloc_get_next_bridge HWLOC_NAME(get_next_bridge)
|
||||
#define hwloc_bridge_covers_pcibus HWLOC_NAME(bridge_covers_pcibus)
|
||||
|
||||
/* hwloc/bitmap.h */
|
||||
|
||||
#define hwloc_bitmap_s HWLOC_NAME(bitmap_s)
|
||||
#define hwloc_bitmap_t HWLOC_NAME(bitmap_t)
|
||||
#define hwloc_const_bitmap_t HWLOC_NAME(const_bitmap_t)
|
||||
|
||||
#define hwloc_bitmap_alloc HWLOC_NAME(bitmap_alloc)
|
||||
#define hwloc_bitmap_alloc_full HWLOC_NAME(bitmap_alloc_full)
|
||||
#define hwloc_bitmap_free HWLOC_NAME(bitmap_free)
|
||||
#define hwloc_bitmap_dup HWLOC_NAME(bitmap_dup)
|
||||
#define hwloc_bitmap_copy HWLOC_NAME(bitmap_copy)
|
||||
#define hwloc_bitmap_snprintf HWLOC_NAME(bitmap_snprintf)
|
||||
#define hwloc_bitmap_asprintf HWLOC_NAME(bitmap_asprintf)
|
||||
#define hwloc_bitmap_sscanf HWLOC_NAME(bitmap_sscanf)
|
||||
#define hwloc_bitmap_list_snprintf HWLOC_NAME(bitmap_list_snprintf)
|
||||
#define hwloc_bitmap_list_asprintf HWLOC_NAME(bitmap_list_asprintf)
|
||||
#define hwloc_bitmap_list_sscanf HWLOC_NAME(bitmap_list_sscanf)
|
||||
#define hwloc_bitmap_taskset_snprintf HWLOC_NAME(bitmap_taskset_snprintf)
|
||||
#define hwloc_bitmap_taskset_asprintf HWLOC_NAME(bitmap_taskset_asprintf)
|
||||
#define hwloc_bitmap_taskset_sscanf HWLOC_NAME(bitmap_taskset_sscanf)
|
||||
#define hwloc_bitmap_zero HWLOC_NAME(bitmap_zero)
|
||||
#define hwloc_bitmap_fill HWLOC_NAME(bitmap_fill)
|
||||
#define hwloc_bitmap_from_ulong HWLOC_NAME(bitmap_from_ulong)
|
||||
#define hwloc_bitmap_from_ulongs HWLOC_NAME(bitmap_from_ulongs)
|
||||
#define hwloc_bitmap_from_ith_ulong HWLOC_NAME(bitmap_from_ith_ulong)
|
||||
#define hwloc_bitmap_to_ulong HWLOC_NAME(bitmap_to_ulong)
|
||||
#define hwloc_bitmap_to_ith_ulong HWLOC_NAME(bitmap_to_ith_ulong)
|
||||
#define hwloc_bitmap_to_ulongs HWLOC_NAME(bitmap_to_ulongs)
|
||||
#define hwloc_bitmap_nr_ulongs HWLOC_NAME(bitmap_nr_ulongs)
|
||||
#define hwloc_bitmap_only HWLOC_NAME(bitmap_only)
|
||||
#define hwloc_bitmap_allbut HWLOC_NAME(bitmap_allbut)
|
||||
#define hwloc_bitmap_set HWLOC_NAME(bitmap_set)
|
||||
#define hwloc_bitmap_set_range HWLOC_NAME(bitmap_set_range)
|
||||
#define hwloc_bitmap_set_ith_ulong HWLOC_NAME(bitmap_set_ith_ulong)
|
||||
#define hwloc_bitmap_clr HWLOC_NAME(bitmap_clr)
|
||||
#define hwloc_bitmap_clr_range HWLOC_NAME(bitmap_clr_range)
|
||||
#define hwloc_bitmap_isset HWLOC_NAME(bitmap_isset)
|
||||
#define hwloc_bitmap_iszero HWLOC_NAME(bitmap_iszero)
|
||||
#define hwloc_bitmap_isfull HWLOC_NAME(bitmap_isfull)
|
||||
#define hwloc_bitmap_isequal HWLOC_NAME(bitmap_isequal)
|
||||
#define hwloc_bitmap_intersects HWLOC_NAME(bitmap_intersects)
|
||||
#define hwloc_bitmap_isincluded HWLOC_NAME(bitmap_isincluded)
|
||||
#define hwloc_bitmap_or HWLOC_NAME(bitmap_or)
|
||||
#define hwloc_bitmap_and HWLOC_NAME(bitmap_and)
|
||||
#define hwloc_bitmap_andnot HWLOC_NAME(bitmap_andnot)
|
||||
#define hwloc_bitmap_xor HWLOC_NAME(bitmap_xor)
|
||||
#define hwloc_bitmap_not HWLOC_NAME(bitmap_not)
|
||||
#define hwloc_bitmap_first HWLOC_NAME(bitmap_first)
|
||||
#define hwloc_bitmap_last HWLOC_NAME(bitmap_last)
|
||||
#define hwloc_bitmap_next HWLOC_NAME(bitmap_next)
|
||||
#define hwloc_bitmap_first_unset HWLOC_NAME(bitmap_first_unset)
|
||||
#define hwloc_bitmap_last_unset HWLOC_NAME(bitmap_last_unset)
|
||||
#define hwloc_bitmap_next_unset HWLOC_NAME(bitmap_next_unset)
|
||||
#define hwloc_bitmap_singlify HWLOC_NAME(bitmap_singlify)
|
||||
#define hwloc_bitmap_compare_first HWLOC_NAME(bitmap_compare_first)
|
||||
#define hwloc_bitmap_compare HWLOC_NAME(bitmap_compare)
|
||||
#define hwloc_bitmap_weight HWLOC_NAME(bitmap_weight)
|
||||
|
||||
/* hwloc/helper.h */
|
||||
|
||||
#define hwloc_get_type_or_below_depth HWLOC_NAME(get_type_or_below_depth)
|
||||
#define hwloc_get_type_or_above_depth HWLOC_NAME(get_type_or_above_depth)
|
||||
#define hwloc_get_root_obj HWLOC_NAME(get_root_obj)
|
||||
#define hwloc_get_ancestor_obj_by_depth HWLOC_NAME(get_ancestor_obj_by_depth)
|
||||
#define hwloc_get_ancestor_obj_by_type HWLOC_NAME(get_ancestor_obj_by_type)
|
||||
#define hwloc_get_next_obj_by_depth HWLOC_NAME(get_next_obj_by_depth)
|
||||
#define hwloc_get_next_obj_by_type HWLOC_NAME(get_next_obj_by_type)
|
||||
#define hwloc_bitmap_singlify_per_core HWLOC_NAME(bitmap_singlify_by_core)
|
||||
#define hwloc_get_pu_obj_by_os_index HWLOC_NAME(get_pu_obj_by_os_index)
|
||||
#define hwloc_get_numanode_obj_by_os_index HWLOC_NAME(get_numanode_obj_by_os_index)
|
||||
#define hwloc_get_next_child HWLOC_NAME(get_next_child)
|
||||
#define hwloc_get_common_ancestor_obj HWLOC_NAME(get_common_ancestor_obj)
|
||||
#define hwloc_obj_is_in_subtree HWLOC_NAME(obj_is_in_subtree)
|
||||
#define hwloc_get_first_largest_obj_inside_cpuset HWLOC_NAME(get_first_largest_obj_inside_cpuset)
|
||||
#define hwloc_get_largest_objs_inside_cpuset HWLOC_NAME(get_largest_objs_inside_cpuset)
|
||||
#define hwloc_get_next_obj_inside_cpuset_by_depth HWLOC_NAME(get_next_obj_inside_cpuset_by_depth)
|
||||
#define hwloc_get_next_obj_inside_cpuset_by_type HWLOC_NAME(get_next_obj_inside_cpuset_by_type)
|
||||
#define hwloc_get_obj_inside_cpuset_by_depth HWLOC_NAME(get_obj_inside_cpuset_by_depth)
|
||||
#define hwloc_get_obj_inside_cpuset_by_type HWLOC_NAME(get_obj_inside_cpuset_by_type)
|
||||
#define hwloc_get_nbobjs_inside_cpuset_by_depth HWLOC_NAME(get_nbobjs_inside_cpuset_by_depth)
|
||||
#define hwloc_get_nbobjs_inside_cpuset_by_type HWLOC_NAME(get_nbobjs_inside_cpuset_by_type)
|
||||
#define hwloc_get_obj_index_inside_cpuset HWLOC_NAME(get_obj_index_inside_cpuset)
|
||||
#define hwloc_get_child_covering_cpuset HWLOC_NAME(get_child_covering_cpuset)
|
||||
#define hwloc_get_obj_covering_cpuset HWLOC_NAME(get_obj_covering_cpuset)
|
||||
#define hwloc_get_next_obj_covering_cpuset_by_depth HWLOC_NAME(get_next_obj_covering_cpuset_by_depth)
|
||||
#define hwloc_get_next_obj_covering_cpuset_by_type HWLOC_NAME(get_next_obj_covering_cpuset_by_type)
|
||||
#define hwloc_obj_type_is_normal HWLOC_NAME(obj_type_is_normal)
|
||||
#define hwloc_obj_type_is_memory HWLOC_NAME(obj_type_is_memory)
|
||||
#define hwloc_obj_type_is_io HWLOC_NAME(obj_type_is_io)
|
||||
#define hwloc_obj_type_is_cache HWLOC_NAME(obj_type_is_cache)
|
||||
#define hwloc_obj_type_is_dcache HWLOC_NAME(obj_type_is_dcache)
|
||||
#define hwloc_obj_type_is_icache HWLOC_NAME(obj_type_is_icache)
|
||||
#define hwloc_get_cache_type_depth HWLOC_NAME(get_cache_type_depth)
|
||||
#define hwloc_get_cache_covering_cpuset HWLOC_NAME(get_cache_covering_cpuset)
|
||||
#define hwloc_get_shared_cache_covering_obj HWLOC_NAME(get_shared_cache_covering_obj)
|
||||
#define hwloc_get_closest_objs HWLOC_NAME(get_closest_objs)
|
||||
#define hwloc_get_obj_below_by_type HWLOC_NAME(get_obj_below_by_type)
|
||||
#define hwloc_get_obj_below_array_by_type HWLOC_NAME(get_obj_below_array_by_type)
|
||||
#define hwloc_get_obj_with_same_locality HWLOC_NAME(get_obj_with_same_locality)
|
||||
#define hwloc_distrib_flags_e HWLOC_NAME(distrib_flags_e)
|
||||
#define HWLOC_DISTRIB_FLAG_REVERSE HWLOC_NAME_CAPS(DISTRIB_FLAG_REVERSE)
|
||||
#define hwloc_distrib HWLOC_NAME(distrib)
|
||||
#define hwloc_alloc_membind_policy HWLOC_NAME(alloc_membind_policy)
|
||||
#define hwloc_alloc_membind_policy_nodeset HWLOC_NAME(alloc_membind_policy_nodeset)
|
||||
#define hwloc_topology_get_complete_cpuset HWLOC_NAME(topology_get_complete_cpuset)
|
||||
#define hwloc_topology_get_topology_cpuset HWLOC_NAME(topology_get_topology_cpuset)
|
||||
#define hwloc_topology_get_allowed_cpuset HWLOC_NAME(topology_get_allowed_cpuset)
|
||||
#define hwloc_topology_get_complete_nodeset HWLOC_NAME(topology_get_complete_nodeset)
|
||||
#define hwloc_topology_get_topology_nodeset HWLOC_NAME(topology_get_topology_nodeset)
|
||||
#define hwloc_topology_get_allowed_nodeset HWLOC_NAME(topology_get_allowed_nodeset)
|
||||
#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)
|
||||
#define HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1 HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_XML_FLAG_V1)
|
||||
#define hwloc_topology_export_xml HWLOC_NAME(topology_export_xml)
|
||||
#define hwloc_topology_export_xmlbuffer HWLOC_NAME(topology_export_xmlbuffer)
|
||||
#define hwloc_free_xmlbuffer HWLOC_NAME(free_xmlbuffer)
|
||||
#define hwloc_topology_set_userdata_export_callback HWLOC_NAME(topology_set_userdata_export_callback)
|
||||
#define hwloc_export_obj_userdata HWLOC_NAME(export_obj_userdata)
|
||||
#define hwloc_export_obj_userdata_base64 HWLOC_NAME(export_obj_userdata_base64)
|
||||
#define hwloc_topology_set_userdata_import_callback HWLOC_NAME(topology_set_userdata_import_callback)
|
||||
|
||||
#define hwloc_topology_export_synthetic_flags_e HWLOC_NAME(topology_export_synthetic_flags_e)
|
||||
#define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES)
|
||||
#define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS)
|
||||
#define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_V1 HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_V1)
|
||||
#define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_IGNORE_MEMORY HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_IGNORE_MEMORY)
|
||||
#define hwloc_topology_export_synthetic HWLOC_NAME(topology_export_synthetic)
|
||||
|
||||
/* distances.h */
|
||||
|
||||
#define hwloc_distances_s HWLOC_NAME(distances_s)
|
||||
|
||||
#define hwloc_distances_kind_e HWLOC_NAME(distances_kind_e)
|
||||
#define HWLOC_DISTANCES_KIND_FROM_OS HWLOC_NAME_CAPS(DISTANCES_KIND_FROM_OS)
|
||||
#define HWLOC_DISTANCES_KIND_FROM_USER HWLOC_NAME_CAPS(DISTANCES_KIND_FROM_USER)
|
||||
#define HWLOC_DISTANCES_KIND_MEANS_LATENCY HWLOC_NAME_CAPS(DISTANCES_KIND_MEANS_LATENCY)
|
||||
#define HWLOC_DISTANCES_KIND_MEANS_BANDWIDTH HWLOC_NAME_CAPS(DISTANCES_KIND_MEANS_BANDWIDTH)
|
||||
#define HWLOC_DISTANCES_KIND_HETEROGENEOUS_TYPES HWLOC_NAME_CAPS(DISTANCES_KIND_HETEROGENEOUS_TYPES)
|
||||
|
||||
#define hwloc_distances_get HWLOC_NAME(distances_get)
|
||||
#define hwloc_distances_get_by_depth HWLOC_NAME(distances_get_by_depth)
|
||||
#define hwloc_distances_get_by_type HWLOC_NAME(distances_get_by_type)
|
||||
#define hwloc_distances_get_by_name HWLOC_NAME(distances_get_by_name)
|
||||
#define hwloc_distances_get_name HWLOC_NAME(distances_get_name)
|
||||
#define hwloc_distances_release HWLOC_NAME(distances_release)
|
||||
#define hwloc_distances_obj_index HWLOC_NAME(distances_obj_index)
|
||||
#define hwloc_distances_obj_pair_values HWLOC_NAME(distances_pair_values)
|
||||
|
||||
#define hwloc_distances_transform_e HWLOC_NAME(distances_transform_e)
|
||||
#define HWLOC_DISTANCES_TRANSFORM_REMOVE_NULL HWLOC_NAME_CAPS(DISTANCES_TRANSFORM_REMOVE_NULL)
|
||||
#define HWLOC_DISTANCES_TRANSFORM_LINKS HWLOC_NAME_CAPS(DISTANCES_TRANSFORM_LINKS)
|
||||
#define HWLOC_DISTANCES_TRANSFORM_MERGE_SWITCH_PORTS HWLOC_NAME_CAPS(DISTANCES_TRANSFORM_MERGE_SWITCH_PORTS)
|
||||
#define HWLOC_DISTANCES_TRANSFORM_TRANSITIVE_CLOSURE HWLOC_NAME_CAPS(DISTANCES_TRANSFORM_TRANSITIVE_CLOSURE)
|
||||
#define hwloc_distances_transform HWLOC_NAME(distances_transform)
|
||||
|
||||
#define hwloc_distances_add_flag_e HWLOC_NAME(distances_add_flag_e)
|
||||
#define HWLOC_DISTANCES_ADD_FLAG_GROUP HWLOC_NAME_CAPS(DISTANCES_ADD_FLAG_GROUP)
|
||||
#define HWLOC_DISTANCES_ADD_FLAG_GROUP_INACCURATE HWLOC_NAME_CAPS(DISTANCES_ADD_FLAG_GROUP_INACCURATE)
|
||||
|
||||
#define hwloc_distances_add_handle_t HWLOC_NAME(distances_add_handle_t)
|
||||
#define hwloc_distances_add_create HWLOC_NAME(distances_add_create)
|
||||
#define hwloc_distances_add_values HWLOC_NAME(distances_add_values)
|
||||
#define hwloc_distances_add_commit HWLOC_NAME(distances_add_commit)
|
||||
|
||||
#define hwloc_distances_remove HWLOC_NAME(distances_remove)
|
||||
#define hwloc_distances_remove_by_depth HWLOC_NAME(distances_remove_by_depth)
|
||||
#define hwloc_distances_remove_by_type HWLOC_NAME(distances_remove_by_type)
|
||||
#define hwloc_distances_release_remove HWLOC_NAME(distances_release_remove)
|
||||
|
||||
/* diff.h */
|
||||
|
||||
#define hwloc_topology_diff_obj_attr_type_e HWLOC_NAME(topology_diff_obj_attr_type_e)
|
||||
#define hwloc_topology_diff_obj_attr_type_t HWLOC_NAME(topology_diff_obj_attr_type_t)
|
||||
#define HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE HWLOC_NAME_CAPS(TOPOLOGY_DIFF_OBJ_ATTR_SIZE)
|
||||
#define HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME HWLOC_NAME_CAPS(TOPOLOGY_DIFF_OBJ_ATTR_NAME)
|
||||
#define HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO HWLOC_NAME_CAPS(TOPOLOGY_DIFF_OBJ_ATTR_INFO)
|
||||
#define hwloc_topology_diff_obj_attr_u HWLOC_NAME(topology_diff_obj_attr_u)
|
||||
#define hwloc_topology_diff_obj_attr_generic_s HWLOC_NAME(topology_diff_obj_attr_generic_s)
|
||||
#define hwloc_topology_diff_obj_attr_uint64_s HWLOC_NAME(topology_diff_obj_attr_uint64_s)
|
||||
#define hwloc_topology_diff_obj_attr_string_s HWLOC_NAME(topology_diff_obj_attr_string_s)
|
||||
#define hwloc_topology_diff_type_e HWLOC_NAME(topology_diff_type_e)
|
||||
#define hwloc_topology_diff_type_t HWLOC_NAME(topology_diff_type_t)
|
||||
#define HWLOC_TOPOLOGY_DIFF_OBJ_ATTR HWLOC_NAME_CAPS(TOPOLOGY_DIFF_OBJ_ATTR)
|
||||
#define HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX HWLOC_NAME_CAPS(TOPOLOGY_DIFF_TOO_COMPLEX)
|
||||
#define hwloc_topology_diff_u HWLOC_NAME(topology_diff_u)
|
||||
#define hwloc_topology_diff_t HWLOC_NAME(topology_diff_t)
|
||||
#define hwloc_topology_diff_generic_s HWLOC_NAME(topology_diff_generic_s)
|
||||
#define hwloc_topology_diff_obj_attr_s HWLOC_NAME(topology_diff_obj_attr_s)
|
||||
#define hwloc_topology_diff_too_complex_s HWLOC_NAME(topology_diff_too_complex_s)
|
||||
#define hwloc_topology_diff_build HWLOC_NAME(topology_diff_build)
|
||||
#define hwloc_topology_diff_apply_flags_e HWLOC_NAME(topology_diff_apply_flags_e)
|
||||
#define HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE HWLOC_NAME_CAPS(TOPOLOGY_DIFF_APPLY_REVERSE)
|
||||
#define hwloc_topology_diff_apply HWLOC_NAME(topology_diff_apply)
|
||||
#define hwloc_topology_diff_destroy HWLOC_NAME(topology_diff_destroy)
|
||||
#define hwloc_topology_diff_load_xml HWLOC_NAME(topology_diff_load_xml)
|
||||
#define hwloc_topology_diff_export_xml HWLOC_NAME(topology_diff_export_xml)
|
||||
#define hwloc_topology_diff_load_xmlbuffer HWLOC_NAME(topology_diff_load_xmlbuffer)
|
||||
#define hwloc_topology_diff_export_xmlbuffer HWLOC_NAME(topology_diff_export_xmlbuffer)
|
||||
|
||||
/* shmem.h */
|
||||
|
||||
#define hwloc_shmem_topology_get_length HWLOC_NAME(shmem_topology_get_length)
|
||||
#define hwloc_shmem_topology_write HWLOC_NAME(shmem_topology_write)
|
||||
#define hwloc_shmem_topology_adopt HWLOC_NAME(shmem_topology_adopt)
|
||||
|
||||
/* glibc-sched.h */
|
||||
|
||||
#define hwloc_cpuset_to_glibc_sched_affinity HWLOC_NAME(cpuset_to_glibc_sched_affinity)
|
||||
#define hwloc_cpuset_from_glibc_sched_affinity HWLOC_NAME(cpuset_from_glibc_sched_affinity)
|
||||
|
||||
/* linux-libnuma.h */
|
||||
|
||||
#define hwloc_cpuset_to_linux_libnuma_ulongs HWLOC_NAME(cpuset_to_linux_libnuma_ulongs)
|
||||
#define hwloc_nodeset_to_linux_libnuma_ulongs HWLOC_NAME(nodeset_to_linux_libnuma_ulongs)
|
||||
#define hwloc_cpuset_from_linux_libnuma_ulongs HWLOC_NAME(cpuset_from_linux_libnuma_ulongs)
|
||||
#define hwloc_nodeset_from_linux_libnuma_ulongs HWLOC_NAME(nodeset_from_linux_libnuma_ulongs)
|
||||
#define hwloc_cpuset_to_linux_libnuma_bitmask HWLOC_NAME(cpuset_to_linux_libnuma_bitmask)
|
||||
#define hwloc_nodeset_to_linux_libnuma_bitmask HWLOC_NAME(nodeset_to_linux_libnuma_bitmask)
|
||||
#define hwloc_cpuset_from_linux_libnuma_bitmask HWLOC_NAME(cpuset_from_linux_libnuma_bitmask)
|
||||
#define hwloc_nodeset_from_linux_libnuma_bitmask HWLOC_NAME(nodeset_from_linux_libnuma_bitmask)
|
||||
|
||||
/* linux.h */
|
||||
|
||||
#define hwloc_linux_set_tid_cpubind HWLOC_NAME(linux_set_tid_cpubind)
|
||||
#define hwloc_linux_get_tid_cpubind HWLOC_NAME(linux_get_tid_cpubind)
|
||||
#define hwloc_linux_get_tid_last_cpu_location HWLOC_NAME(linux_get_tid_last_cpu_location)
|
||||
#define hwloc_linux_read_path_as_cpumask HWLOC_NAME(linux_read_file_cpumask)
|
||||
|
||||
/* windows.h */
|
||||
|
||||
#define hwloc_windows_get_nr_processor_groups HWLOC_NAME(windows_get_nr_processor_groups)
|
||||
#define hwloc_windows_get_processor_group_cpuset HWLOC_NAME(windows_get_processor_group_cpuset)
|
||||
|
||||
/* openfabrics-verbs.h */
|
||||
|
||||
#define hwloc_ibv_get_device_cpuset HWLOC_NAME(ibv_get_device_cpuset)
|
||||
#define hwloc_ibv_get_device_osdev HWLOC_NAME(ibv_get_device_osdev)
|
||||
#define hwloc_ibv_get_device_osdev_by_name HWLOC_NAME(ibv_get_device_osdev_by_name)
|
||||
|
||||
/* opencl.h */
|
||||
|
||||
#define hwloc_cl_device_topology_amd HWLOC_NAME(cl_device_topology_amd)
|
||||
#define hwloc_opencl_get_device_pci_busid HWLOC_NAME(opencl_get_device_pci_ids)
|
||||
#define hwloc_opencl_get_device_cpuset HWLOC_NAME(opencl_get_device_cpuset)
|
||||
#define hwloc_opencl_get_device_osdev HWLOC_NAME(opencl_get_device_osdev)
|
||||
#define hwloc_opencl_get_device_osdev_by_index HWLOC_NAME(opencl_get_device_osdev_by_index)
|
||||
|
||||
/* cuda.h */
|
||||
|
||||
#define hwloc_cuda_get_device_pci_ids HWLOC_NAME(cuda_get_device_pci_ids)
|
||||
#define hwloc_cuda_get_device_cpuset HWLOC_NAME(cuda_get_device_cpuset)
|
||||
#define hwloc_cuda_get_device_pcidev HWLOC_NAME(cuda_get_device_pcidev)
|
||||
#define hwloc_cuda_get_device_osdev HWLOC_NAME(cuda_get_device_osdev)
|
||||
#define hwloc_cuda_get_device_osdev_by_index HWLOC_NAME(cuda_get_device_osdev_by_index)
|
||||
|
||||
/* cudart.h */
|
||||
|
||||
#define hwloc_cudart_get_device_pci_ids HWLOC_NAME(cudart_get_device_pci_ids)
|
||||
#define hwloc_cudart_get_device_cpuset HWLOC_NAME(cudart_get_device_cpuset)
|
||||
#define hwloc_cudart_get_device_pcidev HWLOC_NAME(cudart_get_device_pcidev)
|
||||
#define hwloc_cudart_get_device_osdev_by_index HWLOC_NAME(cudart_get_device_osdev_by_index)
|
||||
|
||||
/* nvml.h */
|
||||
|
||||
#define hwloc_nvml_get_device_cpuset HWLOC_NAME(nvml_get_device_cpuset)
|
||||
#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)
|
||||
|
||||
/* levelzero.h */
|
||||
|
||||
#define hwloc_levelzero_get_device_cpuset HWLOC_NAME(levelzero_get_device_cpuset)
|
||||
#define hwloc_levelzero_get_device_osdev HWLOC_NAME(levelzero_get_device_osdev)
|
||||
|
||||
/* gl.h */
|
||||
|
||||
#define hwloc_gl_get_display_osdev_by_port_device HWLOC_NAME(gl_get_display_osdev_by_port_device)
|
||||
#define hwloc_gl_get_display_osdev_by_name HWLOC_NAME(gl_get_display_osdev_by_name)
|
||||
#define hwloc_gl_get_display_by_osdev HWLOC_NAME(gl_get_display_by_osdev)
|
||||
|
||||
/* hwloc/plugins.h */
|
||||
|
||||
#define hwloc_disc_phase_e HWLOC_NAME(disc_phase_e)
|
||||
#define HWLOC_DISC_PHASE_GLOBAL HWLOC_NAME_CAPS(DISC_PHASE_GLOBAL)
|
||||
#define HWLOC_DISC_PHASE_CPU HWLOC_NAME_CAPS(DISC_PHASE_CPU)
|
||||
#define HWLOC_DISC_PHASE_MEMORY HWLOC_NAME_CAPS(DISC_PHASE_MEMORY)
|
||||
#define HWLOC_DISC_PHASE_PCI HWLOC_NAME_CAPS(DISC_PHASE_PCI)
|
||||
#define HWLOC_DISC_PHASE_IO HWLOC_NAME_CAPS(DISC_PHASE_IO)
|
||||
#define HWLOC_DISC_PHASE_MISC HWLOC_NAME_CAPS(DISC_PHASE_MISC)
|
||||
#define HWLOC_DISC_PHASE_ANNOTATE HWLOC_NAME_CAPS(DISC_PHASE_ANNOTATE)
|
||||
#define HWLOC_DISC_PHASE_TWEAK HWLOC_NAME_CAPS(DISC_PHASE_TWEAK)
|
||||
#define hwloc_disc_phase_t HWLOC_NAME(disc_phase_t)
|
||||
#define hwloc_disc_component HWLOC_NAME(disc_component)
|
||||
|
||||
#define hwloc_disc_status_flag_e HWLOC_NAME(disc_status_flag_e)
|
||||
#define HWLOC_DISC_STATUS_FLAG_GOT_ALLOWED_RESOURCES HWLOC_NAME_CAPS(DISC_STATUS_FLAG_GOT_ALLOWED_RESOURCES)
|
||||
#define hwloc_disc_status HWLOC_NAME(disc_status)
|
||||
|
||||
#define hwloc_backend HWLOC_NAME(backend)
|
||||
|
||||
#define hwloc_backend_alloc HWLOC_NAME(backend_alloc)
|
||||
#define hwloc_backend_enable HWLOC_NAME(backend_enable)
|
||||
|
||||
#define hwloc_component_type_e HWLOC_NAME(component_type_e)
|
||||
#define HWLOC_COMPONENT_TYPE_DISC HWLOC_NAME_CAPS(COMPONENT_TYPE_DISC)
|
||||
#define HWLOC_COMPONENT_TYPE_XML HWLOC_NAME_CAPS(COMPONENT_TYPE_XML)
|
||||
#define hwloc_component_type_t HWLOC_NAME(component_type_t)
|
||||
#define hwloc_component HWLOC_NAME(component)
|
||||
|
||||
#define hwloc_plugin_check_namespace HWLOC_NAME(plugin_check_namespace)
|
||||
|
||||
#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)
|
||||
#define hwloc_alloc_setup_object HWLOC_NAME(alloc_setup_object)
|
||||
#define hwloc_obj_add_children_sets HWLOC_NAME(add_children_sets)
|
||||
#define hwloc_topology_reconnect HWLOC_NAME(topology_reconnect)
|
||||
|
||||
#define hwloc_filter_check_pcidev_subtype_important HWLOC_NAME(filter_check_pcidev_subtype_important)
|
||||
#define hwloc_filter_check_osdev_subtype_important HWLOC_NAME(filter_check_osdev_subtype_important)
|
||||
#define hwloc_filter_check_keep_object_type HWLOC_NAME(filter_check_keep_object_type)
|
||||
#define hwloc_filter_check_keep_object HWLOC_NAME(filter_check_keep_object)
|
||||
|
||||
#define hwloc_pcidisc_find_cap HWLOC_NAME(pcidisc_find_cap)
|
||||
#define hwloc_pcidisc_find_linkspeed HWLOC_NAME(pcidisc_find_linkspeed)
|
||||
#define hwloc_pcidisc_check_bridge_type HWLOC_NAME(pcidisc_check_bridge_type)
|
||||
#define hwloc_pcidisc_find_bridge_buses HWLOC_NAME(pcidisc_find_bridge_buses)
|
||||
#define hwloc_pcidisc_tree_insert_by_busid HWLOC_NAME(pcidisc_tree_insert_by_busid)
|
||||
#define hwloc_pcidisc_tree_attach HWLOC_NAME(pcidisc_tree_attach)
|
||||
|
||||
#define hwloc_pci_find_by_busid HWLOC_NAME(pcidisc_find_by_busid)
|
||||
#define hwloc_pci_find_parent_by_busid HWLOC_NAME(pcidisc_find_busid_parent)
|
||||
|
||||
#define hwloc_backend_distances_add_handle_t HWLOC_NAME(backend_distances_add_handle_t)
|
||||
#define hwloc_backend_distances_add_create HWLOC_NAME(backend_distances_add_create)
|
||||
#define hwloc_backend_distances_add_values HWLOC_NAME(backend_distances_add_values)
|
||||
#define hwloc_backend_distances_add_commit HWLOC_NAME(backend_distances_add_commit)
|
||||
|
||||
/* hwloc/deprecated.h */
|
||||
|
||||
#define hwloc_distances_add HWLOC_NAME(distances_add)
|
||||
|
||||
#define hwloc_topology_insert_misc_object_by_parent HWLOC_NAME(topology_insert_misc_object_by_parent)
|
||||
#define hwloc_obj_cpuset_snprintf HWLOC_NAME(obj_cpuset_snprintf)
|
||||
#define hwloc_obj_type_sscanf HWLOC_NAME(obj_type_sscanf)
|
||||
|
||||
#define hwloc_set_membind_nodeset HWLOC_NAME(set_membind_nodeset)
|
||||
#define hwloc_get_membind_nodeset HWLOC_NAME(get_membind_nodeset)
|
||||
#define hwloc_set_proc_membind_nodeset HWLOC_NAME(set_proc_membind_nodeset)
|
||||
#define hwloc_get_proc_membind_nodeset HWLOC_NAME(get_proc_membind_nodeset)
|
||||
#define hwloc_set_area_membind_nodeset HWLOC_NAME(set_area_membind_nodeset)
|
||||
#define hwloc_get_area_membind_nodeset HWLOC_NAME(get_area_membind_nodeset)
|
||||
#define hwloc_alloc_membind_nodeset HWLOC_NAME(alloc_membind_nodeset)
|
||||
|
||||
#define hwloc_cpuset_to_nodeset_strict HWLOC_NAME(cpuset_to_nodeset_strict)
|
||||
#define hwloc_cpuset_from_nodeset_strict HWLOC_NAME(cpuset_from_nodeset_strict)
|
||||
|
||||
/* private/debug.h */
|
||||
|
||||
#define hwloc_debug_enabled HWLOC_NAME(debug_enabled)
|
||||
#define hwloc_debug HWLOC_NAME(debug)
|
||||
|
||||
/* private/misc.h */
|
||||
|
||||
#ifndef HWLOC_HAVE_CORRECT_SNPRINTF
|
||||
#define hwloc_snprintf HWLOC_NAME(snprintf)
|
||||
#endif
|
||||
#define hwloc_ffsl_manual HWLOC_NAME(ffsl_manual)
|
||||
#define hwloc_ffs32 HWLOC_NAME(ffs32)
|
||||
#define hwloc_ffsl_from_ffs32 HWLOC_NAME(ffsl_from_ffs32)
|
||||
#define hwloc_flsl_manual HWLOC_NAME(flsl_manual)
|
||||
#define hwloc_fls32 HWLOC_NAME(fls32)
|
||||
#define hwloc_flsl_from_fls32 HWLOC_NAME(flsl_from_fls32)
|
||||
#define hwloc_weight_long HWLOC_NAME(weight_long)
|
||||
#define hwloc_strncasecmp HWLOC_NAME(strncasecmp)
|
||||
|
||||
#define hwloc_bitmap_compare_inclusion HWLOC_NAME(bitmap_compare_inclusion)
|
||||
|
||||
#define hwloc_pci_class_string HWLOC_NAME(pci_class_string)
|
||||
#define hwloc_linux_pci_link_speed_from_string HWLOC_NAME(linux_pci_link_speed_from_string)
|
||||
|
||||
#define hwloc_cache_type_by_depth_type HWLOC_NAME(cache_type_by_depth_type)
|
||||
#define hwloc__obj_type_is_normal HWLOC_NAME(_obj_type_is_normal)
|
||||
#define hwloc__obj_type_is_memory HWLOC_NAME(_obj_type_is_memory)
|
||||
#define hwloc__obj_type_is_io HWLOC_NAME(_obj_type_is_io)
|
||||
#define hwloc__obj_type_is_special HWLOC_NAME(_obj_type_is_special)
|
||||
|
||||
#define hwloc__obj_type_is_cache HWLOC_NAME(_obj_type_is_cache)
|
||||
#define hwloc__obj_type_is_dcache HWLOC_NAME(_obj_type_is_dcache)
|
||||
#define hwloc__obj_type_is_icache HWLOC_NAME(_obj_type_is_icache)
|
||||
|
||||
/* private/cpuid-x86.h */
|
||||
|
||||
#define hwloc_have_x86_cpuid HWLOC_NAME(have_x86_cpuid)
|
||||
#define hwloc_x86_cpuid HWLOC_NAME(x86_cpuid)
|
||||
|
||||
/* private/xml.h */
|
||||
|
||||
#define hwloc__xml_verbose HWLOC_NAME(_xml_verbose)
|
||||
|
||||
#define hwloc__xml_import_state_s HWLOC_NAME(_xml_import_state_s)
|
||||
#define hwloc__xml_import_state_t HWLOC_NAME(_xml_import_state_t)
|
||||
#define hwloc__xml_import_diff HWLOC_NAME(_xml_import_diff)
|
||||
#define hwloc_xml_backend_data_s HWLOC_NAME(xml_backend_data_s)
|
||||
#define hwloc__xml_export_state_s HWLOC_NAME(_xml_export_state_s)
|
||||
#define hwloc__xml_export_state_t HWLOC_NAME(_xml_export_state_t)
|
||||
#define hwloc__xml_export_data_s HWLOC_NAME(_xml_export_data_s)
|
||||
#define hwloc__xml_export_topology HWLOC_NAME(_xml_export_topology)
|
||||
#define hwloc__xml_export_diff HWLOC_NAME(_xml_export_diff)
|
||||
|
||||
#define hwloc_xml_callbacks HWLOC_NAME(xml_callbacks)
|
||||
#define hwloc_xml_component HWLOC_NAME(xml_component)
|
||||
#define hwloc_xml_callbacks_register HWLOC_NAME(xml_callbacks_register)
|
||||
#define hwloc_xml_callbacks_reset HWLOC_NAME(xml_callbacks_reset)
|
||||
|
||||
#define hwloc__xml_imported_v1distances_s HWLOC_NAME(_xml_imported_v1distances_s)
|
||||
|
||||
/* private/components.h */
|
||||
|
||||
#define hwloc_disc_component_force_enable HWLOC_NAME(disc_component_force_enable)
|
||||
#define hwloc_disc_components_enable_others HWLOC_NAME(disc_components_instantiate_others)
|
||||
|
||||
#define hwloc_backends_is_thissystem HWLOC_NAME(backends_is_thissystem)
|
||||
#define hwloc_backends_find_callbacks HWLOC_NAME(backends_find_callbacks)
|
||||
|
||||
#define hwloc_topology_components_init HWLOC_NAME(topology_components_init)
|
||||
#define hwloc_backends_disable_all HWLOC_NAME(backends_disable_all)
|
||||
#define hwloc_topology_components_fini HWLOC_NAME(topology_components_fini)
|
||||
|
||||
#define hwloc_components_init HWLOC_NAME(components_init)
|
||||
#define hwloc_components_fini HWLOC_NAME(components_fini)
|
||||
|
||||
/* private/internal-private.h */
|
||||
|
||||
#define hwloc_xml_component HWLOC_NAME(xml_component)
|
||||
#define hwloc_synthetic_component HWLOC_NAME(synthetic_component)
|
||||
|
||||
#define hwloc_aix_component HWLOC_NAME(aix_component)
|
||||
#define hwloc_bgq_component HWLOC_NAME(bgq_component)
|
||||
#define hwloc_darwin_component HWLOC_NAME(darwin_component)
|
||||
#define hwloc_freebsd_component HWLOC_NAME(freebsd_component)
|
||||
#define hwloc_hpux_component HWLOC_NAME(hpux_component)
|
||||
#define hwloc_linux_component HWLOC_NAME(linux_component)
|
||||
#define hwloc_netbsd_component HWLOC_NAME(netbsd_component)
|
||||
#define hwloc_noos_component HWLOC_NAME(noos_component)
|
||||
#define hwloc_solaris_component HWLOC_NAME(solaris_component)
|
||||
#define hwloc_windows_component HWLOC_NAME(windows_component)
|
||||
#define hwloc_x86_component HWLOC_NAME(x86_component)
|
||||
|
||||
#define hwloc_cuda_component HWLOC_NAME(cuda_component)
|
||||
#define hwloc_gl_component HWLOC_NAME(gl_component)
|
||||
#define hwloc_levelzero_component HWLOC_NAME(levelzero_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)
|
||||
|
||||
#define hwloc_xml_libxml_component HWLOC_NAME(xml_libxml_component)
|
||||
#define hwloc_xml_nolibxml_component HWLOC_NAME(xml_nolibxml_component)
|
||||
|
||||
/* 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)
|
||||
#define hwloc_pci_locality_s HWLOC_NAME(pci_locality_s)
|
||||
|
||||
#define hwloc_topology_forced_component_s HWLOC_NAME(topology_forced_component)
|
||||
|
||||
#define hwloc_alloc_root_sets HWLOC_NAME(alloc_root_sets)
|
||||
#define hwloc_setup_pu_level HWLOC_NAME(setup_pu_level)
|
||||
#define hwloc_get_sysctlbyname HWLOC_NAME(get_sysctlbyname)
|
||||
#define hwloc_get_sysctl HWLOC_NAME(get_sysctl)
|
||||
#define hwloc_fallback_nbprocessors HWLOC_NAME(fallback_nbprocessors)
|
||||
#define hwloc_fallback_memsize HWLOC_NAME(fallback_memsize)
|
||||
|
||||
#define hwloc__object_cpusets_compare_first HWLOC_NAME(_object_cpusets_compare_first)
|
||||
#define hwloc__reorder_children HWLOC_NAME(_reorder_children)
|
||||
|
||||
#define hwloc_topology_setup_defaults HWLOC_NAME(topology_setup_defaults)
|
||||
#define hwloc_topology_clear HWLOC_NAME(topology_clear)
|
||||
|
||||
#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)
|
||||
#define hwloc_find_insert_io_parent_by_complete_cpuset HWLOC_NAME(hwloc_find_insert_io_parent_by_complete_cpuset)
|
||||
|
||||
#define hwloc__add_info HWLOC_NAME(_add_info)
|
||||
#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)
|
||||
#define hwloc_set_binding_hooks HWLOC_NAME(set_binding_hooks)
|
||||
|
||||
#define hwloc_set_linuxfs_hooks HWLOC_NAME(set_linuxfs_hooks)
|
||||
#define hwloc_set_bgq_hooks HWLOC_NAME(set_bgq_hooks)
|
||||
#define hwloc_set_solaris_hooks HWLOC_NAME(set_solaris_hooks)
|
||||
#define hwloc_set_aix_hooks HWLOC_NAME(set_aix_hooks)
|
||||
#define hwloc_set_windows_hooks HWLOC_NAME(set_windows_hooks)
|
||||
#define hwloc_set_darwin_hooks HWLOC_NAME(set_darwin_hooks)
|
||||
#define hwloc_set_freebsd_hooks HWLOC_NAME(set_freebsd_hooks)
|
||||
#define hwloc_set_netbsd_hooks HWLOC_NAME(set_netbsd_hooks)
|
||||
#define hwloc_set_hpux_hooks HWLOC_NAME(set_hpux_hooks)
|
||||
|
||||
#define hwloc_look_hardwired_fujitsu_k HWLOC_NAME(look_hardwired_fujitsu_k)
|
||||
#define hwloc_look_hardwired_fujitsu_fx10 HWLOC_NAME(look_hardwired_fujitsu_fx10)
|
||||
#define hwloc_look_hardwired_fujitsu_fx100 HWLOC_NAME(look_hardwired_fujitsu_fx100)
|
||||
|
||||
#define hwloc_add_uname_info HWLOC_NAME(add_uname_info)
|
||||
#define hwloc_free_unlinked_object HWLOC_NAME(free_unlinked_object)
|
||||
#define hwloc_free_object_and_children HWLOC_NAME(free_object_and_children)
|
||||
#define hwloc_free_object_siblings_and_children HWLOC_NAME(free_object_siblings_and_children)
|
||||
|
||||
#define hwloc_alloc_heap HWLOC_NAME(alloc_heap)
|
||||
#define hwloc_alloc_mmap HWLOC_NAME(alloc_mmap)
|
||||
#define hwloc_free_heap HWLOC_NAME(free_heap)
|
||||
#define hwloc_free_mmap HWLOC_NAME(free_mmap)
|
||||
#define hwloc_alloc_or_fail HWLOC_NAME(alloc_or_fail)
|
||||
|
||||
#define hwloc_internal_distances_s HWLOC_NAME(internal_distances_s)
|
||||
#define hwloc_internal_distances_init HWLOC_NAME(internal_distances_init)
|
||||
#define hwloc_internal_distances_prepare HWLOC_NAME(internal_distances_prepare)
|
||||
#define hwloc_internal_distances_dup HWLOC_NAME(internal_distances_dup)
|
||||
#define hwloc_internal_distances_refresh HWLOC_NAME(internal_distances_refresh)
|
||||
#define hwloc_internal_distances_destroy HWLOC_NAME(internal_distances_destroy)
|
||||
#define hwloc_internal_distances_add HWLOC_NAME(internal_distances_add)
|
||||
#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)
|
||||
|
||||
#define hwloc_progname HWLOC_NAME(progname)
|
||||
|
||||
#define hwloc__topology_disadopt HWLOC_NAME(_topology_disadopt)
|
||||
#define hwloc__topology_dup HWLOC_NAME(_topology_dup)
|
||||
|
||||
#define hwloc_tma HWLOC_NAME(tma)
|
||||
#define hwloc_tma_malloc HWLOC_NAME(tma_malloc)
|
||||
#define hwloc_tma_calloc HWLOC_NAME(tma_calloc)
|
||||
#define hwloc_tma_strdup HWLOC_NAME(tma_strdup)
|
||||
#define hwloc_bitmap_tma_dup HWLOC_NAME(bitmap_tma_dup)
|
||||
|
||||
/* private/solaris-chiptype.h */
|
||||
|
||||
#define hwloc_solaris_chip_info_s HWLOC_NAME(solaris_chip_info_s)
|
||||
#define hwloc_solaris_get_chip_info HWLOC_NAME(solaris_get_chip_info)
|
||||
|
||||
#endif /* HWLOC_SYM_TRANSFORM */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_RENAME_H */
|
||||
203
src/3rdparty/hwloc/include/hwloc/rsmi.h
vendored
203
src/3rdparty/hwloc/include/hwloc/rsmi.h
vendored
@@ -1,203 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012-2021 Inria. All rights reserved.
|
||||
* Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.
|
||||
* Written by Advanced Micro Devices,
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Macros to help interaction between hwloc and the ROCm SMI Management Library.
|
||||
*
|
||||
* Applications that use both hwloc and the ROCm SMI Management Library may want to
|
||||
* include this file so as to get topology information for AMD GPU devices.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_RSMI_H
|
||||
#define HWLOC_RSMI_H
|
||||
|
||||
#include "hwloc.h"
|
||||
#include "hwloc/autogen/config.h"
|
||||
#include "hwloc/helper.h"
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
#include "hwloc/linux.h"
|
||||
#endif
|
||||
|
||||
#include <rocm_smi/rocm_smi.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup hwlocality_rsmi Interoperability with the ROCm SMI Management Library
|
||||
*
|
||||
* This interface offers ways to retrieve topology information about
|
||||
* devices managed by the ROCm SMI Management Library.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Get the CPU set of logical processors that are physically
|
||||
* close to AMD GPU device whose index is \p dv_ind.
|
||||
*
|
||||
* Store in \p set the CPU-set describing the locality of the AMD GPU device
|
||||
* whose index is \p dv_ind.
|
||||
*
|
||||
* Topology \p topology and device \p dv_ind must match the local machine.
|
||||
* I/O devices detection and the ROCm SMI component are not needed in the
|
||||
* topology.
|
||||
*
|
||||
* The function only returns the locality of the device.
|
||||
* If more information about the device is needed, OS objects should
|
||||
* be used instead, see hwloc_rsmi_get_device_osdev()
|
||||
* and hwloc_rsmi_get_device_osdev_by_index().
|
||||
*
|
||||
* This function is currently only implemented in a meaningful way for
|
||||
* Linux; other systems will simply get a full cpuset.
|
||||
*/
|
||||
static __hwloc_inline int
|
||||
hwloc_rsmi_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
|
||||
uint32_t dv_ind, hwloc_cpuset_t set)
|
||||
{
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
|
||||
#define HWLOC_RSMI_DEVICE_SYSFS_PATH_MAX 128
|
||||
char path[HWLOC_RSMI_DEVICE_SYSFS_PATH_MAX];
|
||||
rsmi_status_t ret;
|
||||
uint64_t bdfid = 0;
|
||||
unsigned domain, device, bus;
|
||||
|
||||
if (!hwloc_topology_is_thissystem(topology)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = rsmi_dev_pci_id_get(dv_ind, &bdfid);
|
||||
if (RSMI_STATUS_SUCCESS != ret) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
domain = (bdfid>>32) & 0xffffffff;
|
||||
bus = ((bdfid & 0xffff)>>8) & 0xff;
|
||||
device = ((bdfid & 0xff)>>3) & 0x1f;
|
||||
|
||||
sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", domain, bus, device);
|
||||
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|
||||
|| hwloc_bitmap_iszero(set))
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
#else
|
||||
/* Non-Linux systems simply get a full cpuset */
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Get the hwloc OS device object corresponding to the
|
||||
* AMD GPU device whose index is \p dv_ind.
|
||||
*
|
||||
* \return The hwloc OS device object describing the AMD GPU device whose
|
||||
* index is \p dv_ind.
|
||||
* \return \c NULL if none could be found.
|
||||
*
|
||||
* The topology \p topology does not necessarily have to match the current
|
||||
* machine. For instance the topology may be an XML import of a remote host.
|
||||
* I/O devices detection and the ROCm SMI component must be enabled in the
|
||||
* topology.
|
||||
*
|
||||
* \note The corresponding PCI device object can be obtained by looking
|
||||
* at the OS device parent object (unless PCI devices are filtered out).
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_rsmi_get_device_osdev_by_index(hwloc_topology_t topology, uint32_t dv_ind)
|
||||
{
|
||||
hwloc_obj_t osdev = NULL;
|
||||
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
|
||||
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
|
||||
&& osdev->name
|
||||
&& !strncmp("rsmi", osdev->name, 4)
|
||||
&& atoi(osdev->name + 4) == (int) dv_ind)
|
||||
return osdev;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** \brief Get the hwloc OS device object corresponding to AMD GPU device,
|
||||
* whose index is \p dv_ind.
|
||||
*
|
||||
* \return The hwloc OS device object that describes the given
|
||||
* AMD GPU, whose index is \p dv_ind.
|
||||
* \return \c NULL if none could be found.
|
||||
*
|
||||
* Topology \p topology and device \p dv_ind must match the local machine.
|
||||
* I/O devices detection and the ROCm SMI component must be enabled in the
|
||||
* topology. If not, the locality of the object may still be found using
|
||||
* hwloc_rsmi_get_device_cpuset().
|
||||
*
|
||||
* \note The corresponding hwloc PCI device may be found by looking
|
||||
* at the result parent pointer (unless PCI devices are filtered out).
|
||||
*/
|
||||
static __hwloc_inline hwloc_obj_t
|
||||
hwloc_rsmi_get_device_osdev(hwloc_topology_t topology, uint32_t dv_ind)
|
||||
{
|
||||
hwloc_obj_t osdev;
|
||||
rsmi_status_t ret;
|
||||
uint64_t bdfid = 0;
|
||||
unsigned domain, device, bus, func;
|
||||
uint64_t id;
|
||||
char uuid[64];
|
||||
|
||||
if (!hwloc_topology_is_thissystem(topology)) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = rsmi_dev_pci_id_get(dv_ind, &bdfid);
|
||||
if (RSMI_STATUS_SUCCESS != ret) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
domain = (bdfid>>32) & 0xffffffff;
|
||||
bus = ((bdfid & 0xffff)>>8) & 0xff;
|
||||
device = ((bdfid & 0xff)>>3) & 0x1f;
|
||||
func = bdfid & 0x7;
|
||||
|
||||
ret = rsmi_dev_unique_id_get(dv_ind, &id);
|
||||
if (RSMI_STATUS_SUCCESS != ret)
|
||||
uuid[0] = '\0';
|
||||
else
|
||||
sprintf(uuid, "%lx", id);
|
||||
|
||||
osdev = NULL;
|
||||
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
|
||||
hwloc_obj_t pcidev = osdev->parent;
|
||||
const char *info;
|
||||
|
||||
if (strncmp(osdev->name, "rsmi", 4))
|
||||
continue;
|
||||
|
||||
if (pcidev
|
||||
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
|
||||
&& pcidev->attr->pcidev.domain == domain
|
||||
&& pcidev->attr->pcidev.bus == bus
|
||||
&& pcidev->attr->pcidev.dev == device
|
||||
&& pcidev->attr->pcidev.func == func)
|
||||
return osdev;
|
||||
|
||||
info = hwloc_obj_get_info_by_name(osdev, "AMDUUID");
|
||||
if (info && !strcmp(info, uuid))
|
||||
return osdev;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_RSMI_H */
|
||||
137
src/3rdparty/hwloc/include/hwloc/shmem.h
vendored
137
src/3rdparty/hwloc/include/hwloc/shmem.h
vendored
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013-2018 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Sharing topologies between processes
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_SHMEM_H
|
||||
#define HWLOC_SHMEM_H
|
||||
|
||||
#include "hwloc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#elif 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup hwlocality_shmem Sharing topologies between processes
|
||||
*
|
||||
* These functions are used to share a topology between processes by
|
||||
* duplicating it into a file-backed shared-memory buffer.
|
||||
*
|
||||
* The master process must first get the required shared-memory size
|
||||
* for storing this topology with hwloc_shmem_topology_get_length().
|
||||
*
|
||||
* Then it must find a virtual memory area of that size that is available
|
||||
* in all processes (identical virtual addresses in all processes).
|
||||
* On Linux, this can be done by comparing holes found in /proc/\<pid\>/maps
|
||||
* for each process.
|
||||
*
|
||||
* Once found, it must open a destination file for storing the buffer,
|
||||
* and pass it to hwloc_shmem_topology_write() together with
|
||||
* virtual memory address and length obtained above.
|
||||
*
|
||||
* Other processes may then adopt this shared topology by opening the
|
||||
* same file and passing it to hwloc_shmem_topology_adopt() with the
|
||||
* exact same virtual memory address and length.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Get the required shared memory length for storing a topology.
|
||||
*
|
||||
* This length (in bytes) must be used in hwloc_shmem_topology_write()
|
||||
* and hwloc_shmem_topology_adopt() later.
|
||||
*
|
||||
* \note Flags \p flags are currently unused, must be 0.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_shmem_topology_get_length(hwloc_topology_t topology,
|
||||
size_t *lengthp,
|
||||
unsigned long flags);
|
||||
|
||||
/** \brief Duplicate a topology to a shared memory file.
|
||||
*
|
||||
* Temporarily map a file in virtual memory and duplicate the
|
||||
* topology \p topology by allocating duplicates in there.
|
||||
*
|
||||
* The segment of the file pointed by descriptor \p fd,
|
||||
* starting at offset \p fileoffset, and of length \p length (in bytes),
|
||||
* will be temporarily mapped at virtual address \p mmap_address
|
||||
* during the duplication.
|
||||
*
|
||||
* The mapping length \p length must have been previously obtained with
|
||||
* hwloc_shmem_topology_get_length()
|
||||
* and the topology must not have been modified in the meantime.
|
||||
*
|
||||
* \note Flags \p flags are currently unused, must be 0.
|
||||
*
|
||||
* \note The object userdata pointer is duplicated but the pointed buffer
|
||||
* is not. However the caller may also allocate it manually in shared memory
|
||||
* to share it as well.
|
||||
*
|
||||
* \return -1 with errno set to EBUSY if the virtual memory mapping defined
|
||||
* by \p mmap_address and \p length isn't available in the process.
|
||||
* \return -1 with errno set to EINVAL if \p fileoffset, \p mmap_address
|
||||
* or \p length aren't page-aligned.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_shmem_topology_write(hwloc_topology_t topology,
|
||||
int fd, hwloc_uint64_t fileoffset,
|
||||
void *mmap_address, size_t length,
|
||||
unsigned long flags);
|
||||
|
||||
/** \brief Adopt a shared memory topology stored in a file.
|
||||
*
|
||||
* Map a file in virtual memory and adopt the topology that was previously
|
||||
* stored there with hwloc_shmem_topology_write().
|
||||
*
|
||||
* The returned adopted topology in \p topologyp can be used just like any
|
||||
* topology. And it must be destroyed with hwloc_topology_destroy() as usual.
|
||||
*
|
||||
* However the topology is read-only.
|
||||
* For instance, it cannot be modified with hwloc_topology_restrict()
|
||||
* and object userdata pointers cannot be changed.
|
||||
*
|
||||
* The segment of the file pointed by descriptor \p fd,
|
||||
* starting at offset \p fileoffset, and of length \p length (in bytes),
|
||||
* will be mapped at virtual address \p mmap_address.
|
||||
*
|
||||
* The file pointed by descriptor \p fd, the offset \p fileoffset,
|
||||
* the requested mapping virtual address \p mmap_address and the length \p length
|
||||
* must be identical to what was given to hwloc_shmem_topology_write() earlier.
|
||||
*
|
||||
* \note Flags \p flags are currently unused, must be 0.
|
||||
*
|
||||
* \note The object userdata pointer should not be used unless the process
|
||||
* that created the shared topology also placed userdata-pointed buffers
|
||||
* in shared memory.
|
||||
*
|
||||
* \note This function takes care of calling hwloc_topology_abi_check().
|
||||
*
|
||||
* \return -1 with errno set to EBUSY if the virtual memory mapping defined
|
||||
* by \p mmap_address and \p length isn't available in the process.
|
||||
*
|
||||
* \return -1 with errno set to EINVAL if \p fileoffset, \p mmap_address
|
||||
* or \p length aren't page-aligned, or do not match what was given to
|
||||
* hwloc_shmem_topology_write() earlier.
|
||||
*
|
||||
* \return -1 with errno set to EINVAL if the layout of the topology structure
|
||||
* is different between the writer process and the adopter process.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp,
|
||||
int fd, hwloc_uint64_t fileoffset,
|
||||
void *mmap_address, size_t length,
|
||||
unsigned long flags);
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_SHMEM_H */
|
||||
76
src/3rdparty/hwloc/include/hwloc/windows.h
vendored
76
src/3rdparty/hwloc/include/hwloc/windows.h
vendored
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2021 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Macros to help interaction between hwloc and Windows.
|
||||
*
|
||||
* Applications that use hwloc on Windows may want to include this file
|
||||
* for Windows specific hwloc features.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_WINDOWS_H
|
||||
#define HWLOC_WINDOWS_H
|
||||
|
||||
#include "hwloc.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup hwlocality_windows Windows-specific helpers
|
||||
*
|
||||
* These functions query Windows processor groups.
|
||||
* These groups partition the operating system into virtual sets
|
||||
* of up to 64 neighbor PUs.
|
||||
* Threads and processes may only be bound inside a single group.
|
||||
* Although Windows processor groups may be exposed in the hwloc
|
||||
* hierarchy as hwloc Groups, they are also often merged into
|
||||
* existing hwloc objects such as NUMA nodes or Packages.
|
||||
* This API provides explicit information about Windows processor
|
||||
* groups so that applications know whether binding to a large
|
||||
* set of PUs may fail because it spans over multiple Windows
|
||||
* processor groups.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** \brief Get the number of Windows processor groups
|
||||
*
|
||||
* \p flags must be 0 for now.
|
||||
*
|
||||
* \return at least \c 1 on success.
|
||||
* \return -1 on error, for instance if the topology does not match
|
||||
* the current system (e.g. loaded from another machine through XML).
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_windows_get_nr_processor_groups(hwloc_topology_t topology, unsigned long flags);
|
||||
|
||||
/** \brief Get the CPU-set of a Windows processor group.
|
||||
*
|
||||
* Get the set of PU included in the processor group specified
|
||||
* by \p pg_index.
|
||||
* \p pg_index must be between \c 0 and the value returned
|
||||
* by hwloc_windows_get_nr_processor_groups() minus 1.
|
||||
*
|
||||
* \p flags must be 0 for now.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c -1 on error, for instance if \p pg_index is invalid,
|
||||
* or if the topology does not match the current system (e.g. loaded
|
||||
* from another machine through XML).
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_windows_get_processor_group_cpuset(hwloc_topology_t topology, unsigned pg_index, hwloc_cpuset_t cpuset, unsigned long flags);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_WINDOWS_H */
|
||||
672
src/3rdparty/hwloc/include/private/autogen/config.h
vendored
672
src/3rdparty/hwloc/include/private/autogen/config.h
vendored
@@ -1,672 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009, 2011, 2012 CNRS. All rights reserved.
|
||||
* Copyright © 2009-2021 Inria. All rights reserved.
|
||||
* Copyright © 2009, 2011, 2012, 2015 Université Bordeaux. All rights reserved.
|
||||
* Copyright © 2009-2020 Cisco Systems, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_CONFIGURE_H
|
||||
#define HWLOC_CONFIGURE_H
|
||||
|
||||
#define DECLSPEC_EXPORTS
|
||||
|
||||
#define HWLOC_HAVE_MSVC_CPUIDEX 1
|
||||
|
||||
/* Define to 1 if the system has the type `CACHE_DESCRIPTOR'. */
|
||||
#define HAVE_CACHE_DESCRIPTOR 0
|
||||
|
||||
/* Define to 1 if the system has the type `CACHE_RELATIONSHIP'. */
|
||||
#define HAVE_CACHE_RELATIONSHIP 0
|
||||
|
||||
/* Define to 1 if you have the `clz' function. */
|
||||
/* #undef HAVE_CLZ */
|
||||
|
||||
/* Define to 1 if you have the `clzl' function. */
|
||||
/* #undef HAVE_CLZL */
|
||||
|
||||
/* Define to 1 if you have the <CL/cl_ext.h> header file. */
|
||||
/* #undef HAVE_CL_CL_EXT_H */
|
||||
|
||||
/* Define to 1 if you have the `cpuset_setaffinity' function. */
|
||||
/* #undef HAVE_CPUSET_SETAFFINITY */
|
||||
|
||||
/* Define to 1 if you have the `cpuset_setid' function. */
|
||||
/* #undef HAVE_CPUSET_SETID */
|
||||
|
||||
/* Define to 1 if we have -lcuda */
|
||||
/* #undef HAVE_CUDA */
|
||||
|
||||
/* Define to 1 if you have the <cuda.h> header file. */
|
||||
/* #undef HAVE_CUDA_H */
|
||||
|
||||
/* Define to 1 if you have the <cuda_runtime_api.h> header file. */
|
||||
/* #undef HAVE_CUDA_RUNTIME_API_H */
|
||||
|
||||
/* Define to 1 if you have the declaration of `CL_DEVICE_TOPOLOGY_AMD', and to
|
||||
0 if you don't. */
|
||||
/* #undef HAVE_DECL_CL_DEVICE_TOPOLOGY_AMD */
|
||||
|
||||
/* Define to 1 if you have the declaration of `CTL_HW', and to 0 if you don't.
|
||||
*/
|
||||
/* #undef HAVE_DECL_CTL_HW */
|
||||
|
||||
/* Define to 1 if you have the declaration of `fabsf', and to 0 if you don't.
|
||||
*/
|
||||
#define HAVE_DECL_FABSF 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `modff', and to 0 if you don't.
|
||||
*/
|
||||
#define HAVE_DECL_MODFF 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `HW_NCPU', and to 0 if you
|
||||
don't. */
|
||||
/* #undef HAVE_DECL_HW_NCPU */
|
||||
|
||||
/* Define to 1 if you have the declaration of
|
||||
`nvmlDeviceGetMaxPcieLinkGeneration', and to 0 if you don't. */
|
||||
/* #undef HAVE_DECL_NVMLDEVICEGETMAXPCIELINKGENERATION */
|
||||
|
||||
/* Define to 1 if you have the declaration of `pthread_getaffinity_np', and to
|
||||
0 if you don't. */
|
||||
#define HAVE_DECL_PTHREAD_GETAFFINITY_NP 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `pthread_setaffinity_np', and to
|
||||
0 if you don't. */
|
||||
#define HAVE_DECL_PTHREAD_SETAFFINITY_NP 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `strtoull', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_STRTOULL 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `strcasecmp', and to 0 if you
|
||||
don't. */
|
||||
/* #undef HWLOC_HAVE_DECL_STRCASECMP */
|
||||
|
||||
/* Define to 1 if you have the declaration of `snprintf', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_SNPRINTF 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `_strdup', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL__STRDUP 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `_putenv', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL__PUTENV 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `_SC_LARGE_PAGESIZE', and to 0
|
||||
if you don't. */
|
||||
#define HAVE_DECL__SC_LARGE_PAGESIZE 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `_SC_NPROCESSORS_CONF', and to 0
|
||||
if you don't. */
|
||||
#define HAVE_DECL__SC_NPROCESSORS_CONF 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `_SC_NPROCESSORS_ONLN', and to 0
|
||||
if you don't. */
|
||||
#define HAVE_DECL__SC_NPROCESSORS_ONLN 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `_SC_NPROC_CONF', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL__SC_NPROC_CONF 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `_SC_NPROC_ONLN', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL__SC_NPROC_ONLN 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `_SC_PAGESIZE', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL__SC_PAGESIZE 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `_SC_PAGE_SIZE', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL__SC_PAGE_SIZE 0
|
||||
|
||||
/* Define to 1 if you have the <dirent.h> header file. */
|
||||
/* #define HAVE_DIRENT_H 1 */
|
||||
#undef HAVE_DIRENT_H
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
/* #undef HAVE_DLFCN_H */
|
||||
|
||||
/* Define to 1 if you have the `ffs' function. */
|
||||
/* #undef HAVE_FFS */
|
||||
|
||||
/* Define to 1 if you have the `ffsl' function. */
|
||||
/* #undef HAVE_FFSL */
|
||||
|
||||
/* Define to 1 if you have the `fls' function. */
|
||||
/* #undef HAVE_FLS */
|
||||
|
||||
/* Define to 1 if you have the `flsl' function. */
|
||||
/* #undef HAVE_FLSL */
|
||||
|
||||
/* Define to 1 if you have the `getpagesize' function. */
|
||||
#define HAVE_GETPAGESIZE 1
|
||||
|
||||
/* Define to 1 if the system has the type `GROUP_AFFINITY'. */
|
||||
#define HAVE_GROUP_AFFINITY 1
|
||||
|
||||
/* Define to 1 if the system has the type `GROUP_RELATIONSHIP'. */
|
||||
#define HAVE_GROUP_RELATIONSHIP 1
|
||||
|
||||
/* Define to 1 if you have the `host_info' function. */
|
||||
/* #undef HAVE_HOST_INFO */
|
||||
|
||||
/* Define to 1 if you have the <infiniband/verbs.h> header file. */
|
||||
/* #undef HAVE_INFINIBAND_VERBS_H */
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `KAFFINITY'. */
|
||||
#define HAVE_KAFFINITY 1
|
||||
|
||||
/* Define to 1 if you have the <kstat.h> header file. */
|
||||
/* #undef HAVE_KSTAT_H */
|
||||
|
||||
/* Define to 1 if you have the <langinfo.h> header file. */
|
||||
/* #undef HAVE_LANGINFO_H */
|
||||
|
||||
/* Define to 1 if we have -lgdi32 */
|
||||
#define HAVE_LIBGDI32 1
|
||||
|
||||
/* Define to 1 if we have -libverbs */
|
||||
/* #undef HAVE_LIBIBVERBS */
|
||||
|
||||
/* Define to 1 if we have -lkstat */
|
||||
/* #undef HAVE_LIBKSTAT */
|
||||
|
||||
/* Define to 1 if we have -llgrp */
|
||||
/* #undef HAVE_LIBLGRP */
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#define HAVE_LOCALE_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `LOGICAL_PROCESSOR_RELATIONSHIP'. */
|
||||
#define HAVE_LOGICAL_PROCESSOR_RELATIONSHIP 1
|
||||
|
||||
/* Define to 1 if you have the <mach/mach_host.h> header file. */
|
||||
/* #undef HAVE_MACH_MACH_HOST_H */
|
||||
|
||||
/* Define to 1 if you have the <mach/mach_init.h> header file. */
|
||||
/* #undef HAVE_MACH_MACH_INIT_H */
|
||||
|
||||
/* Define to 1 if you have the <malloc.h> header file. */
|
||||
#define HAVE_MALLOC_H 1
|
||||
|
||||
/* Define to 1 if you have the `memalign' function. */
|
||||
/* #undef HAVE_MEMALIGN */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `nl_langinfo' function. */
|
||||
/* #undef HAVE_NL_LANGINFO */
|
||||
|
||||
/* Define to 1 if you have the <numaif.h> header file. */
|
||||
/* #undef HAVE_NUMAIF_H */
|
||||
|
||||
/* Define to 1 if the system has the type `NUMA_NODE_RELATIONSHIP'. */
|
||||
#define HAVE_NUMA_NODE_RELATIONSHIP 1
|
||||
|
||||
/* Define to 1 if you have the <NVCtrl/NVCtrl.h> header file. */
|
||||
/* #undef HAVE_NVCTRL_NVCTRL_H */
|
||||
|
||||
/* Define to 1 if you have the <nvml.h> header file. */
|
||||
/* #undef HAVE_NVML_H */
|
||||
|
||||
/* Define to 1 if you have the `openat' function. */
|
||||
/* #undef HAVE_OPENAT */
|
||||
|
||||
/* Define to 1 if you have the <picl.h> header file. */
|
||||
/* #undef HAVE_PICL_H */
|
||||
|
||||
/* Define to 1 if you have the `posix_memalign' function. */
|
||||
/* #undef HAVE_POSIX_MEMALIGN */
|
||||
|
||||
/* Define to 1 if the system has the type `PROCESSOR_CACHE_TYPE'. */
|
||||
#define HAVE_PROCESSOR_CACHE_TYPE 1
|
||||
|
||||
/* Define to 1 if the system has the type `PROCESSOR_GROUP_INFO'. */
|
||||
#define HAVE_PROCESSOR_GROUP_INFO 1
|
||||
|
||||
/* Define to 1 if the system has the type `PROCESSOR_RELATIONSHIP'. */
|
||||
#define HAVE_PROCESSOR_RELATIONSHIP 1
|
||||
|
||||
/* Define to 1 if the system has the type `PSAPI_WORKING_SET_EX_BLOCK'. */
|
||||
/* #undef HAVE_PSAPI_WORKING_SET_EX_BLOCK */
|
||||
|
||||
/* Define to 1 if the system has the type `PSAPI_WORKING_SET_EX_INFORMATION'.
|
||||
*/
|
||||
/* #undef HAVE_PSAPI_WORKING_SET_EX_INFORMATION */
|
||||
|
||||
/* Define to 1 if the system has the type `PROCESSOR_NUMBER'. */
|
||||
#define HAVE_PROCESSOR_NUMBER 1
|
||||
|
||||
/* Define to 1 if you have the <pthread_np.h> header file. */
|
||||
/* #undef HAVE_PTHREAD_NP_H */
|
||||
|
||||
/* Define to 1 if the system has the type `pthread_t'. */
|
||||
/* #undef HAVE_PTHREAD_T */
|
||||
#undef HAVE_PTHREAD_T
|
||||
|
||||
/* Define to 1 if you have the `putwc' function. */
|
||||
#define HAVE_PUTWC 1
|
||||
|
||||
/* Define to 1 if the system has the type `RelationProcessorPackage'. */
|
||||
/* #undef HAVE_RELATIONPROCESSORPACKAGE */
|
||||
|
||||
/* Define to 1 if you have the `setlocale' function. */
|
||||
#define HAVE_SETLOCALE 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strftime' function. */
|
||||
#define HAVE_STRFTIME 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
/* #define HAVE_STRINGS_H 1*/
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strncasecmp' function. */
|
||||
#define HAVE_STRNCASECMP 1
|
||||
|
||||
/* Define to '1' if sysctl is present and usable */
|
||||
/* #undef HAVE_SYSCTL */
|
||||
|
||||
/* Define to '1' if sysctlbyname is present and usable */
|
||||
/* #undef HAVE_SYSCTLBYNAME */
|
||||
|
||||
/* Define to 1 if the system has the type
|
||||
`SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX'. */
|
||||
#define HAVE_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX 1
|
||||
|
||||
/* Define to 1 if you have the <sys/cpuset.h> header file. */
|
||||
/* #undef HAVE_SYS_CPUSET_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/lgrp_user.h> header file. */
|
||||
/* #undef HAVE_SYS_LGRP_USER_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
/* #undef HAVE_SYS_MMAN_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
/* #define HAVE_SYS_PARAM_H 1 */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/sysctl.h> header file. */
|
||||
/* #undef HAVE_SYS_SYSCTL_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/utsname.h> header file. */
|
||||
/* #undef HAVE_SYS_UTSNAME_H */
|
||||
|
||||
/* Define to 1 if you have the `uname' function. */
|
||||
/* #undef HAVE_UNAME */
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
/* #define HAVE_UNISTD_H 1 */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the `uselocale' function. */
|
||||
/* #undef HAVE_USELOCALE */
|
||||
|
||||
/* Define to 1 if the system has the type `wchar_t'. */
|
||||
#define HAVE_WCHAR_T 1
|
||||
|
||||
/* Define to 1 if you have the <X11/keysym.h> header file. */
|
||||
/* #undef HAVE_X11_KEYSYM_H */
|
||||
|
||||
/* Define to 1 if you have the <X11/Xlib.h> header file. */
|
||||
/* #undef HAVE_X11_XLIB_H */
|
||||
|
||||
/* Define to 1 if you have the <X11/Xutil.h> header file. */
|
||||
/* #undef HAVE_X11_XUTIL_H */
|
||||
|
||||
/* Define to 1 if you have the <xlocale.h> header file. */
|
||||
/* #undef HAVE_XLOCALE_H */
|
||||
|
||||
/* Define to 1 on AIX */
|
||||
/* #undef HWLOC_AIX_SYS */
|
||||
|
||||
/* Define to 1 on BlueGene/Q */
|
||||
/* #undef HWLOC_BGQ_SYS */
|
||||
|
||||
/* Whether C compiler supports symbol visibility or not */
|
||||
#define HWLOC_C_HAVE_VISIBILITY 0
|
||||
|
||||
/* Define to 1 on Darwin */
|
||||
/* #undef HWLOC_DARWIN_SYS */
|
||||
|
||||
/* Whether we are in debugging mode or not */
|
||||
/* #undef HWLOC_DEBUG */
|
||||
|
||||
/* Define to 1 on *FREEBSD */
|
||||
/* #undef HWLOC_FREEBSD_SYS */
|
||||
|
||||
/* Whether your compiler has __attribute__ or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE 1 */
|
||||
#undef HWLOC_HAVE_ATTRIBUTE
|
||||
|
||||
/* Whether your compiler has __attribute__ aligned or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_ALIGNED 1 */
|
||||
|
||||
/* Whether your compiler has __attribute__ always_inline or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_ALWAYS_INLINE 1 */
|
||||
|
||||
/* Whether your compiler has __attribute__ cold or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_COLD 1 */
|
||||
|
||||
/* Whether your compiler has __attribute__ const or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_CONST 1 */
|
||||
|
||||
/* Whether your compiler has __attribute__ deprecated or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_DEPRECATED 1 */
|
||||
|
||||
/* Whether your compiler has __attribute__ format or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_FORMAT 1 */
|
||||
|
||||
/* Whether your compiler has __attribute__ hot or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_HOT 1 */
|
||||
|
||||
/* Whether your compiler has __attribute__ malloc or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_MALLOC 1 */
|
||||
|
||||
/* Whether your compiler has __attribute__ may_alias or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS 1 */
|
||||
|
||||
/* Whether your compiler has __attribute__ nonnull or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_NONNULL 1 */
|
||||
|
||||
/* Whether your compiler has __attribute__ noreturn or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_NORETURN 1 */
|
||||
|
||||
/* Whether your compiler has __attribute__ no_instrument_function or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_NO_INSTRUMENT_FUNCTION 1 */
|
||||
|
||||
/* Whether your compiler has __attribute__ packed or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_PACKED 1 */
|
||||
|
||||
/* Whether your compiler has __attribute__ pure or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_PURE 1 */
|
||||
|
||||
/* Whether your compiler has __attribute__ sentinel or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_SENTINEL 1 */
|
||||
|
||||
/* Whether your compiler has __attribute__ unused or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_UNUSED 1 */
|
||||
|
||||
/* Whether your compiler has __attribute__ warn unused result or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_WARN_UNUSED_RESULT 1 */
|
||||
|
||||
/* Whether your compiler has __attribute__ weak alias or not */
|
||||
/* #define HWLOC_HAVE_ATTRIBUTE_WEAK_ALIAS 1 */
|
||||
|
||||
/* Define to 1 if your `ffs' function is known to be broken. */
|
||||
/* #undef HWLOC_HAVE_BROKEN_FFS */
|
||||
|
||||
/* Define to 1 if you have the `cairo' library. */
|
||||
/* #undef HWLOC_HAVE_CAIRO */
|
||||
|
||||
/* Define to 1 if you have the `clz' function. */
|
||||
/* #undef HWLOC_HAVE_CLZ */
|
||||
|
||||
/* Define to 1 if you have the `clzl' function. */
|
||||
/* #undef HWLOC_HAVE_CLZL */
|
||||
|
||||
/* Define to 1 if you have cpuid */
|
||||
/* #undef HWLOC_HAVE_CPUID */
|
||||
|
||||
/* Define to 1 if the CPU_SET macro works */
|
||||
/* #undef HWLOC_HAVE_CPU_SET */
|
||||
|
||||
/* Define to 1 if the CPU_SET_S macro works */
|
||||
/* #undef HWLOC_HAVE_CPU_SET_S */
|
||||
|
||||
/* Define to 1 if you have the `cudart' SDK. */
|
||||
/* #undef HWLOC_HAVE_CUDART */
|
||||
|
||||
/* Define to 1 if function `clz' is declared by system headers */
|
||||
/* #undef HWLOC_HAVE_DECL_CLZ */
|
||||
|
||||
/* Define to 1 if function `clzl' is declared by system headers */
|
||||
/* #undef HWLOC_HAVE_DECL_CLZL */
|
||||
|
||||
/* Define to 1 if function `ffs' is declared by system headers */
|
||||
/* #undef HWLOC_HAVE_DECL_FFS */
|
||||
|
||||
/* Define to 1 if function `ffsl' is declared by system headers */
|
||||
/* #undef HWLOC_HAVE_DECL_FFSL */
|
||||
|
||||
/* Define to 1 if function `fls' is declared by system headers */
|
||||
/* #undef HWLOC_HAVE_DECL_FLS */
|
||||
|
||||
/* Define to 1 if function `flsl' is declared by system headers */
|
||||
/* #undef HWLOC_HAVE_DECL_FLSL */
|
||||
|
||||
/* Define to 1 if you have the `ffs' function. */
|
||||
/* #undef HWLOC_HAVE_FFS */
|
||||
|
||||
/* Define to 1 if you have the `ffsl' function. */
|
||||
/* #undef HWLOC_HAVE_FFSL */
|
||||
|
||||
/* Define to 1 if you have the `fls' function. */
|
||||
/* #undef HWLOC_HAVE_FLS */
|
||||
|
||||
/* Define to 1 if you have the `flsl' function. */
|
||||
/* #undef HWLOC_HAVE_FLSL */
|
||||
|
||||
/* Define to 1 if you have the GL module components. */
|
||||
/* #undef HWLOC_HAVE_GL */
|
||||
|
||||
/* Define to 1 if you have a library providing the termcap interface */
|
||||
/* #undef HWLOC_HAVE_LIBTERMCAP */
|
||||
|
||||
/* Define to 1 if you have the `libxml2' library. */
|
||||
/* #undef HWLOC_HAVE_LIBXML2 */
|
||||
|
||||
/* Define to 1 if building the Linux PCI component */
|
||||
/* #undef HWLOC_HAVE_LINUXPCI */
|
||||
|
||||
/* Define to 1 if you have the `NVML' library. */
|
||||
/* #undef HWLOC_HAVE_NVML */
|
||||
|
||||
/* Define to 1 if glibc provides the old prototype (without length) of
|
||||
sched_setaffinity() */
|
||||
/* #undef HWLOC_HAVE_OLD_SCHED_SETAFFINITY */
|
||||
|
||||
/* Define to 1 if you have the `OpenCL' library. */
|
||||
/* #undef HWLOC_HAVE_OPENCL */
|
||||
|
||||
/* Define to 1 if the hwloc library should support dynamically-loaded plugins
|
||||
*/
|
||||
/* #undef HWLOC_HAVE_PLUGINS */
|
||||
|
||||
/* `Define to 1 if you have pthread_getthrds_np' */
|
||||
/* #undef HWLOC_HAVE_PTHREAD_GETTHRDS_NP */
|
||||
|
||||
/* Define to 1 if pthread mutexes are available */
|
||||
/* #undef HWLOC_HAVE_PTHREAD_MUTEX */
|
||||
|
||||
/* Define to 1 if glibc provides a prototype of sched_setaffinity() */
|
||||
#define HWLOC_HAVE_SCHED_SETAFFINITY 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HWLOC_HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the `windows.h' header. */
|
||||
#define HWLOC_HAVE_WINDOWS_H 1
|
||||
|
||||
/* Define to 1 if X11 headers including Xutil.h and keysym.h are available. */
|
||||
/* #undef HWLOC_HAVE_X11_KEYSYM */
|
||||
|
||||
/* Define to 1 if function `syscall' is available */
|
||||
/* #undef HWLOC_HAVE_SYSCALL */
|
||||
|
||||
/* Define to 1 on HP-UX */
|
||||
/* #undef HWLOC_HPUX_SYS */
|
||||
|
||||
/* Define to 1 on Linux */
|
||||
/* #undef HWLOC_LINUX_SYS */
|
||||
|
||||
/* Define to 1 on *NETBSD */
|
||||
/* #undef HWLOC_NETBSD_SYS */
|
||||
|
||||
/* The size of `unsigned int', as computed by sizeof */
|
||||
#define HWLOC_SIZEOF_UNSIGNED_INT 4
|
||||
|
||||
/* The size of `unsigned long', as computed by sizeof */
|
||||
#define HWLOC_SIZEOF_UNSIGNED_LONG 4
|
||||
|
||||
/* Define to 1 on Solaris */
|
||||
/* #undef HWLOC_SOLARIS_SYS */
|
||||
|
||||
/* The hwloc symbol prefix */
|
||||
#define HWLOC_SYM_PREFIX hwloc_
|
||||
|
||||
/* The hwloc symbol prefix in all caps */
|
||||
#define HWLOC_SYM_PREFIX_CAPS HWLOC_
|
||||
|
||||
/* Whether we need to re-define all the hwloc public symbols or not */
|
||||
#define HWLOC_SYM_TRANSFORM 0
|
||||
|
||||
/* Define to 1 on unsupported systems */
|
||||
/* #undef HWLOC_UNSUPPORTED_SYS */
|
||||
|
||||
/* Define to 1 if ncurses works, preferred over curses */
|
||||
/* #undef HWLOC_USE_NCURSES */
|
||||
|
||||
/* Define to 1 on WINDOWS */
|
||||
#define HWLOC_WIN_SYS 1
|
||||
|
||||
/* Define to 1 on x86_32 */
|
||||
/* #undef HWLOC_X86_32_ARCH */
|
||||
|
||||
/* Define to 1 on x86_64 */
|
||||
#define HWLOC_X86_64_ARCH 1
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "hwloc"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "https://www.open-mpi.org/projects/hwloc/"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "hwloc"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "hwloc"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "hwloc"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION HWLOC_VERSION
|
||||
|
||||
/* The size of `unsigned int', as computed by sizeof. */
|
||||
#define SIZEOF_UNSIGNED_INT 4
|
||||
|
||||
/* The size of `unsigned long', as computed by sizeof. */
|
||||
#define SIZEOF_UNSIGNED_LONG 4
|
||||
|
||||
/* The size of `void *', as computed by sizeof. */
|
||||
#define SIZEOF_VOID_P 8
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Enable extensions on HP-UX. */
|
||||
#ifndef _HPUX_SOURCE
|
||||
# define _HPUX_SOURCE 1
|
||||
#endif
|
||||
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
/*
|
||||
#ifndef _ALL_SOURCE
|
||||
# define _ALL_SOURCE 1
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
/*
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
*/
|
||||
/* Enable threading extensions on Solaris. */
|
||||
/*
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# define _POSIX_PTHREAD_SEMANTICS 1
|
||||
#endif
|
||||
*/
|
||||
/* Enable extensions on HP NonStop. */
|
||||
/*
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# define _TANDEM_SOURCE 1
|
||||
#endif
|
||||
*/
|
||||
/* Enable general extensions on Solaris. */
|
||||
/*
|
||||
#ifndef __EXTENSIONS__
|
||||
# define __EXTENSIONS__ 1
|
||||
#endif
|
||||
*/
|
||||
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION HWLOC_VERSION
|
||||
|
||||
/* Define to 1 if the X Window System is missing or not being used. */
|
||||
#define X_DISPLAY_MISSING 1
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
/* #undef _MINIX */
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
/* #undef _POSIX_1_SOURCE */
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
/* #undef _POSIX_SOURCE */
|
||||
|
||||
/* Define this to the process ID type */
|
||||
#define hwloc_pid_t HANDLE
|
||||
|
||||
/* Define this to either strncasecmp or strncmp */
|
||||
#define hwloc_strncasecmp strncasecmp
|
||||
|
||||
/* 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 */
|
||||
45
src/3rdparty/hwloc/include/private/components.h
vendored
45
src/3rdparty/hwloc/include/private/components.h
vendored
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012-2019 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HWLOC_INSIDE_PLUGIN
|
||||
/*
|
||||
* these declarations are internal only, they are not available to plugins
|
||||
* (many functions below are internal static symbols).
|
||||
*/
|
||||
#error This file should not be used in plugins
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef PRIVATE_COMPONENTS_H
|
||||
#define PRIVATE_COMPONENTS_H 1
|
||||
|
||||
#include "hwloc/plugins.h"
|
||||
|
||||
struct hwloc_topology;
|
||||
|
||||
extern int hwloc_disc_component_force_enable(struct hwloc_topology *topology,
|
||||
int envvar_forced, /* 1 if forced through envvar, 0 if forced through API */
|
||||
const char *name,
|
||||
const void *data1, const void *data2, const void *data3);
|
||||
extern void hwloc_disc_components_enable_others(struct hwloc_topology *topology);
|
||||
|
||||
/* Compute the topology is_thissystem flag and find some callbacks based on enabled backends */
|
||||
extern void hwloc_backends_is_thissystem(struct hwloc_topology *topology);
|
||||
extern void hwloc_backends_find_callbacks(struct hwloc_topology *topology);
|
||||
|
||||
/* Initialize the lists of components and backends used by a topology */
|
||||
extern void hwloc_topology_components_init(struct hwloc_topology *topology);
|
||||
/* Disable and destroy all backends used by a topology */
|
||||
extern void hwloc_backends_disable_all(struct hwloc_topology *topology);
|
||||
/* Cleanup the lists of components used by a topology */
|
||||
extern void hwloc_topology_components_fini(struct hwloc_topology *topology);
|
||||
|
||||
/* Used by the core to setup/destroy the list of components */
|
||||
extern void hwloc_components_init(void); /* increases components refcount, should be called exactly once per topology (during init) */
|
||||
extern void hwloc_components_fini(void); /* decreases components refcount, should be called exactly once per topology (during destroy) */
|
||||
|
||||
#endif /* PRIVATE_COMPONENTS_H */
|
||||
|
||||
86
src/3rdparty/hwloc/include/private/cpuid-x86.h
vendored
86
src/3rdparty/hwloc/include/private/cpuid-x86.h
vendored
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2010-2012, 2014 Université Bordeaux
|
||||
* Copyright © 2010 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright © 2014 Inria. All rights reserved.
|
||||
*
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/* Internals for x86's cpuid. */
|
||||
|
||||
#ifndef HWLOC_PRIVATE_CPUID_X86_H
|
||||
#define HWLOC_PRIVATE_CPUID_X86_H
|
||||
|
||||
#if (defined HWLOC_X86_32_ARCH) && (!defined HWLOC_HAVE_MSVC_CPUIDEX)
|
||||
static __hwloc_inline int hwloc_have_x86_cpuid(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned tmp, tmp2;
|
||||
__asm__(
|
||||
"mov $0,%0\n\t" /* Not supported a priori */
|
||||
|
||||
"pushfl \n\t" /* Save flags */
|
||||
|
||||
"pushfl \n\t" \
|
||||
"pop %1 \n\t" /* Get flags */ \
|
||||
|
||||
#define TRY_TOGGLE \
|
||||
"xor $0x00200000,%1\n\t" /* Try to toggle ID */ \
|
||||
"mov %1,%2\n\t" /* Save expected value */ \
|
||||
"push %1 \n\t" \
|
||||
"popfl \n\t" /* Try to toggle */ \
|
||||
"pushfl \n\t" \
|
||||
"pop %1 \n\t" \
|
||||
"cmp %1,%2\n\t" /* Compare with expected value */ \
|
||||
"jnz 0f\n\t" /* Unexpected, failure */ \
|
||||
|
||||
TRY_TOGGLE /* Try to set/clear */
|
||||
TRY_TOGGLE /* Try to clear/set */
|
||||
|
||||
"mov $1,%0\n\t" /* Passed the test! */
|
||||
|
||||
"0: \n\t"
|
||||
"popfl \n\t" /* Restore flags */
|
||||
|
||||
: "=r" (ret), "=&r" (tmp), "=&r" (tmp2));
|
||||
return ret;
|
||||
}
|
||||
#endif /* !defined HWLOC_X86_32_ARCH && !defined HWLOC_HAVE_MSVC_CPUIDEX*/
|
||||
#if (defined HWLOC_X86_64_ARCH) || (defined HWLOC_HAVE_MSVC_CPUIDEX)
|
||||
static __hwloc_inline int hwloc_have_x86_cpuid(void) { return 1; }
|
||||
#endif /* HWLOC_X86_64_ARCH */
|
||||
|
||||
static __hwloc_inline void hwloc_x86_cpuid(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx)
|
||||
{
|
||||
#ifdef HWLOC_HAVE_MSVC_CPUIDEX
|
||||
int regs[4];
|
||||
__cpuidex(regs, *eax, *ecx);
|
||||
*eax = regs[0];
|
||||
*ebx = regs[1];
|
||||
*ecx = regs[2];
|
||||
*edx = regs[3];
|
||||
#else /* HWLOC_HAVE_MSVC_CPUIDEX */
|
||||
/* Note: gcc might want to use bx or the stack for %1 addressing, so we can't
|
||||
* use them :/ */
|
||||
#ifdef HWLOC_X86_64_ARCH
|
||||
hwloc_uint64_t sav_rbx;
|
||||
__asm__(
|
||||
"mov %%rbx,%2\n\t"
|
||||
"cpuid\n\t"
|
||||
"xchg %2,%%rbx\n\t"
|
||||
"movl %k2,%1\n\t"
|
||||
: "+a" (*eax), "=m" (*ebx), "=&r"(sav_rbx),
|
||||
"+c" (*ecx), "=&d" (*edx));
|
||||
#elif defined(HWLOC_X86_32_ARCH)
|
||||
__asm__(
|
||||
"mov %%ebx,%1\n\t"
|
||||
"cpuid\n\t"
|
||||
"xchg %%ebx,%1\n\t"
|
||||
: "+a" (*eax), "=&SD" (*ebx), "+c" (*ecx), "=&d" (*edx));
|
||||
#else
|
||||
#error unknown architecture
|
||||
#endif
|
||||
#endif /* HWLOC_HAVE_MSVC_CPUIDEX */
|
||||
}
|
||||
|
||||
#endif /* HWLOC_PRIVATE_X86_CPUID_H */
|
||||
95
src/3rdparty/hwloc/include/private/debug.h
vendored
95
src/3rdparty/hwloc/include/private/debug.h
vendored
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* The configuration file */
|
||||
|
||||
#ifndef HWLOC_DEBUG_H
|
||||
#define HWLOC_DEBUG_H
|
||||
|
||||
#include "private/autogen/config.h"
|
||||
#include "private/misc.h"
|
||||
|
||||
#ifdef HWLOC_DEBUG
|
||||
#include <stdarg.h>
|
||||
#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)]))
|
||||
|
||||
#ifdef HWLOC_DEBUG
|
||||
static __hwloc_inline int hwloc_debug_enabled(void)
|
||||
{
|
||||
static int checked = 0;
|
||||
static int enabled = 1;
|
||||
if (!checked) {
|
||||
const char *env = getenv("HWLOC_DEBUG_VERBOSE");
|
||||
if (env)
|
||||
enabled = atoi(env);
|
||||
if (enabled)
|
||||
fprintf(stderr, "hwloc verbose debug enabled, may be disabled with HWLOC_DEBUG_VERBOSE=0 in the environment.\n");
|
||||
checked = 1;
|
||||
}
|
||||
return enabled;
|
||||
}
|
||||
#endif
|
||||
|
||||
static __hwloc_inline void hwloc_debug(const char *s __hwloc_attribute_unused, ...) __hwloc_attribute_format(printf, 1, 2);
|
||||
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
|
||||
}
|
||||
|
||||
#ifdef HWLOC_DEBUG
|
||||
#define hwloc_debug_bitmap(fmt, bitmap) do { \
|
||||
if (hwloc_debug_enabled()) { \
|
||||
char *s; \
|
||||
hwloc_bitmap_asprintf(&s, bitmap); \
|
||||
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); \
|
||||
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); \
|
||||
hwloc_debug(fmt, arg1, arg2, s); \
|
||||
free(s); \
|
||||
} } while (0)
|
||||
#else
|
||||
#define hwloc_debug_bitmap(s, bitmap) do { } while(0)
|
||||
#define hwloc_debug_1arg_bitmap(s, arg1, bitmap) do { } while(0)
|
||||
#define hwloc_debug_2args_bitmap(s, arg1, arg2, bitmap) do { } while(0)
|
||||
#endif
|
||||
|
||||
#endif /* HWLOC_DEBUG_H */
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2018-2020 Inria. All rights reserved.
|
||||
*
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/* List of components defined inside hwloc */
|
||||
|
||||
#ifndef PRIVATE_INTERNAL_COMPONENTS_H
|
||||
#define PRIVATE_INTERNAL_COMPONENTS_H
|
||||
|
||||
/* global discovery */
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_synthetic_component;
|
||||
|
||||
/* CPU discovery */
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_aix_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_bgq_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_darwin_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_freebsd_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_hpux_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_linux_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_netbsd_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_noos_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_solaris_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_windows_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_x86_component;
|
||||
|
||||
/* I/O discovery */
|
||||
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_levelzero_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_opencl_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_pci_component;
|
||||
|
||||
/* XML backend */
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_nolibxml_component;
|
||||
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_libxml_component;
|
||||
|
||||
#endif /* PRIVATE_INTERNAL_COMPONENTS_H */
|
||||
576
src/3rdparty/hwloc/include/private/misc.h
vendored
576
src/3rdparty/hwloc/include/private/misc.h
vendored
@@ -1,576 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2019 Inria. All rights reserved.
|
||||
* Copyright © 2009-2012 Université Bordeaux
|
||||
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/* Misc macros and inlines. */
|
||||
|
||||
#ifndef HWLOC_PRIVATE_MISC_H
|
||||
#define HWLOC_PRIVATE_MISC_H
|
||||
|
||||
#include "hwloc/autogen/config.h"
|
||||
#include "private/autogen/config.h"
|
||||
#include "hwloc.h"
|
||||
|
||||
#ifdef HWLOC_HAVE_DECL_STRNCASECMP
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#else
|
||||
#ifdef HAVE_CTYPE_H
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define HWLOC_BITS_PER_LONG (HWLOC_SIZEOF_UNSIGNED_LONG * 8)
|
||||
#define HWLOC_BITS_PER_INT (HWLOC_SIZEOF_UNSIGNED_INT * 8)
|
||||
|
||||
#if (HWLOC_BITS_PER_LONG != 32) && (HWLOC_BITS_PER_LONG != 64)
|
||||
#error "unknown size for unsigned long."
|
||||
#endif
|
||||
|
||||
#if (HWLOC_BITS_PER_INT != 16) && (HWLOC_BITS_PER_INT != 32) && (HWLOC_BITS_PER_INT != 64)
|
||||
#error "unknown size for unsigned int."
|
||||
#endif
|
||||
|
||||
/* internal-use-only value for when we don't know the type or don't have any value */
|
||||
#define HWLOC_OBJ_TYPE_NONE ((hwloc_obj_type_t) -1)
|
||||
|
||||
/**
|
||||
* ffsl helpers.
|
||||
*/
|
||||
|
||||
#if defined(HWLOC_HAVE_BROKEN_FFS)
|
||||
|
||||
/* System has a broken ffs().
|
||||
* We must check the before __GNUC__ or HWLOC_HAVE_FFSL
|
||||
*/
|
||||
# define HWLOC_NO_FFS
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
# if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))
|
||||
/* Starting from 3.4, gcc has a long variant. */
|
||||
# define hwloc_ffsl(x) __builtin_ffsl(x)
|
||||
# else
|
||||
# define hwloc_ffs(x) __builtin_ffs(x)
|
||||
# define HWLOC_NEED_FFSL
|
||||
# endif
|
||||
|
||||
#elif defined(HWLOC_HAVE_FFSL)
|
||||
|
||||
# ifndef HWLOC_HAVE_DECL_FFSL
|
||||
extern int ffsl(long) __hwloc_attribute_const;
|
||||
# endif
|
||||
|
||||
# define hwloc_ffsl(x) ffsl(x)
|
||||
|
||||
#elif defined(HWLOC_HAVE_FFS)
|
||||
|
||||
# ifndef HWLOC_HAVE_DECL_FFS
|
||||
extern int ffs(int) __hwloc_attribute_const;
|
||||
# endif
|
||||
|
||||
# define hwloc_ffs(x) ffs(x)
|
||||
# define HWLOC_NEED_FFSL
|
||||
|
||||
#else /* no ffs implementation */
|
||||
|
||||
# define HWLOC_NO_FFS
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HWLOC_NO_FFS
|
||||
|
||||
/* no ffs or it is known to be broken */
|
||||
static __hwloc_inline int
|
||||
hwloc_ffsl_manual(unsigned long x) __hwloc_attribute_const;
|
||||
static __hwloc_inline int
|
||||
hwloc_ffsl_manual(unsigned long x)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!x)
|
||||
return 0;
|
||||
|
||||
i = 1;
|
||||
#if HWLOC_BITS_PER_LONG >= 64
|
||||
if (!(x & 0xfffffffful)) {
|
||||
x >>= 32;
|
||||
i += 32;
|
||||
}
|
||||
#endif
|
||||
if (!(x & 0xffffu)) {
|
||||
x >>= 16;
|
||||
i += 16;
|
||||
}
|
||||
if (!(x & 0xff)) {
|
||||
x >>= 8;
|
||||
i += 8;
|
||||
}
|
||||
if (!(x & 0xf)) {
|
||||
x >>= 4;
|
||||
i += 4;
|
||||
}
|
||||
if (!(x & 0x3)) {
|
||||
x >>= 2;
|
||||
i += 2;
|
||||
}
|
||||
if (!(x & 0x1)) {
|
||||
x >>= 1;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
/* always define hwloc_ffsl as a macro, to avoid renaming breakage */
|
||||
#define hwloc_ffsl hwloc_ffsl_manual
|
||||
|
||||
#elif defined(HWLOC_NEED_FFSL)
|
||||
|
||||
/* We only have an int ffs(int) implementation, build a long one. */
|
||||
|
||||
/* First make it 32 bits if it was only 16. */
|
||||
static __hwloc_inline int
|
||||
hwloc_ffs32(unsigned long x) __hwloc_attribute_const;
|
||||
static __hwloc_inline int
|
||||
hwloc_ffs32(unsigned long x)
|
||||
{
|
||||
#if HWLOC_BITS_PER_INT == 16
|
||||
int low_ffs, hi_ffs;
|
||||
|
||||
low_ffs = hwloc_ffs(x & 0xfffful);
|
||||
if (low_ffs)
|
||||
return low_ffs;
|
||||
|
||||
hi_ffs = hwloc_ffs(x >> 16);
|
||||
if (hi_ffs)
|
||||
return hi_ffs + 16;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return hwloc_ffs(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Then make it 64 bit if longs are. */
|
||||
static __hwloc_inline int
|
||||
hwloc_ffsl_from_ffs32(unsigned long x) __hwloc_attribute_const;
|
||||
static __hwloc_inline int
|
||||
hwloc_ffsl_from_ffs32(unsigned long x)
|
||||
{
|
||||
#if HWLOC_BITS_PER_LONG == 64
|
||||
int low_ffs, hi_ffs;
|
||||
|
||||
low_ffs = hwloc_ffs32(x & 0xfffffffful);
|
||||
if (low_ffs)
|
||||
return low_ffs;
|
||||
|
||||
hi_ffs = hwloc_ffs32(x >> 32);
|
||||
if (hi_ffs)
|
||||
return hi_ffs + 32;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return hwloc_ffs32(x);
|
||||
#endif
|
||||
}
|
||||
/* always define hwloc_ffsl as a macro, to avoid renaming breakage */
|
||||
#define hwloc_ffsl hwloc_ffsl_from_ffs32
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* flsl helpers.
|
||||
*/
|
||||
#ifdef __GNUC_____
|
||||
|
||||
# if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))
|
||||
# define hwloc_flsl(x) ((x) ? (8*sizeof(long) - __builtin_clzl(x)) : 0)
|
||||
# else
|
||||
# define hwloc_fls(x) ((x) ? (8*sizeof(int) - __builtin_clz(x)) : 0)
|
||||
# define HWLOC_NEED_FLSL
|
||||
# endif
|
||||
|
||||
#elif defined(HWLOC_HAVE_FLSL)
|
||||
|
||||
# ifndef HWLOC_HAVE_DECL_FLSL
|
||||
extern int flsl(long) __hwloc_attribute_const;
|
||||
# endif
|
||||
|
||||
# define hwloc_flsl(x) flsl(x)
|
||||
|
||||
#elif defined(HWLOC_HAVE_CLZL)
|
||||
|
||||
# ifndef HWLOC_HAVE_DECL_CLZL
|
||||
extern int clzl(long) __hwloc_attribute_const;
|
||||
# endif
|
||||
|
||||
# define hwloc_flsl(x) ((x) ? (8*sizeof(long) - clzl(x)) : 0)
|
||||
|
||||
#elif defined(HWLOC_HAVE_FLS)
|
||||
|
||||
# ifndef HWLOC_HAVE_DECL_FLS
|
||||
extern int fls(int) __hwloc_attribute_const;
|
||||
# endif
|
||||
|
||||
# define hwloc_fls(x) fls(x)
|
||||
# define HWLOC_NEED_FLSL
|
||||
|
||||
#elif defined(HWLOC_HAVE_CLZ)
|
||||
|
||||
# ifndef HWLOC_HAVE_DECL_CLZ
|
||||
extern int clz(int) __hwloc_attribute_const;
|
||||
# endif
|
||||
|
||||
# define hwloc_fls(x) ((x) ? (8*sizeof(int) - clz(x)) : 0)
|
||||
# define HWLOC_NEED_FLSL
|
||||
|
||||
#else /* no fls implementation */
|
||||
|
||||
static __hwloc_inline int
|
||||
hwloc_flsl_manual(unsigned long x) __hwloc_attribute_const;
|
||||
static __hwloc_inline int
|
||||
hwloc_flsl_manual(unsigned long x)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (!x)
|
||||
return 0;
|
||||
|
||||
i = 1;
|
||||
#if HWLOC_BITS_PER_LONG >= 64
|
||||
if ((x & 0xffffffff00000000ul)) {
|
||||
x >>= 32;
|
||||
i += 32;
|
||||
}
|
||||
#endif
|
||||
if ((x & 0xffff0000u)) {
|
||||
x >>= 16;
|
||||
i += 16;
|
||||
}
|
||||
if ((x & 0xff00)) {
|
||||
x >>= 8;
|
||||
i += 8;
|
||||
}
|
||||
if ((x & 0xf0)) {
|
||||
x >>= 4;
|
||||
i += 4;
|
||||
}
|
||||
if ((x & 0xc)) {
|
||||
x >>= 2;
|
||||
i += 2;
|
||||
}
|
||||
if ((x & 0x2)) {
|
||||
x >>= 1;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
/* always define hwloc_flsl as a macro, to avoid renaming breakage */
|
||||
#define hwloc_flsl hwloc_flsl_manual
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HWLOC_NEED_FLSL
|
||||
|
||||
/* We only have an int fls(int) implementation, build a long one. */
|
||||
|
||||
/* First make it 32 bits if it was only 16. */
|
||||
static __hwloc_inline int
|
||||
hwloc_fls32(unsigned long x) __hwloc_attribute_const;
|
||||
static __hwloc_inline int
|
||||
hwloc_fls32(unsigned long x)
|
||||
{
|
||||
#if HWLOC_BITS_PER_INT == 16
|
||||
int low_fls, hi_fls;
|
||||
|
||||
hi_fls = hwloc_fls(x >> 16);
|
||||
if (hi_fls)
|
||||
return hi_fls + 16;
|
||||
|
||||
low_fls = hwloc_fls(x & 0xfffful);
|
||||
if (low_fls)
|
||||
return low_fls;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return hwloc_fls(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Then make it 64 bit if longs are. */
|
||||
static __hwloc_inline int
|
||||
hwloc_flsl_from_fls32(unsigned long x) __hwloc_attribute_const;
|
||||
static __hwloc_inline int
|
||||
hwloc_flsl_from_fls32(unsigned long x)
|
||||
{
|
||||
#if HWLOC_BITS_PER_LONG == 64
|
||||
int low_fls, hi_fls;
|
||||
|
||||
hi_fls = hwloc_fls32(x >> 32);
|
||||
if (hi_fls)
|
||||
return hi_fls + 32;
|
||||
|
||||
low_fls = hwloc_fls32(x & 0xfffffffful);
|
||||
if (low_fls)
|
||||
return low_fls;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return hwloc_fls32(x);
|
||||
#endif
|
||||
}
|
||||
/* always define hwloc_flsl as a macro, to avoid renaming breakage */
|
||||
#define hwloc_flsl hwloc_flsl_from_fls32
|
||||
|
||||
#endif
|
||||
|
||||
static __hwloc_inline int
|
||||
hwloc_weight_long(unsigned long w) __hwloc_attribute_const;
|
||||
static __hwloc_inline int
|
||||
hwloc_weight_long(unsigned long w)
|
||||
{
|
||||
#if HWLOC_BITS_PER_LONG == 32
|
||||
#if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__) >= 4)
|
||||
return __builtin_popcount(w);
|
||||
#else
|
||||
unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
|
||||
res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
|
||||
res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
|
||||
res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
|
||||
return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
|
||||
#endif
|
||||
#else /* HWLOC_BITS_PER_LONG == 32 */
|
||||
#if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__) >= 4)
|
||||
return __builtin_popcountll(w);
|
||||
#else
|
||||
unsigned long res;
|
||||
res = (w & 0x5555555555555555ul) + ((w >> 1) & 0x5555555555555555ul);
|
||||
res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
|
||||
res = (res & 0x0F0F0F0F0F0F0F0Ful) + ((res >> 4) & 0x0F0F0F0F0F0F0F0Ful);
|
||||
res = (res & 0x00FF00FF00FF00FFul) + ((res >> 8) & 0x00FF00FF00FF00FFul);
|
||||
res = (res & 0x0000FFFF0000FFFFul) + ((res >> 16) & 0x0000FFFF0000FFFFul);
|
||||
return (res & 0x00000000FFFFFFFFul) + ((res >> 32) & 0x00000000FFFFFFFFul);
|
||||
#endif
|
||||
#endif /* HWLOC_BITS_PER_LONG == 64 */
|
||||
}
|
||||
|
||||
#if !HAVE_DECL_STRTOULL && defined(HAVE_STRTOULL)
|
||||
unsigned long long int strtoull(const char *nptr, char **endptr, int base);
|
||||
#endif
|
||||
|
||||
static __hwloc_inline int hwloc_strncasecmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
#ifdef HWLOC_HAVE_DECL_STRNCASECMP
|
||||
return strncasecmp(s1, s2, n);
|
||||
#else
|
||||
while (n) {
|
||||
char c1 = tolower(*s1), c2 = tolower(*s2);
|
||||
if (!c1 || !c2 || c1 != c2)
|
||||
return c1-c2;
|
||||
n--; s1++; s2++;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static __hwloc_inline hwloc_obj_type_t hwloc_cache_type_by_depth_type(unsigned depth, hwloc_obj_cache_type_t type)
|
||||
{
|
||||
if (type == HWLOC_OBJ_CACHE_INSTRUCTION) {
|
||||
if (depth >= 1 && depth <= 3)
|
||||
return HWLOC_OBJ_L1ICACHE + depth-1;
|
||||
else
|
||||
return HWLOC_OBJ_TYPE_NONE;
|
||||
} else {
|
||||
if (depth >= 1 && depth <= 5)
|
||||
return HWLOC_OBJ_L1CACHE + depth-1;
|
||||
else
|
||||
return HWLOC_OBJ_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
#define HWLOC_BITMAP_EQUAL 0 /* Bitmaps are equal */
|
||||
#define HWLOC_BITMAP_INCLUDED 1 /* First bitmap included in second */
|
||||
#define HWLOC_BITMAP_CONTAINS 2 /* First bitmap contains second */
|
||||
#define HWLOC_BITMAP_INTERSECTS 3 /* Bitmaps intersect without any inclusion */
|
||||
#define HWLOC_BITMAP_DIFFERENT 4 /* Bitmaps do not intersect */
|
||||
|
||||
/* Compare bitmaps \p bitmap1 and \p bitmap2 from an inclusion point of view. */
|
||||
HWLOC_DECLSPEC int hwloc_bitmap_compare_inclusion(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
|
||||
|
||||
/* Return a stringified PCI class. */
|
||||
HWLOC_DECLSPEC extern const char * hwloc_pci_class_string(unsigned short class_id);
|
||||
|
||||
/* Parse a PCI link speed (GT/s) string from Linux sysfs */
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
#include <stdlib.h> /* for atof() */
|
||||
static __hwloc_inline float
|
||||
hwloc_linux_pci_link_speed_from_string(const char *string)
|
||||
{
|
||||
/* don't parse Gen1 with atof() since it expects a localized string
|
||||
* while the kernel sysfs files aren't.
|
||||
*/
|
||||
if (!strncmp(string, "2.5 ", 4))
|
||||
/* "2.5 GT/s" is Gen1 with 8/10 encoding */
|
||||
return 2.5 * .8;
|
||||
|
||||
/* also hardwire Gen2 since it also has a specific encoding */
|
||||
if (!strncmp(string, "5 ", 2))
|
||||
/* "5 GT/s" is Gen2 with 8/10 encoding */
|
||||
return 5 * .8;
|
||||
|
||||
/* handle Gen3+ in a generic way */
|
||||
return atof(string) * 128./130; /* Gen3+ encoding is 128/130 */
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Traverse children of a parent */
|
||||
#define for_each_child(child, parent) for(child = parent->first_child; child; child = child->next_sibling)
|
||||
#define for_each_memory_child(child, parent) for(child = parent->memory_first_child; child; child = child->next_sibling)
|
||||
#define for_each_io_child(child, parent) for(child = parent->io_first_child; child; child = child->next_sibling)
|
||||
#define for_each_misc_child(child, parent) for(child = parent->misc_first_child; child; child = child->next_sibling)
|
||||
|
||||
/* Any object attached to normal children */
|
||||
static __hwloc_inline int hwloc__obj_type_is_normal (hwloc_obj_type_t type)
|
||||
{
|
||||
/* type contiguity is asserted in topology_check() */
|
||||
return type <= HWLOC_OBJ_GROUP || type == HWLOC_OBJ_DIE;
|
||||
}
|
||||
|
||||
/* Any object attached to memory children, currently NUMA nodes or Memory-side caches */
|
||||
static __hwloc_inline int hwloc__obj_type_is_memory (hwloc_obj_type_t type)
|
||||
{
|
||||
/* type contiguity is asserted in topology_check() */
|
||||
return type == HWLOC_OBJ_NUMANODE || type == HWLOC_OBJ_MEMCACHE;
|
||||
}
|
||||
|
||||
/* I/O or Misc object, without cpusets or nodesets. */
|
||||
static __hwloc_inline int hwloc__obj_type_is_special (hwloc_obj_type_t type)
|
||||
{
|
||||
/* type contiguity is asserted in topology_check() */
|
||||
return type >= HWLOC_OBJ_BRIDGE && type <= HWLOC_OBJ_MISC;
|
||||
}
|
||||
|
||||
/* Any object attached to io children */
|
||||
static __hwloc_inline int hwloc__obj_type_is_io (hwloc_obj_type_t type)
|
||||
{
|
||||
/* type contiguity is asserted in topology_check() */
|
||||
return type >= HWLOC_OBJ_BRIDGE && type <= HWLOC_OBJ_OS_DEVICE;
|
||||
}
|
||||
|
||||
/* Any CPU caches (not Memory-side caches) */
|
||||
static __hwloc_inline int
|
||||
hwloc__obj_type_is_cache(hwloc_obj_type_t type)
|
||||
{
|
||||
/* type contiguity is asserted in topology_check() */
|
||||
return (type >= HWLOC_OBJ_L1CACHE && type <= HWLOC_OBJ_L3ICACHE);
|
||||
}
|
||||
|
||||
static __hwloc_inline int
|
||||
hwloc__obj_type_is_dcache(hwloc_obj_type_t type)
|
||||
{
|
||||
/* type contiguity is asserted in topology_check() */
|
||||
return (type >= HWLOC_OBJ_L1CACHE && type <= HWLOC_OBJ_L5CACHE);
|
||||
}
|
||||
|
||||
/** \brief Check whether an object is a Instruction Cache. */
|
||||
static __hwloc_inline int
|
||||
hwloc__obj_type_is_icache(hwloc_obj_type_t type)
|
||||
{
|
||||
/* type contiguity is asserted in topology_check() */
|
||||
return (type >= HWLOC_OBJ_L1ICACHE && type <= HWLOC_OBJ_L3ICACHE);
|
||||
}
|
||||
|
||||
#ifdef HAVE_USELOCALE
|
||||
#include "locale.h"
|
||||
#ifdef HAVE_XLOCALE_H
|
||||
#include "xlocale.h"
|
||||
#endif
|
||||
#define hwloc_localeswitch_declare locale_t __old_locale = (locale_t)0, __new_locale
|
||||
#define hwloc_localeswitch_init() do { \
|
||||
__new_locale = newlocale(LC_ALL_MASK, "C", (locale_t)0); \
|
||||
if (__new_locale != (locale_t)0) \
|
||||
__old_locale = uselocale(__new_locale); \
|
||||
} while (0)
|
||||
#define hwloc_localeswitch_fini() do { \
|
||||
if (__new_locale != (locale_t)0) { \
|
||||
uselocale(__old_locale); \
|
||||
freelocale(__new_locale); \
|
||||
} \
|
||||
} while(0)
|
||||
#else /* HAVE_USELOCALE */
|
||||
#if HWLOC_HAVE_ATTRIBUTE_UNUSED
|
||||
#define hwloc_localeswitch_declare int __dummy_nolocale __hwloc_attribute_unused
|
||||
#define hwloc_localeswitch_init()
|
||||
#else
|
||||
#define hwloc_localeswitch_declare int __dummy_nolocale
|
||||
#define hwloc_localeswitch_init() (void)__dummy_nolocale
|
||||
#endif
|
||||
#define hwloc_localeswitch_fini()
|
||||
#endif /* HAVE_USELOCALE */
|
||||
|
||||
#if !HAVE_DECL_FABSF
|
||||
#define fabsf(f) fabs((double)(f))
|
||||
#endif
|
||||
|
||||
#if !HAVE_DECL_MODFF
|
||||
#define modff(x,iptr) (float)modf((double)x,(double *)iptr)
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL__SC_PAGE_SIZE
|
||||
#define hwloc_getpagesize() sysconf(_SC_PAGE_SIZE)
|
||||
#elif HAVE_DECL__SC_PAGESIZE
|
||||
#define hwloc_getpagesize() sysconf(_SC_PAGESIZE)
|
||||
#elif defined HAVE_GETPAGESIZE
|
||||
#define hwloc_getpagesize() getpagesize()
|
||||
#else
|
||||
#undef hwloc_getpagesize
|
||||
#endif
|
||||
|
||||
#if HWLOC_HAVE_ATTRIBUTE_FORMAT
|
||||
# define __hwloc_attribute_format(type, str, arg) __attribute__((__format__(type, str, arg)))
|
||||
#else
|
||||
# define __hwloc_attribute_format(type, str, arg)
|
||||
#endif
|
||||
|
||||
#define hwloc_memory_size_printf_value(_size, _verbose) \
|
||||
((_size) < (10ULL<<20) || (_verbose) ? (((_size)>>9)+1)>>1 : (_size) < (10ULL<<30) ? (((_size)>>19)+1)>>1 : (_size) < (10ULL<<40) ? (((_size)>>29)+1)>>1 : (((_size)>>39)+1)>>1)
|
||||
#define hwloc_memory_size_printf_unit(_size, _verbose) \
|
||||
((_size) < (10ULL<<20) || (_verbose) ? "KB" : (_size) < (10ULL<<30) ? "MB" : (_size) < (10ULL<<40) ? "GB" : "TB")
|
||||
|
||||
#ifdef HWLOC_WIN_SYS
|
||||
# ifndef HAVE_SSIZE_T
|
||||
typedef SSIZE_T ssize_t;
|
||||
# endif
|
||||
# if !HAVE_DECL_STRTOULL && !defined(HAVE_STRTOULL)
|
||||
# define strtoull _strtoui64
|
||||
# endif
|
||||
# ifndef S_ISREG
|
||||
# define S_ISREG(m) ((m) & S_IFREG)
|
||||
# endif
|
||||
# ifndef S_ISDIR
|
||||
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
# endif
|
||||
# ifndef S_IRWXU
|
||||
# define S_IRWXU 00700
|
||||
# endif
|
||||
# ifndef HWLOC_HAVE_DECL_STRCASECMP
|
||||
# define strcasecmp _stricmp
|
||||
# endif
|
||||
# if !HAVE_DECL_SNPRINTF
|
||||
# define snprintf _snprintf
|
||||
# endif
|
||||
# if HAVE_DECL__STRDUP
|
||||
# define strdup _strdup
|
||||
# endif
|
||||
# if HAVE_DECL__PUTENV
|
||||
# define putenv _putenv
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* HWLOC_PRIVATE_MISC_H */
|
||||
578
src/3rdparty/hwloc/include/private/netloc.h
vendored
578
src/3rdparty/hwloc/include/private/netloc.h
vendored
@@ -1,578 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2014 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright © 2013-2014 University of Wisconsin-La Crosse.
|
||||
* All rights reserved.
|
||||
* Copyright © 2015-2017 Inria. All rights reserved.
|
||||
*
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
* See COPYING in top-level directory.
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#ifndef _NETLOC_PRIVATE_H_
|
||||
#define _NETLOC_PRIVATE_H_
|
||||
|
||||
#include <hwloc.h>
|
||||
#include <netloc.h>
|
||||
#include <netloc/uthash.h>
|
||||
#include <netloc/utarray.h>
|
||||
#include <private/autogen/config.h>
|
||||
|
||||
#define NETLOCFILE_VERSION 1
|
||||
|
||||
#ifdef NETLOC_SCOTCH
|
||||
#include <stdint.h>
|
||||
#include <scotch.h>
|
||||
#define NETLOC_int SCOTCH_Num
|
||||
#else
|
||||
#define NETLOC_int int
|
||||
#endif
|
||||
|
||||
/*
|
||||
* "Import" a few things from hwloc
|
||||
*/
|
||||
#define __netloc_attribute_unused __hwloc_attribute_unused
|
||||
#define __netloc_attribute_malloc __hwloc_attribute_malloc
|
||||
#define __netloc_attribute_const __hwloc_attribute_const
|
||||
#define __netloc_attribute_pure __hwloc_attribute_pure
|
||||
#define __netloc_attribute_deprecated __hwloc_attribute_deprecated
|
||||
#define __netloc_attribute_may_alias __hwloc_attribute_may_alias
|
||||
#define NETLOC_DECLSPEC HWLOC_DECLSPEC
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Types
|
||||
**********************************************************************/
|
||||
|
||||
/**
|
||||
* Definitions for Comparators
|
||||
* \sa These are the return values from the following functions:
|
||||
* netloc_network_compare, netloc_dt_edge_t_compare, netloc_dt_node_t_compare
|
||||
*/
|
||||
typedef enum {
|
||||
NETLOC_CMP_SAME = 0, /**< Compared as the Same */
|
||||
NETLOC_CMP_SIMILAR = -1, /**< Compared as Similar, but not the Same */
|
||||
NETLOC_CMP_DIFF = -2 /**< Compared as Different */
|
||||
} netloc_compare_type_t;
|
||||
|
||||
/**
|
||||
* Enumerated type for the various types of supported networks
|
||||
*/
|
||||
typedef enum {
|
||||
NETLOC_NETWORK_TYPE_ETHERNET = 1, /**< Ethernet network */
|
||||
NETLOC_NETWORK_TYPE_INFINIBAND = 2, /**< InfiniBand network */
|
||||
NETLOC_NETWORK_TYPE_INVALID = 3 /**< Invalid network */
|
||||
} netloc_network_type_t;
|
||||
|
||||
/**
|
||||
* Enumerated type for the various types of supported topologies
|
||||
*/
|
||||
typedef enum {
|
||||
NETLOC_TOPOLOGY_TYPE_INVALID = -1, /**< Invalid */
|
||||
NETLOC_TOPOLOGY_TYPE_TREE = 1, /**< Tree */
|
||||
} netloc_topology_type_t;
|
||||
|
||||
/**
|
||||
* Enumerated type for the various types of nodes
|
||||
*/
|
||||
typedef enum {
|
||||
NETLOC_NODE_TYPE_HOST = 0, /**< Host (a.k.a., network addressable endpoint - e.g., MAC Address) node */
|
||||
NETLOC_NODE_TYPE_SWITCH = 1, /**< Switch node */
|
||||
NETLOC_NODE_TYPE_INVALID = 2 /**< Invalid node */
|
||||
} netloc_node_type_t;
|
||||
|
||||
typedef enum {
|
||||
NETLOC_ARCH_TREE = 0, /* Fat tree */
|
||||
} netloc_arch_type_t;
|
||||
|
||||
|
||||
/* Pre declarations to avoid inter dependency problems */
|
||||
/** \cond IGNORE */
|
||||
struct netloc_topology_t;
|
||||
typedef struct netloc_topology_t netloc_topology_t;
|
||||
struct netloc_node_t;
|
||||
typedef struct netloc_node_t netloc_node_t;
|
||||
struct netloc_edge_t;
|
||||
typedef struct netloc_edge_t netloc_edge_t;
|
||||
struct netloc_physical_link_t;
|
||||
typedef struct netloc_physical_link_t netloc_physical_link_t;
|
||||
struct netloc_path_t;
|
||||
typedef struct netloc_path_t netloc_path_t;
|
||||
|
||||
struct netloc_arch_tree_t;
|
||||
typedef struct netloc_arch_tree_t netloc_arch_tree_t;
|
||||
struct netloc_arch_node_t;
|
||||
typedef struct netloc_arch_node_t netloc_arch_node_t;
|
||||
struct netloc_arch_node_slot_t;
|
||||
typedef struct netloc_arch_node_slot_t netloc_arch_node_slot_t;
|
||||
struct netloc_arch_t;
|
||||
typedef struct netloc_arch_t netloc_arch_t;
|
||||
/** \endcond */
|
||||
|
||||
/**
|
||||
* \struct netloc_topology_t
|
||||
* \brief Netloc Topology Context
|
||||
*
|
||||
* An opaque data structure used to reference a network topology.
|
||||
*
|
||||
* \note Must be initialized with \ref netloc_topology_construct()
|
||||
*/
|
||||
struct netloc_topology_t {
|
||||
/** Topology path */
|
||||
char *topopath;
|
||||
/** Subnet ID */
|
||||
char *subnet_id;
|
||||
|
||||
/** Node List */
|
||||
netloc_node_t *nodes; /* Hash table of nodes by physical_id */
|
||||
netloc_node_t *nodesByHostname; /* Hash table of nodes by hostname */
|
||||
|
||||
netloc_physical_link_t *physical_links; /* Hash table with physcial links */
|
||||
|
||||
/** Partition List */
|
||||
UT_array *partitions;
|
||||
|
||||
/** Hwloc topology List */
|
||||
char *hwlocpath;
|
||||
UT_array *topos;
|
||||
hwloc_topology_t *hwloc_topos;
|
||||
|
||||
/** Type of the graph */
|
||||
netloc_topology_type_t type;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Netloc Node Type
|
||||
*
|
||||
* Represents the concept of a node (a.k.a., vertex, endpoint) within a network
|
||||
* graph. This could be a server or a network switch. The \ref node_type parameter
|
||||
* will distinguish the exact type of node this represents in the graph.
|
||||
*/
|
||||
struct netloc_node_t {
|
||||
UT_hash_handle hh; /* makes this structure hashable with physical_id */
|
||||
UT_hash_handle hh2; /* makes this structure hashable with hostname */
|
||||
|
||||
/** Physical ID of the node */
|
||||
char physical_id[20];
|
||||
|
||||
/** Logical ID of the node (if any) */
|
||||
int logical_id;
|
||||
|
||||
/** Type of the node */
|
||||
netloc_node_type_t type;
|
||||
|
||||
/* Pointer to physical_links */
|
||||
UT_array *physical_links;
|
||||
|
||||
/** Description information from discovery (if any) */
|
||||
char *description;
|
||||
|
||||
/**
|
||||
* Application-given private data pointer.
|
||||
* Initialized to NULL, and not used by the netloc library.
|
||||
*/
|
||||
void * userdata;
|
||||
|
||||
/** Outgoing edges from this node */
|
||||
netloc_edge_t *edges;
|
||||
|
||||
UT_array *subnodes; /* the group of nodes for the virtual nodes */
|
||||
|
||||
netloc_path_t *paths;
|
||||
|
||||
char *hostname;
|
||||
|
||||
UT_array *partitions; /* index in the list from the topology */
|
||||
|
||||
hwloc_topology_t hwlocTopo;
|
||||
int hwlocTopoIdx;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Netloc Edge Type
|
||||
*
|
||||
* Represents the concept of a directed edge within a network graph.
|
||||
*
|
||||
* \note We do not point to the netloc_node_t structure directly to
|
||||
* simplify the representation, and allow the information to more easily
|
||||
* be entered into the data store without circular references.
|
||||
* \todo JJH Is the note above still true?
|
||||
*/
|
||||
struct netloc_edge_t {
|
||||
UT_hash_handle hh; /* makes this structure hashable */
|
||||
|
||||
netloc_node_t *dest;
|
||||
|
||||
int id;
|
||||
|
||||
/** Pointers to the parent node */
|
||||
netloc_node_t *node;
|
||||
|
||||
/* Pointer to physical_links */
|
||||
UT_array *physical_links;
|
||||
|
||||
/** total gbits of the links */
|
||||
float total_gbits;
|
||||
|
||||
UT_array *partitions; /* index in the list from the topology */
|
||||
|
||||
UT_array *subnode_edges; /* for edges going to virtual nodes */
|
||||
|
||||
struct netloc_edge_t *other_way;
|
||||
|
||||
/**
|
||||
* Application-given private data pointer.
|
||||
* Initialized to NULL, and not used by the netloc library.
|
||||
*/
|
||||
void * userdata;
|
||||
};
|
||||
|
||||
|
||||
struct netloc_physical_link_t {
|
||||
UT_hash_handle hh; /* makes this structure hashable */
|
||||
|
||||
int id; // TODO long long
|
||||
netloc_node_t *src;
|
||||
netloc_node_t *dest;
|
||||
int ports[2];
|
||||
char *width;
|
||||
char *speed;
|
||||
|
||||
netloc_edge_t *edge;
|
||||
|
||||
int other_way_id;
|
||||
struct netloc_physical_link_t *other_way;
|
||||
|
||||
UT_array *partitions; /* index in the list from the topology */
|
||||
|
||||
/** gbits of the link from speed and width */
|
||||
float gbits;
|
||||
|
||||
/** Description information from discovery (if any) */
|
||||
char *description;
|
||||
};
|
||||
|
||||
struct netloc_path_t {
|
||||
UT_hash_handle hh; /* makes this structure hashable */
|
||||
char dest_id[20];
|
||||
UT_array *links;
|
||||
};
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Architecture structures
|
||||
**********************************************************************/
|
||||
struct netloc_arch_tree_t {
|
||||
NETLOC_int num_levels;
|
||||
NETLOC_int *degrees;
|
||||
NETLOC_int *cost;
|
||||
};
|
||||
|
||||
struct netloc_arch_node_t {
|
||||
UT_hash_handle hh; /* makes this structure hashable */
|
||||
char *name; /* Hash key */
|
||||
netloc_node_t *node; /* Corresponding node */
|
||||
int idx_in_topo; /* idx with ghost hosts to have complete topo */
|
||||
int num_slots; /* it is not the real number of slots but the maximum slot idx */
|
||||
int *slot_idx; /* corresponding idx in slot_tree */
|
||||
int *slot_os_idx; /* corresponding os index for each leaf in tree */
|
||||
netloc_arch_tree_t *slot_tree; /* Tree built from hwloc */
|
||||
int num_current_slots; /* Number of PUs */
|
||||
NETLOC_int *current_slots; /* indices in the complete tree */
|
||||
int *slot_ranks; /* corresponding MPI rank for each leaf in tree */
|
||||
};
|
||||
|
||||
struct netloc_arch_node_slot_t {
|
||||
netloc_arch_node_t *node;
|
||||
int slot;
|
||||
};
|
||||
|
||||
struct netloc_arch_t {
|
||||
netloc_topology_t *topology;
|
||||
int has_slots; /* if slots are included in the architecture */
|
||||
netloc_arch_type_t type;
|
||||
union {
|
||||
netloc_arch_tree_t *node_tree;
|
||||
netloc_arch_tree_t *global_tree;
|
||||
} arch;
|
||||
netloc_arch_node_t *nodes_by_name;
|
||||
netloc_arch_node_slot_t *node_slot_by_idx; /* node_slot by index in complete topo */
|
||||
NETLOC_int num_current_hosts; /* if has_slots, host is a slot, else host is a node */
|
||||
NETLOC_int *current_hosts; /* indices in the complete topology */
|
||||
};
|
||||
|
||||
/**********************************************************************
|
||||
* Topology Functions
|
||||
**********************************************************************/
|
||||
/**
|
||||
* Allocate a topology handle.
|
||||
*
|
||||
* User is responsible for calling \ref netloc_detach on the topology handle.
|
||||
* The network parameter information is deep copied into the topology handle, so the
|
||||
* user may destruct the network handle after calling this function and/or reuse
|
||||
* the network handle.
|
||||
*
|
||||
* \returns NETLOC_SUCCESS on success
|
||||
* \returns NETLOC_ERROR upon an error.
|
||||
*/
|
||||
netloc_topology_t *netloc_topology_construct(char *path);
|
||||
|
||||
/**
|
||||
* Destruct a topology handle
|
||||
*
|
||||
* \param topology A valid pointer to a \ref netloc_topology_t handle created
|
||||
* from a prior call to \ref netloc_topology_construct.
|
||||
*
|
||||
* \returns NETLOC_SUCCESS on success
|
||||
* \returns NETLOC_ERROR upon an error.
|
||||
*/
|
||||
int netloc_topology_destruct(netloc_topology_t *topology);
|
||||
|
||||
int netloc_topology_find_partition_idx(netloc_topology_t *topology, char *partition_name);
|
||||
|
||||
int netloc_topology_read_hwloc(netloc_topology_t *topology, int num_nodes,
|
||||
netloc_node_t **node_list);
|
||||
|
||||
#define netloc_topology_iter_partitions(topology,partition) \
|
||||
for ((partition) = (char **)utarray_front(topology->partitions); \
|
||||
(partition) != NULL; \
|
||||
(partition) = (char **)utarray_next(topology->partitions, partition))
|
||||
|
||||
#define netloc_topology_iter_hwloctopos(topology,hwloctopo) \
|
||||
for ((hwloctopo) = (char **)utarray_front(topology->topos); \
|
||||
(hwloctopo) != NULL; \
|
||||
(hwloctopo) = (char **)utarray_next(topology->topos, hwloctopo))
|
||||
|
||||
#define netloc_topology_find_node(topology,node_id,node) \
|
||||
HASH_FIND_STR(topology->nodes, node_id, node)
|
||||
|
||||
#define netloc_topology_iter_nodes(topology,node,_tmp) \
|
||||
HASH_ITER(hh, topology->nodes, node, _tmp)
|
||||
|
||||
#define netloc_topology_num_nodes(topology) \
|
||||
HASH_COUNT(topology->nodes)
|
||||
|
||||
/*************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for netloc_node_t
|
||||
*
|
||||
* User is responsible for calling the destructor on the handle.
|
||||
*
|
||||
* Returns
|
||||
* A newly allocated pointer to the network information.
|
||||
*/
|
||||
netloc_node_t *netloc_node_construct(void);
|
||||
|
||||
/**
|
||||
* Destructor for netloc_node_t
|
||||
*
|
||||
* \param node A valid node handle
|
||||
*
|
||||
* Returns
|
||||
* NETLOC_SUCCESS on success
|
||||
* NETLOC_ERROR on error
|
||||
*/
|
||||
int netloc_node_destruct(netloc_node_t *node);
|
||||
|
||||
char *netloc_node_pretty_print(netloc_node_t* node);
|
||||
|
||||
#define netloc_node_get_num_subnodes(node) \
|
||||
utarray_len((node)->subnodes)
|
||||
|
||||
#define netloc_node_get_subnode(node,i) \
|
||||
(*(netloc_node_t **)utarray_eltptr((node)->subnodes, (i)))
|
||||
|
||||
#define netloc_node_get_num_edges(node) \
|
||||
utarray_len((node)->edges)
|
||||
|
||||
#define netloc_node_get_edge(node,i) \
|
||||
(*(netloc_edge_t **)utarray_eltptr((node)->edges, (i)))
|
||||
|
||||
#define netloc_node_iter_edges(node,edge,_tmp) \
|
||||
HASH_ITER(hh, node->edges, edge, _tmp)
|
||||
|
||||
#define netloc_node_iter_paths(node,path,_tmp) \
|
||||
HASH_ITER(hh, node->paths, path, _tmp)
|
||||
|
||||
#define netloc_node_is_host(node) \
|
||||
(node->type == NETLOC_NODE_TYPE_HOST)
|
||||
|
||||
#define netloc_node_is_switch(node) \
|
||||
(node->type == NETLOC_NODE_TYPE_SWITCH)
|
||||
|
||||
#define netloc_node_iter_paths(node, path,_tmp) \
|
||||
HASH_ITER(hh, node->paths, path, _tmp)
|
||||
|
||||
int netloc_node_is_in_partition(netloc_node_t *node, int partition);
|
||||
|
||||
/*************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for netloc_edge_t
|
||||
*
|
||||
* User is responsible for calling the destructor on the handle.
|
||||
*
|
||||
* Returns
|
||||
* A newly allocated pointer to the edge information.
|
||||
*/
|
||||
netloc_edge_t *netloc_edge_construct(void);
|
||||
|
||||
/**
|
||||
* Destructor for netloc_edge_t
|
||||
*
|
||||
* \param edge A valid edge handle
|
||||
*
|
||||
* Returns
|
||||
* NETLOC_SUCCESS on success
|
||||
* NETLOC_ERROR on error
|
||||
*/
|
||||
int netloc_edge_destruct(netloc_edge_t *edge);
|
||||
|
||||
char * netloc_edge_pretty_print(netloc_edge_t* edge);
|
||||
|
||||
void netloc_edge_reset_uid(void);
|
||||
|
||||
int netloc_edge_is_in_partition(netloc_edge_t *edge, int partition);
|
||||
|
||||
#define netloc_edge_get_num_links(edge) \
|
||||
utarray_len((edge)->physical_links)
|
||||
|
||||
#define netloc_edge_get_link(edge,i) \
|
||||
(*(netloc_physical_link_t **)utarray_eltptr((edge)->physical_links, (i)))
|
||||
|
||||
#define netloc_edge_get_num_subedges(edge) \
|
||||
utarray_len((edge)->subnode_edges)
|
||||
|
||||
#define netloc_edge_get_subedge(edge,i) \
|
||||
(*(netloc_edge_t **)utarray_eltptr((edge)->subnode_edges, (i)))
|
||||
|
||||
/*************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for netloc_physical_link_t
|
||||
*
|
||||
* User is responsible for calling the destructor on the handle.
|
||||
*
|
||||
* Returns
|
||||
* A newly allocated pointer to the physical link information.
|
||||
*/
|
||||
netloc_physical_link_t * netloc_physical_link_construct(void);
|
||||
|
||||
/**
|
||||
* Destructor for netloc_physical_link_t
|
||||
*
|
||||
* Returns
|
||||
* NETLOC_SUCCESS on success
|
||||
* NETLOC_ERROR on error
|
||||
*/
|
||||
int netloc_physical_link_destruct(netloc_physical_link_t *link);
|
||||
|
||||
char * netloc_link_pretty_print(netloc_physical_link_t* link);
|
||||
|
||||
/*************************************************/
|
||||
|
||||
|
||||
netloc_path_t *netloc_path_construct(void);
|
||||
int netloc_path_destruct(netloc_path_t *path);
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Architecture functions
|
||||
**********************************************************************/
|
||||
|
||||
netloc_arch_t * netloc_arch_construct(void);
|
||||
|
||||
int netloc_arch_destruct(netloc_arch_t *arch);
|
||||
|
||||
int netloc_arch_build(netloc_arch_t *arch, int add_slots);
|
||||
|
||||
int netloc_arch_set_current_resources(netloc_arch_t *arch);
|
||||
|
||||
int netloc_arch_set_global_resources(netloc_arch_t *arch);
|
||||
|
||||
int netloc_arch_node_get_hwloc_info(netloc_arch_node_t *arch);
|
||||
|
||||
void netloc_arch_tree_complete(netloc_arch_tree_t *tree, UT_array **down_degrees_by_level,
|
||||
int num_hosts, int **parch_idx);
|
||||
|
||||
NETLOC_int netloc_arch_tree_num_leaves(netloc_arch_tree_t *tree);
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Access functions of various elements of the topology
|
||||
**********************************************************************/
|
||||
|
||||
#define netloc_get_num_partitions(object) \
|
||||
utarray_len((object)->partitions)
|
||||
|
||||
#define netloc_get_partition(object,i) \
|
||||
(*(int *)utarray_eltptr((object)->partitions, (i)))
|
||||
|
||||
|
||||
#define netloc_path_iter_links(path,link) \
|
||||
for ((link) = (netloc_physical_link_t **)utarray_front(path->links); \
|
||||
(link) != NULL; \
|
||||
(link) = (netloc_physical_link_t **)utarray_next(path->links, link))
|
||||
|
||||
/**********************************************************************
|
||||
* Misc functions
|
||||
**********************************************************************/
|
||||
|
||||
/**
|
||||
* Decode the network type
|
||||
*
|
||||
* \param net_type A valid member of the \ref netloc_network_type_t type
|
||||
*
|
||||
* \returns NULL if the type is invalid
|
||||
* \returns A string for that \ref netloc_network_type_t type
|
||||
*/
|
||||
static inline const char * netloc_network_type_decode(netloc_network_type_t net_type) {
|
||||
if( NETLOC_NETWORK_TYPE_ETHERNET == net_type ) {
|
||||
return "ETH";
|
||||
}
|
||||
else if( NETLOC_NETWORK_TYPE_INFINIBAND == net_type ) {
|
||||
return "IB";
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the node type
|
||||
*
|
||||
* \param node_type A valid member of the \ref netloc_node_type_t type
|
||||
*
|
||||
* \returns NULL if the type is invalid
|
||||
* \returns A string for that \ref netloc_node_type_t type
|
||||
*/
|
||||
static inline const char * netloc_node_type_decode(netloc_node_type_t node_type) {
|
||||
if( NETLOC_NODE_TYPE_SWITCH == node_type ) {
|
||||
return "SW";
|
||||
}
|
||||
else if( NETLOC_NODE_TYPE_HOST == node_type ) {
|
||||
return "CA";
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t netloc_line_get(char **lineptr, size_t *n, FILE *stream);
|
||||
|
||||
char *netloc_line_get_next_token(char **string, char c);
|
||||
|
||||
int netloc_build_comm_mat(char *filename, int *pn, double ***pmat);
|
||||
|
||||
#define STRDUP_IF_NOT_NULL(str) (NULL == str ? NULL : strdup(str))
|
||||
#define STR_EMPTY_IF_NULL(str) (NULL == str ? "" : str)
|
||||
|
||||
|
||||
#endif // _NETLOC_PRIVATE_H_
|
||||
535
src/3rdparty/hwloc/include/private/private.h
vendored
535
src/3rdparty/hwloc/include/private/private.h
vendored
@@ -1,535 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2021 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.
|
||||
*/
|
||||
|
||||
/* Internal types and helpers. */
|
||||
|
||||
|
||||
#ifdef HWLOC_INSIDE_PLUGIN
|
||||
/*
|
||||
* these declarations are internal only, they are not available to plugins
|
||||
* (many functions below are internal static symbols).
|
||||
*/
|
||||
#error This file should not be used in plugins
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HWLOC_PRIVATE_H
|
||||
#define HWLOC_PRIVATE_H
|
||||
|
||||
#include "private/autogen/config.h"
|
||||
#include "hwloc.h"
|
||||
#include "hwloc/bitmap.h"
|
||||
#include "private/components.h"
|
||||
#include "private/misc.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_UTSNAME_H
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#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:
|
||||
* changes below in this structure (and its children)
|
||||
* should cause a bump of HWLOC_TOPOLOGY_ABI.
|
||||
*****************************************************/
|
||||
|
||||
struct hwloc_topology {
|
||||
unsigned topology_abi;
|
||||
|
||||
unsigned nb_levels; /* Number of horizontal levels */
|
||||
unsigned nb_levels_allocated; /* Number of levels allocated and zeroed in level_nbobjects and levels below */
|
||||
unsigned *level_nbobjects; /* Number of objects on each horizontal level */
|
||||
struct hwloc_obj ***levels; /* Direct access to levels, levels[l = 0 .. nblevels-1][0..level_nbobjects[l]] */
|
||||
unsigned long flags;
|
||||
int type_depth[HWLOC_OBJ_TYPE_MAX];
|
||||
enum hwloc_type_filter_e type_filter[HWLOC_OBJ_TYPE_MAX];
|
||||
int is_thissystem;
|
||||
int is_loaded;
|
||||
int modified; /* >0 if objects were added/removed recently, which means a reconnect is needed */
|
||||
hwloc_pid_t pid; /* Process ID the topology is view from, 0 for self */
|
||||
void *userdata;
|
||||
uint64_t next_gp_index;
|
||||
|
||||
void *adopted_shmem_addr;
|
||||
size_t adopted_shmem_length;
|
||||
|
||||
#define HWLOC_NR_SLEVELS 6
|
||||
#define HWLOC_SLEVEL_NUMANODE 0
|
||||
#define HWLOC_SLEVEL_BRIDGE 1
|
||||
#define HWLOC_SLEVEL_PCIDEV 2
|
||||
#define HWLOC_SLEVEL_OSDEV 3
|
||||
#define HWLOC_SLEVEL_MISC 4
|
||||
#define HWLOC_SLEVEL_MEMCACHE 5
|
||||
/* order must match negative depth, it's asserted in setup_defaults() */
|
||||
#define HWLOC_SLEVEL_FROM_DEPTH(x) (HWLOC_TYPE_DEPTH_NUMANODE-(x))
|
||||
#define HWLOC_SLEVEL_TO_DEPTH(x) (HWLOC_TYPE_DEPTH_NUMANODE-(x))
|
||||
struct hwloc_special_level_s {
|
||||
unsigned nbobjs;
|
||||
struct hwloc_obj **objs;
|
||||
struct hwloc_obj *first, *last; /* Temporarily used while listing object before building the objs array */
|
||||
} slevels[HWLOC_NR_SLEVELS];
|
||||
|
||||
hwloc_bitmap_t allowed_cpuset;
|
||||
hwloc_bitmap_t allowed_nodeset;
|
||||
|
||||
struct hwloc_binding_hooks {
|
||||
/* These are actually rather OS hooks since some of them are not about binding */
|
||||
int (*set_thisproc_cpubind)(hwloc_topology_t topology, hwloc_const_cpuset_t set, int flags);
|
||||
int (*get_thisproc_cpubind)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);
|
||||
int (*set_thisthread_cpubind)(hwloc_topology_t topology, hwloc_const_cpuset_t set, int flags);
|
||||
int (*get_thisthread_cpubind)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);
|
||||
int (*set_proc_cpubind)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_cpuset_t set, int flags);
|
||||
int (*get_proc_cpubind)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_cpuset_t set, int flags);
|
||||
#ifdef hwloc_thread_t
|
||||
int (*set_thread_cpubind)(hwloc_topology_t topology, hwloc_thread_t tid, hwloc_const_cpuset_t set, int flags);
|
||||
int (*get_thread_cpubind)(hwloc_topology_t topology, hwloc_thread_t tid, hwloc_cpuset_t set, int flags);
|
||||
#endif
|
||||
|
||||
int (*get_thisproc_last_cpu_location)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);
|
||||
int (*get_thisthread_last_cpu_location)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);
|
||||
int (*get_proc_last_cpu_location)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_cpuset_t set, int flags);
|
||||
|
||||
int (*set_thisproc_membind)(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags);
|
||||
int (*get_thisproc_membind)(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags);
|
||||
int (*set_thisthread_membind)(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags);
|
||||
int (*get_thisthread_membind)(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags);
|
||||
int (*set_proc_membind)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags);
|
||||
int (*get_proc_membind)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags);
|
||||
int (*set_area_membind)(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags);
|
||||
int (*get_area_membind)(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags);
|
||||
int (*get_area_memlocation)(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, int flags);
|
||||
/* This has to return the same kind of pointer as alloc_membind, so that free_membind can be used on it */
|
||||
void *(*alloc)(hwloc_topology_t topology, size_t len);
|
||||
/* alloc_membind has to always succeed if !(flags & HWLOC_MEMBIND_STRICT).
|
||||
* see hwloc_alloc_or_fail which is convenient for that. */
|
||||
void *(*alloc_membind)(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags);
|
||||
int (*free_membind)(hwloc_topology_t topology, void *addr, size_t len);
|
||||
|
||||
int (*get_allowed_resources)(hwloc_topology_t topology);
|
||||
} binding_hooks;
|
||||
|
||||
struct hwloc_topology_support support;
|
||||
|
||||
void (*userdata_export_cb)(void *reserved, struct hwloc_topology *topology, struct hwloc_obj *obj);
|
||||
void (*userdata_import_cb)(struct hwloc_topology *topology, struct hwloc_obj *obj, const char *name, const void *buffer, size_t length);
|
||||
int userdata_not_decoded;
|
||||
|
||||
struct hwloc_internal_distances_s {
|
||||
char *name; /* FIXME: needs an API to set it from user */
|
||||
|
||||
unsigned id; /* to match the container id field of public distances structure
|
||||
* not exported to XML, regenerated during _add()
|
||||
*/
|
||||
|
||||
/* if all objects have the same type, different_types is NULL and unique_type is valid.
|
||||
* otherwise unique_type is HWLOC_OBJ_TYPE_NONE and different_types contains individual objects types.
|
||||
*/
|
||||
hwloc_obj_type_t unique_type;
|
||||
hwloc_obj_type_t *different_types;
|
||||
|
||||
/* add union hwloc_obj_attr_u if we ever support groups */
|
||||
unsigned nbobjs;
|
||||
uint64_t *indexes; /* array of OS or GP indexes before we can convert them into objs.
|
||||
* OS indexes for distances covering only PUs or only NUMAnodes.
|
||||
*/
|
||||
#define HWLOC_DIST_TYPE_USE_OS_INDEX(_type) ((_type) == HWLOC_OBJ_PU || (_type == HWLOC_OBJ_NUMANODE))
|
||||
uint64_t *values; /* distance matrices, ordered according to the above indexes/objs array.
|
||||
* distance from i to j is stored in slot i*nbnodes+j.
|
||||
*/
|
||||
unsigned long kind;
|
||||
|
||||
#define HWLOC_INTERNAL_DIST_FLAG_OBJS_VALID (1U<<0) /* if the objs array is valid below */
|
||||
#define HWLOC_INTERNAL_DIST_FLAG_NOT_COMMITTED (1U<<1) /* if the distances isn't in the list yet */
|
||||
unsigned iflags;
|
||||
|
||||
/* objects are currently stored in physical_index order */
|
||||
hwloc_obj_t *objs; /* array of objects */
|
||||
|
||||
struct hwloc_internal_distances_s *prev, *next;
|
||||
} *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;
|
||||
float grouping_accuracies[5];
|
||||
unsigned grouping_next_subkind;
|
||||
|
||||
/* list of enabled backends. */
|
||||
struct hwloc_backend * backends;
|
||||
struct hwloc_backend * get_pci_busid_cpuset_backend; /* first backend that provides get_pci_busid_cpuset() callback */
|
||||
unsigned backend_phases;
|
||||
unsigned backend_excluded_phases;
|
||||
|
||||
/* memory allocator for topology objects */
|
||||
struct hwloc_tma * tma;
|
||||
|
||||
/*****************************************************
|
||||
* WARNING:
|
||||
* changes above in this structure (and its children)
|
||||
* should cause a bump of HWLOC_TOPOLOGY_ABI.
|
||||
*****************************************************/
|
||||
|
||||
/*
|
||||
* temporary variables during discovery
|
||||
*/
|
||||
|
||||
/* machine-wide memory.
|
||||
* temporarily stored there by OSes that only provide this without NUMA information,
|
||||
* and actually used later by the core.
|
||||
*/
|
||||
struct hwloc_numanode_attr_s machine_memory;
|
||||
|
||||
/* pci stuff */
|
||||
int pci_has_forced_locality;
|
||||
unsigned pci_forced_locality_nr;
|
||||
struct hwloc_pci_forced_locality_s {
|
||||
unsigned domain;
|
||||
unsigned bus_first, bus_last;
|
||||
hwloc_bitmap_t cpuset;
|
||||
} * pci_forced_locality;
|
||||
|
||||
/* component blacklisting */
|
||||
unsigned nr_blacklisted_components;
|
||||
struct hwloc_topology_forced_component_s {
|
||||
struct hwloc_disc_component *component;
|
||||
unsigned phases;
|
||||
} *blacklisted_components;
|
||||
|
||||
/* FIXME: keep until topo destroy and reuse for finding specific buses */
|
||||
struct hwloc_pci_locality_s {
|
||||
unsigned domain;
|
||||
unsigned bus_min;
|
||||
unsigned bus_max;
|
||||
hwloc_bitmap_t cpuset;
|
||||
hwloc_obj_t parent;
|
||||
struct hwloc_pci_locality_s *prev, *next;
|
||||
} *first_pci_locality, *last_pci_locality;
|
||||
};
|
||||
|
||||
extern void hwloc_alloc_root_sets(hwloc_obj_t root);
|
||||
extern void hwloc_setup_pu_level(struct hwloc_topology *topology, unsigned nb_pus);
|
||||
extern int hwloc_get_sysctlbyname(const char *name, int64_t *n);
|
||||
extern int hwloc_get_sysctl(int name[], unsigned namelen, int64_t *n);
|
||||
|
||||
/* returns the number of CPU from the OS (only valid if thissystem) */
|
||||
#define HWLOC_FALLBACK_NBPROCESSORS_INCLUDE_OFFLINE 1 /* by default we try to get only the online CPUs */
|
||||
extern int hwloc_fallback_nbprocessors(unsigned flags);
|
||||
/* returns the memory size from the OS (only valid if thissystem) */
|
||||
extern int64_t hwloc_fallback_memsize(void);
|
||||
|
||||
extern int hwloc__object_cpusets_compare_first(hwloc_obj_t obj1, hwloc_obj_t obj2);
|
||||
extern void hwloc__reorder_children(hwloc_obj_t parent);
|
||||
|
||||
extern void hwloc_topology_setup_defaults(struct hwloc_topology *topology);
|
||||
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, 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);
|
||||
extern void hwloc_pci_discovery_exit(struct hwloc_topology *topology);
|
||||
|
||||
/* Look for an object matching complete cpuset exactly, or insert one.
|
||||
* Return NULL on failure.
|
||||
* Return a good fallback (object above) on failure to insert.
|
||||
*/
|
||||
extern hwloc_obj_t hwloc_find_insert_io_parent_by_complete_cpuset(struct hwloc_topology *topology, hwloc_cpuset_t cpuset);
|
||||
|
||||
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 */
|
||||
extern void hwloc_set_native_binding_hooks(struct hwloc_binding_hooks *hooks, struct hwloc_topology_support *support);
|
||||
/* set either native OS binding hooks (if thissystem), or dummy ones */
|
||||
extern void hwloc_set_binding_hooks(struct hwloc_topology *topology);
|
||||
|
||||
#if defined(HWLOC_LINUX_SYS)
|
||||
extern void hwloc_set_linuxfs_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
|
||||
#endif /* HWLOC_LINUX_SYS */
|
||||
|
||||
#if defined(HWLOC_BGQ_SYS)
|
||||
extern void hwloc_set_bgq_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
|
||||
#endif /* HWLOC_BGQ_SYS */
|
||||
|
||||
#ifdef HWLOC_SOLARIS_SYS
|
||||
extern void hwloc_set_solaris_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
|
||||
#endif /* HWLOC_SOLARIS_SYS */
|
||||
|
||||
#ifdef HWLOC_AIX_SYS
|
||||
extern void hwloc_set_aix_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
|
||||
#endif /* HWLOC_AIX_SYS */
|
||||
|
||||
#ifdef HWLOC_WIN_SYS
|
||||
extern void hwloc_set_windows_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
|
||||
#endif /* HWLOC_WIN_SYS */
|
||||
|
||||
#ifdef HWLOC_DARWIN_SYS
|
||||
extern void hwloc_set_darwin_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
|
||||
#endif /* HWLOC_DARWIN_SYS */
|
||||
|
||||
#ifdef HWLOC_FREEBSD_SYS
|
||||
extern void hwloc_set_freebsd_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
|
||||
#endif /* HWLOC_FREEBSD_SYS */
|
||||
|
||||
#ifdef HWLOC_NETBSD_SYS
|
||||
extern void hwloc_set_netbsd_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
|
||||
#endif /* HWLOC_NETBSD_SYS */
|
||||
|
||||
#ifdef HWLOC_HPUX_SYS
|
||||
extern void hwloc_set_hpux_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
|
||||
#endif /* HWLOC_HPUX_SYS */
|
||||
|
||||
extern int hwloc_look_hardwired_fujitsu_k(struct hwloc_topology *topology);
|
||||
extern int hwloc_look_hardwired_fujitsu_fx10(struct hwloc_topology *topology);
|
||||
extern int hwloc_look_hardwired_fujitsu_fx100(struct hwloc_topology *topology);
|
||||
|
||||
/* Insert uname-specific names/values in the object infos array.
|
||||
* If cached_uname isn't NULL, it is used as a struct utsname instead of recalling uname.
|
||||
* Any field that starts with \0 is ignored.
|
||||
*/
|
||||
extern void hwloc_add_uname_info(struct hwloc_topology *topology, void *cached_uname);
|
||||
|
||||
/* Free obj and its attributes assuming it's not linked to a parent and doesn't have any child */
|
||||
extern void hwloc_free_unlinked_object(hwloc_obj_t obj);
|
||||
|
||||
/* Free obj and its children, assuming it's not linked to a parent */
|
||||
extern void hwloc_free_object_and_children(hwloc_obj_t obj);
|
||||
|
||||
/* Free obj, its next siblings, and their children, assuming they're not linked to a parent */
|
||||
extern void hwloc_free_object_siblings_and_children(hwloc_obj_t obj);
|
||||
|
||||
/* This can be used for the alloc field to get allocated data that can be freed by free() */
|
||||
void *hwloc_alloc_heap(hwloc_topology_t topology, size_t len);
|
||||
|
||||
/* This can be used for the alloc field to get allocated data that can be freed by munmap() */
|
||||
void *hwloc_alloc_mmap(hwloc_topology_t topology, size_t len);
|
||||
|
||||
/* This can be used for the free_membind field to free data using free() */
|
||||
int hwloc_free_heap(hwloc_topology_t topology, void *addr, size_t len);
|
||||
|
||||
/* This can be used for the free_membind field to free data using munmap() */
|
||||
int hwloc_free_mmap(hwloc_topology_t topology, void *addr, size_t len);
|
||||
|
||||
/* Allocates unbound memory or fail, depending on whether STRICT is requested
|
||||
* or not */
|
||||
static __hwloc_inline void *
|
||||
hwloc_alloc_or_fail(hwloc_topology_t topology, size_t len, int flags)
|
||||
{
|
||||
if (flags & HWLOC_MEMBIND_STRICT)
|
||||
return NULL;
|
||||
return hwloc_alloc(topology, len);
|
||||
}
|
||||
|
||||
extern void hwloc_internal_distances_init(hwloc_topology_t topology);
|
||||
extern void hwloc_internal_distances_prepare(hwloc_topology_t topology);
|
||||
extern void hwloc_internal_distances_destroy(hwloc_topology_t topology);
|
||||
extern int hwloc_internal_distances_dup(hwloc_topology_t new, hwloc_topology_t old);
|
||||
extern void hwloc_internal_distances_refresh(hwloc_topology_t topology);
|
||||
extern void hwloc_internal_distances_invalidate_cached_objs(hwloc_topology_t topology);
|
||||
|
||||
/* these distances_add() functions are higher-level than those in hwloc/plugins.h
|
||||
* but they may change in the future, hence they are not exported to plugins.
|
||||
*/
|
||||
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 int hwloc_internal_distances_add(hwloc_topology_t topology, const char *name, unsigned nbobjs, hwloc_obj_t *objs, uint64_t *values, unsigned long kind, unsigned long flags);
|
||||
|
||||
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.
|
||||
*/
|
||||
extern int hwloc_encode_to_base64(const char *src, size_t srclength, char *target, size_t targsize);
|
||||
/* decode src buffer into target buffer.
|
||||
* src is 0-terminated.
|
||||
* targsize must be at least srclength*3/4+1 (srclength not including \0)
|
||||
* but only srclength*3/4 characters will be meaningful
|
||||
* (the next one may be partially written during decoding, but it should be ignored).
|
||||
*/
|
||||
extern int hwloc_decode_from_base64(char const *src, char *target, size_t targsize);
|
||||
|
||||
/* On some systems, snprintf returns the size of written data, not the actually
|
||||
* required size. Sometimes it returns -1 on truncation too.
|
||||
* And sometimes it doesn't like NULL output buffers.
|
||||
* http://www.gnu.org/software/gnulib/manual/html_node/snprintf.html
|
||||
*
|
||||
* hwloc_snprintf behaves properly, but it's a bit overkill on the vast majority
|
||||
* of platforms, so don't enable it unless really needed.
|
||||
*/
|
||||
#ifdef HWLOC_HAVE_CORRECT_SNPRINTF
|
||||
#define hwloc_snprintf snprintf
|
||||
#else
|
||||
extern int hwloc_snprintf(char *str, size_t size, const char *format, ...) __hwloc_attribute_format(printf, 3, 4);
|
||||
#endif
|
||||
|
||||
/* Return the name of the currently running program, if supported.
|
||||
* If not NULL, must be freed by the caller.
|
||||
*/
|
||||
extern char * hwloc_progname(struct hwloc_topology *topology);
|
||||
|
||||
/* obj->attr->group.kind internal values.
|
||||
* the core will keep the smallest ones when merging two groups,
|
||||
* that's why user-given kinds are first.
|
||||
*/
|
||||
/* first, user-given groups, should remain as long as possible */
|
||||
#define HWLOC_GROUP_KIND_USER 0 /* user-given, user may use subkind too */
|
||||
#define HWLOC_GROUP_KIND_SYNTHETIC 10 /* subkind is group depth within synthetic description */
|
||||
/* then, hardware-specific groups */
|
||||
#define HWLOC_GROUP_KIND_INTEL_KNL_SUBNUMA_CLUSTER 100 /* no subkind */
|
||||
#define HWLOC_GROUP_KIND_INTEL_EXTTOPOENUM_UNKNOWN 101 /* subkind is unknown level */
|
||||
#define HWLOC_GROUP_KIND_INTEL_MODULE 102 /* no subkind */
|
||||
#define HWLOC_GROUP_KIND_INTEL_TILE 103 /* no subkind */
|
||||
#define HWLOC_GROUP_KIND_INTEL_DIE 104 /* no subkind */
|
||||
#define HWLOC_GROUP_KIND_S390_BOOK 110 /* subkind 0 is book, subkind 1 is drawer (group of books) */
|
||||
#define HWLOC_GROUP_KIND_AMD_COMPUTE_UNIT 120 /* no subkind */
|
||||
/* then, OS-specific groups */
|
||||
#define HWLOC_GROUP_KIND_SOLARIS_PG_HW_PERF 200 /* subkind is group width */
|
||||
#define HWLOC_GROUP_KIND_AIX_SDL_UNKNOWN 210 /* subkind is SDL level */
|
||||
#define HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP 220 /* no subkind */
|
||||
#define HWLOC_GROUP_KIND_WINDOWS_RELATIONSHIP_UNKNOWN 221 /* no subkind */
|
||||
#define HWLOC_GROUP_KIND_LINUX_CLUSTER 222 /* no subkind */
|
||||
/* distance groups */
|
||||
#define HWLOC_GROUP_KIND_DISTANCE 900 /* subkind is round of adding these groups during distance based grouping */
|
||||
/* finally, hwloc-specific groups required to insert something else, should disappear as soon as possible */
|
||||
#define HWLOC_GROUP_KIND_IO 1000 /* no subkind */
|
||||
#define HWLOC_GROUP_KIND_MEMORY 1001 /* no subkind */
|
||||
|
||||
/* memory allocator for topology objects */
|
||||
struct hwloc_tma {
|
||||
void * (*malloc)(struct hwloc_tma *, size_t);
|
||||
void *data;
|
||||
int dontfree; /* when set, free() or realloc() cannot be used, and tma->malloc() cannot fail */
|
||||
};
|
||||
|
||||
static __hwloc_inline void *
|
||||
hwloc_tma_malloc(struct hwloc_tma *tma,
|
||||
size_t size)
|
||||
{
|
||||
if (tma) {
|
||||
return tma->malloc(tma, size);
|
||||
} else {
|
||||
return malloc(size);
|
||||
}
|
||||
}
|
||||
|
||||
static __hwloc_inline void *
|
||||
hwloc_tma_calloc(struct hwloc_tma *tma,
|
||||
size_t size)
|
||||
{
|
||||
char *ptr = hwloc_tma_malloc(tma, size);
|
||||
if (ptr)
|
||||
memset(ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static __hwloc_inline char *
|
||||
hwloc_tma_strdup(struct hwloc_tma *tma,
|
||||
const char *src)
|
||||
{
|
||||
size_t len = strlen(src);
|
||||
char *ptr = hwloc_tma_malloc(tma, len+1);
|
||||
if (ptr)
|
||||
memcpy(ptr, src, len+1);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* bitmap allocator to be used inside hwloc */
|
||||
extern hwloc_bitmap_t hwloc_bitmap_tma_dup(struct hwloc_tma *tma, hwloc_const_bitmap_t old);
|
||||
|
||||
extern int hwloc__topology_dup(hwloc_topology_t *newp, hwloc_topology_t old, struct hwloc_tma *tma);
|
||||
extern void hwloc__topology_disadopt(hwloc_topology_t topology);
|
||||
|
||||
#endif /* HWLOC_PRIVATE_H */
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009-2010 Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Copyright © 2017 Inria. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HWLOC_INSIDE_PLUGIN
|
||||
/*
|
||||
* these declarations are internal only, they are not available to plugins
|
||||
* (functions below are internal static symbols).
|
||||
*/
|
||||
#error This file should not be used in plugins
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HWLOC_PRIVATE_SOLARIS_CHIPTYPE_H
|
||||
#define HWLOC_PRIVATE_SOLARIS_CHIPTYPE_H
|
||||
|
||||
struct hwloc_solaris_chip_info_s {
|
||||
char *model;
|
||||
char *type;
|
||||
/* L1i, L1d, L2, L3 */
|
||||
#define HWLOC_SOLARIS_CHIP_INFO_L1I 0
|
||||
#define HWLOC_SOLARIS_CHIP_INFO_L1D 1
|
||||
#define HWLOC_SOLARIS_CHIP_INFO_L2I 2
|
||||
#define HWLOC_SOLARIS_CHIP_INFO_L2D 3
|
||||
#define HWLOC_SOLARIS_CHIP_INFO_L3 4
|
||||
long cache_size[5]; /* cleared to -1 if we don't want of that cache */
|
||||
unsigned cache_linesize[5];
|
||||
unsigned cache_associativity[5];
|
||||
int l2_unified;
|
||||
};
|
||||
|
||||
/* fills the structure with 0 on error */
|
||||
extern void hwloc_solaris_get_chip_info(struct hwloc_solaris_chip_info_s *info);
|
||||
|
||||
#endif /* HWLOC_PRIVATE_SOLARIS_CHIPTYPE_H */
|
||||
21
src/3rdparty/hwloc/include/private/windows.h
vendored
21
src/3rdparty/hwloc/include/private/windows.h
vendored
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 Université Bordeaux
|
||||
* Copyright © 2020 Inria. All rights reserved.
|
||||
*
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_PRIVATE_WINDOWS_H
|
||||
#define HWLOC_PRIVATE_WINDOWS_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define _ANONYMOUS_UNION __extension__
|
||||
#define _ANONYMOUS_STRUCT __extension__
|
||||
#else
|
||||
#define _ANONYMOUS_UNION
|
||||
#define _ANONYMOUS_STRUCT
|
||||
#endif /* __GNUC__ */
|
||||
#define DUMMYUNIONNAME
|
||||
#define DUMMYSTRUCTNAME
|
||||
|
||||
#endif /* HWLOC_PRIVATE_WINDOWS_H */
|
||||
107
src/3rdparty/hwloc/include/private/xml.h
vendored
107
src/3rdparty/hwloc/include/private/xml.h
vendored
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009-2017 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef PRIVATE_XML_H
|
||||
#define PRIVATE_XML_H 1
|
||||
|
||||
#include "hwloc.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
HWLOC_DECLSPEC int hwloc__xml_verbose(void);
|
||||
|
||||
/**************
|
||||
* XML import *
|
||||
**************/
|
||||
|
||||
typedef struct hwloc__xml_import_state_s {
|
||||
struct hwloc__xml_import_state_s *parent;
|
||||
|
||||
/* globals shared because the entire stack of states during import */
|
||||
struct hwloc_xml_backend_data_s *global;
|
||||
|
||||
/* opaque data used to store backend-specific data.
|
||||
* statically allocated to allow stack-allocation by the common code without knowing actual backend needs.
|
||||
*/
|
||||
char data[32];
|
||||
} * hwloc__xml_import_state_t;
|
||||
|
||||
struct hwloc__xml_imported_v1distances_s {
|
||||
unsigned long kind;
|
||||
unsigned nbobjs;
|
||||
float *floats;
|
||||
struct hwloc__xml_imported_v1distances_s *prev, *next;
|
||||
};
|
||||
|
||||
HWLOC_DECLSPEC int hwloc__xml_import_diff(hwloc__xml_import_state_t state, hwloc_topology_diff_t *firstdiffp);
|
||||
|
||||
struct hwloc_xml_backend_data_s {
|
||||
/* xml backend parameters */
|
||||
int (*look_init)(struct hwloc_xml_backend_data_s *bdata, struct hwloc__xml_import_state_s *state);
|
||||
void (*look_done)(struct hwloc_xml_backend_data_s *bdata, int result);
|
||||
void (*backend_exit)(struct hwloc_xml_backend_data_s *bdata);
|
||||
int (*next_attr)(struct hwloc__xml_import_state_s * state, char **namep, char **valuep);
|
||||
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, 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 */
|
||||
unsigned version_major, version_minor;
|
||||
unsigned nbnumanodes;
|
||||
hwloc_obj_t first_numanode, last_numanode; /* temporary cousin-list for handling v1distances */
|
||||
struct hwloc__xml_imported_v1distances_s *first_v1dist, *last_v1dist;
|
||||
};
|
||||
|
||||
/**************
|
||||
* XML export *
|
||||
**************/
|
||||
|
||||
typedef struct hwloc__xml_export_state_s {
|
||||
struct hwloc__xml_export_state_s *parent;
|
||||
|
||||
void (*new_child)(struct hwloc__xml_export_state_s *parentstate, struct hwloc__xml_export_state_s *state, const char *name);
|
||||
void (*new_prop)(struct hwloc__xml_export_state_s *state, const char *name, const char *value);
|
||||
void (*add_content)(struct hwloc__xml_export_state_s *state, const char *buffer, size_t length);
|
||||
void (*end_object)(struct hwloc__xml_export_state_s *state, const char *name);
|
||||
|
||||
struct hwloc__xml_export_data_s {
|
||||
hwloc_obj_t v1_memory_group; /* if we need to insert intermediate group above memory children when exporting to v1 */
|
||||
} *global;
|
||||
|
||||
/* opaque data used to store backend-specific data.
|
||||
* statically allocated to allow stack-allocation by the common code without knowing actual backend needs.
|
||||
*/
|
||||
char data[40];
|
||||
} * hwloc__xml_export_state_t;
|
||||
|
||||
HWLOC_DECLSPEC void hwloc__xml_export_topology(hwloc__xml_export_state_t parentstate, hwloc_topology_t topology, unsigned long flags);
|
||||
|
||||
HWLOC_DECLSPEC void hwloc__xml_export_diff(hwloc__xml_export_state_t parentstate, hwloc_topology_diff_t diff);
|
||||
|
||||
/******************
|
||||
* XML components *
|
||||
******************/
|
||||
|
||||
struct hwloc_xml_callbacks {
|
||||
int (*backend_init)(struct hwloc_xml_backend_data_s *bdata, const char *xmlpath, const char *xmlbuffer, int xmlbuflen);
|
||||
int (*export_file)(struct hwloc_topology *topology, struct hwloc__xml_export_data_s *edata, const char *filename, unsigned long flags);
|
||||
int (*export_buffer)(struct hwloc_topology *topology, struct hwloc__xml_export_data_s *edata, char **xmlbuffer, int *buflen, unsigned long flags);
|
||||
void (*free_buffer)(void *xmlbuffer);
|
||||
int (*import_diff)(struct hwloc__xml_import_state_s *state, const char *xmlpath, const char *xmlbuffer, int xmlbuflen, hwloc_topology_diff_t *diff, char **refnamep);
|
||||
int (*export_diff_file)(union hwloc_topology_diff_u *diff, const char *refname, const char *filename);
|
||||
int (*export_diff_buffer)(union hwloc_topology_diff_u *diff, const char *refname, char **xmlbuffer, int *buflen);
|
||||
};
|
||||
|
||||
struct hwloc_xml_component {
|
||||
struct hwloc_xml_callbacks *nolibxml_callbacks;
|
||||
struct hwloc_xml_callbacks *libxml_callbacks;
|
||||
};
|
||||
|
||||
HWLOC_DECLSPEC void hwloc_xml_callbacks_register(struct hwloc_xml_component *component);
|
||||
HWLOC_DECLSPEC void hwloc_xml_callbacks_reset(void);
|
||||
|
||||
#endif /* PRIVATE_XML_H */
|
||||
309
src/3rdparty/hwloc/src/base64.c
vendored
309
src/3rdparty/hwloc/src/base64.c
vendored
@@ -1,309 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012-2018 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*
|
||||
* Modifications after import:
|
||||
* - removed all #if
|
||||
* - updated prototypes
|
||||
* - updated #include
|
||||
*/
|
||||
|
||||
/* include hwloc's config before anything else
|
||||
* so that extensions and features are properly enabled
|
||||
*/
|
||||
#include "private/private.h"
|
||||
|
||||
/* $OpenBSD: base64.c,v 1.5 2006/10/21 09:55:03 otto Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1995 by International Business Machines, Inc.
|
||||
*
|
||||
* International Business Machines, Inc. (hereinafter called IBM) grants
|
||||
* permission under its copyrights to use, copy, modify, and distribute this
|
||||
* Software with or without fee, provided that the above copyright notice and
|
||||
* all paragraphs of this notice appear in all copies, and that the name of IBM
|
||||
* not be used in connection with the marketing of any product incorporating
|
||||
* the Software or modifications thereof, without specific, written prior
|
||||
* permission.
|
||||
*
|
||||
* To the extent it has a right to do so, IBM grants an immunity from suit
|
||||
* under its patents, if any, for the use, sale or manufacture of products to
|
||||
* the extent that such products are used for performing Domain Name System
|
||||
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
|
||||
* granted for any product per se or for any other function of any product.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
|
||||
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
|
||||
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
/* OPENBSD ORIGINAL: lib/libc/net/base64.c */
|
||||
|
||||
static const char Base64[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
static const char Pad64 = '=';
|
||||
|
||||
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
|
||||
The following encoding technique is taken from RFC 1521 by Borenstein
|
||||
and Freed. It is reproduced here in a slightly edited form for
|
||||
convenience.
|
||||
|
||||
A 65-character subset of US-ASCII is used, enabling 6 bits to be
|
||||
represented per printable character. (The extra 65th character, "=",
|
||||
is used to signify a special processing function.)
|
||||
|
||||
The encoding process represents 24-bit groups of input bits as output
|
||||
strings of 4 encoded characters. Proceeding from left to right, a
|
||||
24-bit input group is formed by concatenating 3 8-bit input groups.
|
||||
These 24 bits are then treated as 4 concatenated 6-bit groups, each
|
||||
of which is translated into a single digit in the base64 alphabet.
|
||||
|
||||
Each 6-bit group is used as an index into an array of 64 printable
|
||||
characters. The character referenced by the index is placed in the
|
||||
output string.
|
||||
|
||||
Table 1: The Base64 Alphabet
|
||||
|
||||
Value Encoding Value Encoding Value Encoding Value Encoding
|
||||
0 A 17 R 34 i 51 z
|
||||
1 B 18 S 35 j 52 0
|
||||
2 C 19 T 36 k 53 1
|
||||
3 D 20 U 37 l 54 2
|
||||
4 E 21 V 38 m 55 3
|
||||
5 F 22 W 39 n 56 4
|
||||
6 G 23 X 40 o 57 5
|
||||
7 H 24 Y 41 p 58 6
|
||||
8 I 25 Z 42 q 59 7
|
||||
9 J 26 a 43 r 60 8
|
||||
10 K 27 b 44 s 61 9
|
||||
11 L 28 c 45 t 62 +
|
||||
12 M 29 d 46 u 63 /
|
||||
13 N 30 e 47 v
|
||||
14 O 31 f 48 w (pad) =
|
||||
15 P 32 g 49 x
|
||||
16 Q 33 h 50 y
|
||||
|
||||
Special processing is performed if fewer than 24 bits are available
|
||||
at the end of the data being encoded. A full encoding quantum is
|
||||
always completed at the end of a quantity. When fewer than 24 input
|
||||
bits are available in an input group, zero bits are added (on the
|
||||
right) to form an integral number of 6-bit groups. Padding at the
|
||||
end of the data is performed using the '=' character.
|
||||
|
||||
Since all base64 input is an integral number of octets, only the
|
||||
-------------------------------------------------
|
||||
following cases can arise:
|
||||
|
||||
(1) the final quantum of encoding input is an integral
|
||||
multiple of 24 bits; here, the final unit of encoded
|
||||
output will be an integral multiple of 4 characters
|
||||
with no "=" padding,
|
||||
(2) the final quantum of encoding input is exactly 8 bits;
|
||||
here, the final unit of encoded output will be two
|
||||
characters followed by two "=" padding characters, or
|
||||
(3) the final quantum of encoding input is exactly 16 bits;
|
||||
here, the final unit of encoded output will be three
|
||||
characters followed by one "=" padding character.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
int
|
||||
hwloc_encode_to_base64(const char *src, size_t srclength, char *target, size_t targsize)
|
||||
{
|
||||
size_t datalength = 0;
|
||||
unsigned char input[3];
|
||||
unsigned char output[4];
|
||||
unsigned int i;
|
||||
|
||||
while (2 < srclength) {
|
||||
input[0] = *src++;
|
||||
input[1] = *src++;
|
||||
input[2] = *src++;
|
||||
srclength -= 3;
|
||||
|
||||
output[0] = input[0] >> 2;
|
||||
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
|
||||
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
|
||||
output[3] = input[2] & 0x3f;
|
||||
|
||||
if (datalength + 4 > targsize)
|
||||
return (-1);
|
||||
target[datalength++] = Base64[output[0]];
|
||||
target[datalength++] = Base64[output[1]];
|
||||
target[datalength++] = Base64[output[2]];
|
||||
target[datalength++] = Base64[output[3]];
|
||||
}
|
||||
|
||||
/* Now we worry about padding. */
|
||||
if (0 != srclength) {
|
||||
/* Get what's left. */
|
||||
input[0] = input[1] = input[2] = '\0';
|
||||
for (i = 0; i < srclength; i++)
|
||||
input[i] = *src++;
|
||||
|
||||
output[0] = input[0] >> 2;
|
||||
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
|
||||
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
|
||||
|
||||
if (datalength + 4 > targsize)
|
||||
return (-1);
|
||||
target[datalength++] = Base64[output[0]];
|
||||
target[datalength++] = Base64[output[1]];
|
||||
if (srclength == 1)
|
||||
target[datalength++] = Pad64;
|
||||
else
|
||||
target[datalength++] = Base64[output[2]];
|
||||
target[datalength++] = Pad64;
|
||||
}
|
||||
if (datalength >= targsize)
|
||||
return (-1);
|
||||
target[datalength] = '\0'; /* Returned value doesn't count \0. */
|
||||
return (int)(datalength);
|
||||
}
|
||||
|
||||
/* skips all whitespace anywhere.
|
||||
converts characters, four at a time, starting at (or after)
|
||||
src from base - 64 numbers into three 8 bit bytes in the target area.
|
||||
it returns the number of data bytes stored at the target, or -1 on error.
|
||||
*/
|
||||
|
||||
int
|
||||
hwloc_decode_from_base64(char const *src, char *target, size_t targsize)
|
||||
{
|
||||
unsigned int tarindex, state;
|
||||
int ch;
|
||||
char *pos;
|
||||
|
||||
state = 0;
|
||||
tarindex = 0;
|
||||
|
||||
while ((ch = *src++) != '\0') {
|
||||
if (isspace(ch)) /* Skip whitespace anywhere. */
|
||||
continue;
|
||||
|
||||
if (ch == Pad64)
|
||||
break;
|
||||
|
||||
pos = strchr(Base64, ch);
|
||||
if (pos == 0) /* A non-base64 character. */
|
||||
return (-1);
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (target) {
|
||||
if (tarindex >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] = (char)(pos - Base64) << 2;
|
||||
}
|
||||
state = 1;
|
||||
break;
|
||||
case 1:
|
||||
if (target) {
|
||||
if (tarindex + 1 >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= (pos - Base64) >> 4;
|
||||
target[tarindex+1] = ((pos - Base64) & 0x0f)
|
||||
<< 4 ;
|
||||
}
|
||||
tarindex++;
|
||||
state = 2;
|
||||
break;
|
||||
case 2:
|
||||
if (target) {
|
||||
if (tarindex + 1 >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= (pos - Base64) >> 2;
|
||||
target[tarindex+1] = ((pos - Base64) & 0x03)
|
||||
<< 6;
|
||||
}
|
||||
tarindex++;
|
||||
state = 3;
|
||||
break;
|
||||
case 3:
|
||||
if (target) {
|
||||
if (tarindex >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= (pos - Base64);
|
||||
}
|
||||
tarindex++;
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We are done decoding Base-64 chars. Let's see if we ended
|
||||
* on a byte boundary, and/or with erroneous trailing characters.
|
||||
*/
|
||||
|
||||
if (ch == Pad64) { /* We got a pad char. */
|
||||
ch = *src++; /* Skip it, get next. */
|
||||
switch (state) {
|
||||
case 0: /* Invalid = in first position */
|
||||
case 1: /* Invalid = in second position */
|
||||
return (-1);
|
||||
|
||||
case 2: /* Valid, means one byte of info */
|
||||
/* Skip any number of spaces. */
|
||||
for (; ch != '\0'; ch = *src++)
|
||||
if (!isspace(ch))
|
||||
break;
|
||||
/* Make sure there is another trailing = sign. */
|
||||
if (ch != Pad64)
|
||||
return (-1);
|
||||
ch = *src++; /* Skip the = */
|
||||
/* Fall through to "single trailing =" case. */
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 3: /* Valid, means two bytes of info */
|
||||
/*
|
||||
* We know this char is an =. Is there anything but
|
||||
* whitespace after it?
|
||||
*/
|
||||
for (; ch != '\0'; ch = *src++)
|
||||
if (!isspace(ch))
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Now make sure for cases 2 and 3 that the "extra"
|
||||
* bits that slopped past the last full byte were
|
||||
* zeros. If we don't check them, they become a
|
||||
* subliminal channel.
|
||||
*/
|
||||
if (target && target[tarindex] != 0)
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* We ended by seeing the end of the string. Make sure we
|
||||
* have no partial bytes lying around.
|
||||
*/
|
||||
if (state != 0)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (tarindex);
|
||||
}
|
||||
926
src/3rdparty/hwloc/src/bind.c
vendored
926
src/3rdparty/hwloc/src/bind.c
vendored
@@ -1,926 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "private/autogen/config.h"
|
||||
#include "hwloc.h"
|
||||
#include "private/private.h"
|
||||
#include "hwloc/helper.h"
|
||||
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
# include <sys/mman.h>
|
||||
#endif
|
||||
/* <malloc.h> is only needed if we don't have posix_memalign() */
|
||||
#if defined(hwloc_getpagesize) && !defined(HAVE_POSIX_MEMALIGN) && defined(HAVE_MEMALIGN) && defined(HAVE_MALLOC_H)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* TODO: HWLOC_GNU_SYS,
|
||||
*
|
||||
* We could use glibc's sched_setaffinity generically when it is available
|
||||
*
|
||||
* Darwin and OpenBSD don't seem to have binding facilities.
|
||||
*/
|
||||
|
||||
#define HWLOC_CPUBIND_ALLFLAGS (HWLOC_CPUBIND_PROCESS|HWLOC_CPUBIND_THREAD|HWLOC_CPUBIND_STRICT|HWLOC_CPUBIND_NOMEMBIND)
|
||||
|
||||
static hwloc_const_bitmap_t
|
||||
hwloc_fix_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t set)
|
||||
{
|
||||
hwloc_const_bitmap_t topology_set = hwloc_topology_get_topology_cpuset(topology);
|
||||
hwloc_const_bitmap_t complete_set = hwloc_topology_get_complete_cpuset(topology);
|
||||
|
||||
if (hwloc_bitmap_iszero(set)) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!hwloc_bitmap_isincluded(set, complete_set)) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (hwloc_bitmap_isincluded(topology_set, set))
|
||||
set = complete_set;
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_set_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t set, int flags)
|
||||
{
|
||||
if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
set = hwloc_fix_cpubind(topology, set);
|
||||
if (!set)
|
||||
return -1;
|
||||
|
||||
if (flags & HWLOC_CPUBIND_PROCESS) {
|
||||
if (topology->binding_hooks.set_thisproc_cpubind)
|
||||
return topology->binding_hooks.set_thisproc_cpubind(topology, set, flags);
|
||||
} else if (flags & HWLOC_CPUBIND_THREAD) {
|
||||
if (topology->binding_hooks.set_thisthread_cpubind)
|
||||
return topology->binding_hooks.set_thisthread_cpubind(topology, set, flags);
|
||||
} else {
|
||||
if (topology->binding_hooks.set_thisproc_cpubind) {
|
||||
int err = topology->binding_hooks.set_thisproc_cpubind(topology, set, flags);
|
||||
if (err >= 0 || errno != ENOSYS)
|
||||
return err;
|
||||
/* ENOSYS, fallback */
|
||||
}
|
||||
if (topology->binding_hooks.set_thisthread_cpubind)
|
||||
return topology->binding_hooks.set_thisthread_cpubind(topology, set, flags);
|
||||
}
|
||||
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_get_cpubind(hwloc_topology_t topology, hwloc_bitmap_t set, int flags)
|
||||
{
|
||||
if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags & HWLOC_CPUBIND_PROCESS) {
|
||||
if (topology->binding_hooks.get_thisproc_cpubind)
|
||||
return topology->binding_hooks.get_thisproc_cpubind(topology, set, flags);
|
||||
} else if (flags & HWLOC_CPUBIND_THREAD) {
|
||||
if (topology->binding_hooks.get_thisthread_cpubind)
|
||||
return topology->binding_hooks.get_thisthread_cpubind(topology, set, flags);
|
||||
} else {
|
||||
if (topology->binding_hooks.get_thisproc_cpubind) {
|
||||
int err = topology->binding_hooks.get_thisproc_cpubind(topology, set, flags);
|
||||
if (err >= 0 || errno != ENOSYS)
|
||||
return err;
|
||||
/* ENOSYS, fallback */
|
||||
}
|
||||
if (topology->binding_hooks.get_thisthread_cpubind)
|
||||
return topology->binding_hooks.get_thisthread_cpubind(topology, set, flags);
|
||||
}
|
||||
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_set_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_bitmap_t set, int flags)
|
||||
{
|
||||
if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
set = hwloc_fix_cpubind(topology, set);
|
||||
if (!set)
|
||||
return -1;
|
||||
|
||||
if (topology->binding_hooks.set_proc_cpubind)
|
||||
return topology->binding_hooks.set_proc_cpubind(topology, pid, set, flags);
|
||||
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_get_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t set, int flags)
|
||||
{
|
||||
if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (topology->binding_hooks.get_proc_cpubind)
|
||||
return topology->binding_hooks.get_proc_cpubind(topology, pid, set, flags);
|
||||
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef hwloc_thread_t
|
||||
int
|
||||
hwloc_set_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t tid, hwloc_const_bitmap_t set, int flags)
|
||||
{
|
||||
if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
set = hwloc_fix_cpubind(topology, set);
|
||||
if (!set)
|
||||
return -1;
|
||||
|
||||
if (topology->binding_hooks.set_thread_cpubind)
|
||||
return topology->binding_hooks.set_thread_cpubind(topology, tid, set, flags);
|
||||
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_get_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t tid, hwloc_bitmap_t set, int flags)
|
||||
{
|
||||
if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (topology->binding_hooks.get_thread_cpubind)
|
||||
return topology->binding_hooks.get_thread_cpubind(topology, tid, set, flags);
|
||||
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
hwloc_get_last_cpu_location(hwloc_topology_t topology, hwloc_bitmap_t set, int flags)
|
||||
{
|
||||
if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags & HWLOC_CPUBIND_PROCESS) {
|
||||
if (topology->binding_hooks.get_thisproc_last_cpu_location)
|
||||
return topology->binding_hooks.get_thisproc_last_cpu_location(topology, set, flags);
|
||||
} else if (flags & HWLOC_CPUBIND_THREAD) {
|
||||
if (topology->binding_hooks.get_thisthread_last_cpu_location)
|
||||
return topology->binding_hooks.get_thisthread_last_cpu_location(topology, set, flags);
|
||||
} else {
|
||||
if (topology->binding_hooks.get_thisproc_last_cpu_location) {
|
||||
int err = topology->binding_hooks.get_thisproc_last_cpu_location(topology, set, flags);
|
||||
if (err >= 0 || errno != ENOSYS)
|
||||
return err;
|
||||
/* ENOSYS, fallback */
|
||||
}
|
||||
if (topology->binding_hooks.get_thisthread_last_cpu_location)
|
||||
return topology->binding_hooks.get_thisthread_last_cpu_location(topology, set, flags);
|
||||
}
|
||||
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_get_proc_last_cpu_location(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t set, int flags)
|
||||
{
|
||||
if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (topology->binding_hooks.get_proc_last_cpu_location)
|
||||
return topology->binding_hooks.get_proc_last_cpu_location(topology, pid, set, flags);
|
||||
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define HWLOC_MEMBIND_ALLFLAGS (HWLOC_MEMBIND_PROCESS|HWLOC_MEMBIND_THREAD|HWLOC_MEMBIND_STRICT|HWLOC_MEMBIND_MIGRATE|HWLOC_MEMBIND_NOCPUBIND|HWLOC_MEMBIND_BYNODESET)
|
||||
|
||||
static hwloc_const_nodeset_t
|
||||
hwloc_fix_membind(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset)
|
||||
{
|
||||
hwloc_const_bitmap_t topology_nodeset = hwloc_topology_get_topology_nodeset(topology);
|
||||
hwloc_const_bitmap_t complete_nodeset = hwloc_topology_get_complete_nodeset(topology);
|
||||
|
||||
if (hwloc_bitmap_iszero(nodeset)) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!hwloc_bitmap_isincluded(nodeset, complete_nodeset)) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (hwloc_bitmap_isincluded(topology_nodeset, nodeset))
|
||||
return complete_nodeset;
|
||||
|
||||
return nodeset;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_fix_membind_cpuset(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_const_cpuset_t cpuset)
|
||||
{
|
||||
hwloc_const_bitmap_t topology_set = hwloc_topology_get_topology_cpuset(topology);
|
||||
hwloc_const_bitmap_t complete_set = hwloc_topology_get_complete_cpuset(topology);
|
||||
hwloc_const_bitmap_t complete_nodeset = hwloc_topology_get_complete_nodeset(topology);
|
||||
|
||||
if (hwloc_bitmap_iszero(cpuset)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!hwloc_bitmap_isincluded(cpuset, complete_set)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hwloc_bitmap_isincluded(topology_set, cpuset)) {
|
||||
hwloc_bitmap_copy(nodeset, complete_nodeset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hwloc_cpuset_to_nodeset(topology, cpuset, nodeset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __hwloc_inline int hwloc__check_membind_policy(hwloc_membind_policy_t policy)
|
||||
{
|
||||
if (policy == HWLOC_MEMBIND_DEFAULT
|
||||
|| policy == HWLOC_MEMBIND_FIRSTTOUCH
|
||||
|| policy == HWLOC_MEMBIND_BIND
|
||||
|| policy == HWLOC_MEMBIND_INTERLEAVE
|
||||
|| policy == HWLOC_MEMBIND_NEXTTOUCH)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_set_membind_by_nodeset(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
|
||||
{
|
||||
if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
nodeset = hwloc_fix_membind(topology, nodeset);
|
||||
if (!nodeset)
|
||||
return -1;
|
||||
|
||||
if (flags & HWLOC_MEMBIND_PROCESS) {
|
||||
if (topology->binding_hooks.set_thisproc_membind)
|
||||
return topology->binding_hooks.set_thisproc_membind(topology, nodeset, policy, flags);
|
||||
} else if (flags & HWLOC_MEMBIND_THREAD) {
|
||||
if (topology->binding_hooks.set_thisthread_membind)
|
||||
return topology->binding_hooks.set_thisthread_membind(topology, nodeset, policy, flags);
|
||||
} else {
|
||||
if (topology->binding_hooks.set_thisproc_membind) {
|
||||
int err = topology->binding_hooks.set_thisproc_membind(topology, nodeset, policy, flags);
|
||||
if (err >= 0 || errno != ENOSYS)
|
||||
return err;
|
||||
/* ENOSYS, fallback */
|
||||
}
|
||||
if (topology->binding_hooks.set_thisthread_membind)
|
||||
return topology->binding_hooks.set_thisthread_membind(topology, nodeset, policy, flags);
|
||||
}
|
||||
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_set_membind(hwloc_topology_t topology, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (flags & HWLOC_MEMBIND_BYNODESET) {
|
||||
ret = hwloc_set_membind_by_nodeset(topology, set, policy, flags);
|
||||
} else {
|
||||
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
|
||||
if (hwloc_fix_membind_cpuset(topology, nodeset, set))
|
||||
ret = -1;
|
||||
else
|
||||
ret = hwloc_set_membind_by_nodeset(topology, nodeset, policy, flags);
|
||||
hwloc_bitmap_free(nodeset);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_get_membind_by_nodeset(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
|
||||
{
|
||||
if (flags & ~HWLOC_MEMBIND_ALLFLAGS) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags & HWLOC_MEMBIND_PROCESS) {
|
||||
if (topology->binding_hooks.get_thisproc_membind)
|
||||
return topology->binding_hooks.get_thisproc_membind(topology, nodeset, policy, flags);
|
||||
} else if (flags & HWLOC_MEMBIND_THREAD) {
|
||||
if (topology->binding_hooks.get_thisthread_membind)
|
||||
return topology->binding_hooks.get_thisthread_membind(topology, nodeset, policy, flags);
|
||||
} else {
|
||||
if (topology->binding_hooks.get_thisproc_membind) {
|
||||
int err = topology->binding_hooks.get_thisproc_membind(topology, nodeset, policy, flags);
|
||||
if (err >= 0 || errno != ENOSYS)
|
||||
return err;
|
||||
/* ENOSYS, fallback */
|
||||
}
|
||||
if (topology->binding_hooks.get_thisthread_membind)
|
||||
return topology->binding_hooks.get_thisthread_membind(topology, nodeset, policy, flags);
|
||||
}
|
||||
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_get_membind(hwloc_topology_t topology, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (flags & HWLOC_MEMBIND_BYNODESET) {
|
||||
ret = hwloc_get_membind_by_nodeset(topology, set, policy, flags);
|
||||
} else {
|
||||
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
|
||||
ret = hwloc_get_membind_by_nodeset(topology, nodeset, policy, flags);
|
||||
if (!ret)
|
||||
hwloc_cpuset_from_nodeset(topology, set, nodeset);
|
||||
hwloc_bitmap_free(nodeset);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_set_proc_membind_by_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
|
||||
{
|
||||
if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
nodeset = hwloc_fix_membind(topology, nodeset);
|
||||
if (!nodeset)
|
||||
return -1;
|
||||
|
||||
if (topology->binding_hooks.set_proc_membind)
|
||||
return topology->binding_hooks.set_proc_membind(topology, pid, nodeset, policy, flags);
|
||||
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hwloc_set_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (flags & HWLOC_MEMBIND_BYNODESET) {
|
||||
ret = hwloc_set_proc_membind_by_nodeset(topology, pid, set, policy, flags);
|
||||
} else {
|
||||
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
|
||||
if (hwloc_fix_membind_cpuset(topology, nodeset, set))
|
||||
ret = -1;
|
||||
else
|
||||
ret = hwloc_set_proc_membind_by_nodeset(topology, pid, nodeset, policy, flags);
|
||||
hwloc_bitmap_free(nodeset);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_get_proc_membind_by_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
|
||||
{
|
||||
if (flags & ~HWLOC_MEMBIND_ALLFLAGS) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (topology->binding_hooks.get_proc_membind)
|
||||
return topology->binding_hooks.get_proc_membind(topology, pid, nodeset, policy, flags);
|
||||
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_get_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (flags & HWLOC_MEMBIND_BYNODESET) {
|
||||
ret = hwloc_get_proc_membind_by_nodeset(topology, pid, set, policy, flags);
|
||||
} else {
|
||||
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
|
||||
ret = hwloc_get_proc_membind_by_nodeset(topology, pid, nodeset, policy, flags);
|
||||
if (!ret)
|
||||
hwloc_cpuset_from_nodeset(topology, set, nodeset);
|
||||
hwloc_bitmap_free(nodeset);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_set_area_membind_by_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
|
||||
{
|
||||
if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!len)
|
||||
/* nothing to do */
|
||||
return 0;
|
||||
|
||||
nodeset = hwloc_fix_membind(topology, nodeset);
|
||||
if (!nodeset)
|
||||
return -1;
|
||||
|
||||
if (topology->binding_hooks.set_area_membind)
|
||||
return topology->binding_hooks.set_area_membind(topology, addr, len, nodeset, policy, flags);
|
||||
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_set_area_membind(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (flags & HWLOC_MEMBIND_BYNODESET) {
|
||||
ret = hwloc_set_area_membind_by_nodeset(topology, addr, len, set, policy, flags);
|
||||
} else {
|
||||
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
|
||||
if (hwloc_fix_membind_cpuset(topology, nodeset, set))
|
||||
ret = -1;
|
||||
else
|
||||
ret = hwloc_set_area_membind_by_nodeset(topology, addr, len, nodeset, policy, flags);
|
||||
hwloc_bitmap_free(nodeset);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_get_area_membind_by_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
|
||||
{
|
||||
if (flags & ~HWLOC_MEMBIND_ALLFLAGS) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!len) {
|
||||
/* nothing to query */
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (topology->binding_hooks.get_area_membind)
|
||||
return topology->binding_hooks.get_area_membind(topology, addr, len, nodeset, policy, flags);
|
||||
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_get_area_membind(hwloc_topology_t topology, const void *addr, size_t len, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (flags & HWLOC_MEMBIND_BYNODESET) {
|
||||
ret = hwloc_get_area_membind_by_nodeset(topology, addr, len, set, policy, flags);
|
||||
} else {
|
||||
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
|
||||
ret = hwloc_get_area_membind_by_nodeset(topology, addr, len, nodeset, policy, flags);
|
||||
if (!ret)
|
||||
hwloc_cpuset_from_nodeset(topology, set, nodeset);
|
||||
hwloc_bitmap_free(nodeset);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_get_area_memlocation_by_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, int flags)
|
||||
{
|
||||
if (flags & ~HWLOC_MEMBIND_ALLFLAGS) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!len)
|
||||
/* nothing to do */
|
||||
return 0;
|
||||
|
||||
if (topology->binding_hooks.get_area_memlocation)
|
||||
return topology->binding_hooks.get_area_memlocation(topology, addr, len, nodeset, flags);
|
||||
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_get_area_memlocation(hwloc_topology_t topology, const void *addr, size_t len, hwloc_cpuset_t set, int flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (flags & HWLOC_MEMBIND_BYNODESET) {
|
||||
ret = hwloc_get_area_memlocation_by_nodeset(topology, addr, len, set, flags);
|
||||
} else {
|
||||
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
|
||||
ret = hwloc_get_area_memlocation_by_nodeset(topology, addr, len, nodeset, flags);
|
||||
if (!ret)
|
||||
hwloc_cpuset_from_nodeset(topology, set, nodeset);
|
||||
hwloc_bitmap_free(nodeset);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *
|
||||
hwloc_alloc_heap(hwloc_topology_t topology __hwloc_attribute_unused, size_t len)
|
||||
{
|
||||
void *p = NULL;
|
||||
#if defined(hwloc_getpagesize) && defined(HAVE_POSIX_MEMALIGN)
|
||||
errno = posix_memalign(&p, hwloc_getpagesize(), len);
|
||||
if (errno)
|
||||
p = NULL;
|
||||
#elif defined(hwloc_getpagesize) && defined(HAVE_MEMALIGN)
|
||||
p = memalign(hwloc_getpagesize(), len);
|
||||
#else
|
||||
p = malloc(len);
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
#ifdef MAP_ANONYMOUS
|
||||
void *
|
||||
hwloc_alloc_mmap(hwloc_topology_t topology __hwloc_attribute_unused, size_t len)
|
||||
{
|
||||
void * buffer = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
return buffer == MAP_FAILED ? NULL : buffer;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
hwloc_free_heap(hwloc_topology_t topology __hwloc_attribute_unused, void *addr, size_t len __hwloc_attribute_unused)
|
||||
{
|
||||
free(addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef MAP_ANONYMOUS
|
||||
int
|
||||
hwloc_free_mmap(hwloc_topology_t topology __hwloc_attribute_unused, void *addr, size_t len)
|
||||
{
|
||||
if (!addr)
|
||||
return 0;
|
||||
return munmap(addr, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
void *
|
||||
hwloc_alloc(hwloc_topology_t topology, size_t len)
|
||||
{
|
||||
if (topology->binding_hooks.alloc)
|
||||
return topology->binding_hooks.alloc(topology, len);
|
||||
return hwloc_alloc_heap(topology, len);
|
||||
}
|
||||
|
||||
static void *
|
||||
hwloc_alloc_membind_by_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nodeset = hwloc_fix_membind(topology, nodeset);
|
||||
if (!nodeset)
|
||||
goto fallback;
|
||||
if (flags & HWLOC_MEMBIND_MIGRATE) {
|
||||
errno = EINVAL;
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
if (topology->binding_hooks.alloc_membind)
|
||||
return topology->binding_hooks.alloc_membind(topology, len, nodeset, policy, flags);
|
||||
else if (topology->binding_hooks.set_area_membind) {
|
||||
p = hwloc_alloc(topology, len);
|
||||
if (!p)
|
||||
return NULL;
|
||||
if (topology->binding_hooks.set_area_membind(topology, p, len, nodeset, policy, flags) && flags & HWLOC_MEMBIND_STRICT) {
|
||||
int error = errno;
|
||||
free(p);
|
||||
errno = error;
|
||||
return NULL;
|
||||
}
|
||||
return p;
|
||||
} else {
|
||||
errno = ENOSYS;
|
||||
}
|
||||
|
||||
fallback:
|
||||
if (flags & HWLOC_MEMBIND_STRICT)
|
||||
/* Report error */
|
||||
return NULL;
|
||||
/* Never mind, allocate anyway */
|
||||
return hwloc_alloc(topology, len);
|
||||
}
|
||||
|
||||
void *
|
||||
hwloc_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
if (flags & HWLOC_MEMBIND_BYNODESET) {
|
||||
ret = hwloc_alloc_membind_by_nodeset(topology, len, set, policy, flags);
|
||||
} else {
|
||||
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
|
||||
if (hwloc_fix_membind_cpuset(topology, nodeset, set)) {
|
||||
if (flags & HWLOC_MEMBIND_STRICT)
|
||||
ret = NULL;
|
||||
else
|
||||
ret = hwloc_alloc(topology, len);
|
||||
} else
|
||||
ret = hwloc_alloc_membind_by_nodeset(topology, len, nodeset, policy, flags);
|
||||
hwloc_bitmap_free(nodeset);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_free(hwloc_topology_t topology, void *addr, size_t len)
|
||||
{
|
||||
if (topology->binding_hooks.free_membind)
|
||||
return topology->binding_hooks.free_membind(topology, addr, len);
|
||||
return hwloc_free_heap(topology, addr, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Empty binding hooks always returning success
|
||||
*/
|
||||
|
||||
static int dontset_return_complete_cpuset(hwloc_topology_t topology, hwloc_cpuset_t set)
|
||||
{
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dontset_thisthread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int dontget_thisthread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_bitmap_t set, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
return dontset_return_complete_cpuset(topology, set);
|
||||
}
|
||||
static int dontset_thisproc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int dontget_thisproc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_bitmap_t set, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
return dontset_return_complete_cpuset(topology, set);
|
||||
}
|
||||
static int dontset_proc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int dontget_proc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid __hwloc_attribute_unused, hwloc_bitmap_t cpuset, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
return dontset_return_complete_cpuset(topology, cpuset);
|
||||
}
|
||||
#ifdef hwloc_thread_t
|
||||
static int dontset_thread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_thread_t tid __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int dontget_thread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_thread_t tid __hwloc_attribute_unused, hwloc_bitmap_t cpuset, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
return dontset_return_complete_cpuset(topology, cpuset);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int dontset_return_complete_nodeset(hwloc_topology_t topology, hwloc_nodeset_t set, hwloc_membind_policy_t *policy)
|
||||
{
|
||||
hwloc_bitmap_copy(set, hwloc_topology_get_complete_nodeset(topology));
|
||||
*policy = HWLOC_MEMBIND_MIXED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dontset_thisproc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int dontget_thisproc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
return dontset_return_complete_nodeset(topology, set, policy);
|
||||
}
|
||||
|
||||
static int dontset_thisthread_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int dontget_thisthread_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
return dontset_return_complete_nodeset(topology, set, policy);
|
||||
}
|
||||
|
||||
static int dontset_proc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int dontget_proc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid __hwloc_attribute_unused, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
return dontset_return_complete_nodeset(topology, set, policy);
|
||||
}
|
||||
|
||||
static int dontset_area_membind(hwloc_topology_t topology __hwloc_attribute_unused, const void *addr __hwloc_attribute_unused, size_t size __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int dontget_area_membind(hwloc_topology_t topology __hwloc_attribute_unused, const void *addr __hwloc_attribute_unused, size_t size __hwloc_attribute_unused, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
return dontset_return_complete_nodeset(topology, set, policy);
|
||||
}
|
||||
static int dontget_area_memlocation(hwloc_topology_t topology __hwloc_attribute_unused, const void *addr __hwloc_attribute_unused, size_t size __hwloc_attribute_unused, hwloc_bitmap_t set, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
hwloc_membind_policy_t policy;
|
||||
return dontset_return_complete_nodeset(topology, set, &policy);
|
||||
}
|
||||
|
||||
static void * dontalloc_membind(hwloc_topology_t topology __hwloc_attribute_unused, size_t size __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
static int dontfree_membind(hwloc_topology_t topology __hwloc_attribute_unused, void *addr __hwloc_attribute_unused, size_t size __hwloc_attribute_unused)
|
||||
{
|
||||
free(addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hwloc_set_dummy_hooks(struct hwloc_binding_hooks *hooks,
|
||||
struct hwloc_topology_support *support __hwloc_attribute_unused)
|
||||
{
|
||||
hooks->set_thisproc_cpubind = dontset_thisproc_cpubind;
|
||||
hooks->get_thisproc_cpubind = dontget_thisproc_cpubind;
|
||||
hooks->set_thisthread_cpubind = dontset_thisthread_cpubind;
|
||||
hooks->get_thisthread_cpubind = dontget_thisthread_cpubind;
|
||||
hooks->set_proc_cpubind = dontset_proc_cpubind;
|
||||
hooks->get_proc_cpubind = dontget_proc_cpubind;
|
||||
#ifdef hwloc_thread_t
|
||||
hooks->set_thread_cpubind = dontset_thread_cpubind;
|
||||
hooks->get_thread_cpubind = dontget_thread_cpubind;
|
||||
#endif
|
||||
hooks->get_thisproc_last_cpu_location = dontget_thisproc_cpubind; /* cpubind instead of last_cpu_location is ok */
|
||||
hooks->get_thisthread_last_cpu_location = dontget_thisthread_cpubind; /* cpubind instead of last_cpu_location is ok */
|
||||
hooks->get_proc_last_cpu_location = dontget_proc_cpubind; /* cpubind instead of last_cpu_location is ok */
|
||||
/* TODO: get_thread_last_cpu_location */
|
||||
hooks->set_thisproc_membind = dontset_thisproc_membind;
|
||||
hooks->get_thisproc_membind = dontget_thisproc_membind;
|
||||
hooks->set_thisthread_membind = dontset_thisthread_membind;
|
||||
hooks->get_thisthread_membind = dontget_thisthread_membind;
|
||||
hooks->set_proc_membind = dontset_proc_membind;
|
||||
hooks->get_proc_membind = dontget_proc_membind;
|
||||
hooks->set_area_membind = dontset_area_membind;
|
||||
hooks->get_area_membind = dontget_area_membind;
|
||||
hooks->get_area_memlocation = dontget_area_memlocation;
|
||||
hooks->alloc_membind = dontalloc_membind;
|
||||
hooks->free_membind = dontfree_membind;
|
||||
}
|
||||
|
||||
void
|
||||
hwloc_set_native_binding_hooks(struct hwloc_binding_hooks *hooks, struct hwloc_topology_support *support)
|
||||
{
|
||||
# ifdef HWLOC_LINUX_SYS
|
||||
hwloc_set_linuxfs_hooks(hooks, support);
|
||||
# endif /* HWLOC_LINUX_SYS */
|
||||
|
||||
# ifdef HWLOC_BGQ_SYS
|
||||
hwloc_set_bgq_hooks(hooks, support);
|
||||
# endif /* HWLOC_BGQ_SYS */
|
||||
|
||||
# ifdef HWLOC_AIX_SYS
|
||||
hwloc_set_aix_hooks(hooks, support);
|
||||
# endif /* HWLOC_AIX_SYS */
|
||||
|
||||
# ifdef HWLOC_SOLARIS_SYS
|
||||
hwloc_set_solaris_hooks(hooks, support);
|
||||
# endif /* HWLOC_SOLARIS_SYS */
|
||||
|
||||
# ifdef HWLOC_WIN_SYS
|
||||
hwloc_set_windows_hooks(hooks, support);
|
||||
# endif /* HWLOC_WIN_SYS */
|
||||
|
||||
# ifdef HWLOC_DARWIN_SYS
|
||||
hwloc_set_darwin_hooks(hooks, support);
|
||||
# endif /* HWLOC_DARWIN_SYS */
|
||||
|
||||
# ifdef HWLOC_FREEBSD_SYS
|
||||
hwloc_set_freebsd_hooks(hooks, support);
|
||||
# endif /* HWLOC_FREEBSD_SYS */
|
||||
|
||||
# ifdef HWLOC_NETBSD_SYS
|
||||
hwloc_set_netbsd_hooks(hooks, support);
|
||||
# endif /* HWLOC_NETBSD_SYS */
|
||||
|
||||
# ifdef HWLOC_HPUX_SYS
|
||||
hwloc_set_hpux_hooks(hooks, support);
|
||||
# endif /* HWLOC_HPUX_SYS */
|
||||
}
|
||||
|
||||
/* If the represented system is actually not this system, use dummy binding hooks. */
|
||||
void
|
||||
hwloc_set_binding_hooks(struct hwloc_topology *topology)
|
||||
{
|
||||
if (topology->is_thissystem) {
|
||||
hwloc_set_native_binding_hooks(&topology->binding_hooks, &topology->support);
|
||||
/* every hook not set above will return ENOSYS */
|
||||
} else {
|
||||
/* not this system, use dummy binding hooks that do nothing (but don't return ENOSYS) */
|
||||
hwloc_set_dummy_hooks(&topology->binding_hooks, &topology->support);
|
||||
|
||||
/* Linux has some hooks that also work in this case, but they are not strictly needed yet. */
|
||||
}
|
||||
|
||||
/* if not is_thissystem, set_cpubind is fake
|
||||
* and get_cpubind returns the whole system cpuset,
|
||||
* so don't report that set/get_cpubind as supported
|
||||
*/
|
||||
if (topology->is_thissystem) {
|
||||
#define DO(which,kind) \
|
||||
if (topology->binding_hooks.kind) \
|
||||
topology->support.which##bind->kind = 1;
|
||||
DO(cpu,set_thisproc_cpubind);
|
||||
DO(cpu,get_thisproc_cpubind);
|
||||
DO(cpu,set_proc_cpubind);
|
||||
DO(cpu,get_proc_cpubind);
|
||||
DO(cpu,set_thisthread_cpubind);
|
||||
DO(cpu,get_thisthread_cpubind);
|
||||
#ifdef hwloc_thread_t
|
||||
DO(cpu,set_thread_cpubind);
|
||||
DO(cpu,get_thread_cpubind);
|
||||
#endif
|
||||
DO(cpu,get_thisproc_last_cpu_location);
|
||||
DO(cpu,get_proc_last_cpu_location);
|
||||
DO(cpu,get_thisthread_last_cpu_location);
|
||||
DO(mem,set_thisproc_membind);
|
||||
DO(mem,get_thisproc_membind);
|
||||
DO(mem,set_thisthread_membind);
|
||||
DO(mem,get_thisthread_membind);
|
||||
DO(mem,set_proc_membind);
|
||||
DO(mem,get_proc_membind);
|
||||
DO(mem,set_area_membind);
|
||||
DO(mem,get_area_membind);
|
||||
DO(mem,get_area_memlocation);
|
||||
DO(mem,alloc_membind);
|
||||
#undef DO
|
||||
}
|
||||
}
|
||||
1717
src/3rdparty/hwloc/src/bitmap.c
vendored
1717
src/3rdparty/hwloc/src/bitmap.c
vendored
File diff suppressed because it is too large
Load Diff
1091
src/3rdparty/hwloc/src/components.c
vendored
1091
src/3rdparty/hwloc/src/components.c
vendored
File diff suppressed because it is too large
Load Diff
661
src/3rdparty/hwloc/src/cpukinds.c
vendored
661
src/3rdparty/hwloc/src/cpukinds.c
vendored
@@ -1,661 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2020-2021 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;
|
||||
|
||||
if (!old->nr_cpukinds)
|
||||
return 0;
|
||||
|
||||
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].ranking_value == topology->cpukinds[j].ranking_value)
|
||||
/* 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, /* either coretype or frequency or both */
|
||||
HWLOC_CPUKINDS_RANKING_CORETYPE_FREQUENCY_STRICT, /* both coretype and frequency are required */
|
||||
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_STRICT == heuristics) {
|
||||
hwloc_debug("Trying to rank cpukinds by coretype+frequency_strict...\n");
|
||||
/* we need intel_core_type AND (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_FREQUENCY == heuristics) {
|
||||
hwloc_debug("Trying to rank cpukinds by coretype+frequency...\n");
|
||||
/* we need intel_core_type OR (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;
|
||||
uint64_t arv = a->ranking_value;
|
||||
uint64_t brv = b->ranking_value;
|
||||
return arv < brv ? -1 : arv > brv ? 1 : 0;
|
||||
}
|
||||
|
||||
/* 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+frequency_strict"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_CORETYPE_FREQUENCY_STRICT;
|
||||
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() < 2)
|
||||
fprintf(stderr, "hwloc: 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;
|
||||
|
||||
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);
|
||||
|
||||
err = hwloc__cpukinds_try_rank_by_info(topology, HWLOC_CPUKINDS_RANKING_CORETYPE_FREQUENCY, &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;
|
||||
}
|
||||
540
src/3rdparty/hwloc/src/diff.c
vendored
540
src/3rdparty/hwloc/src/diff.c
vendored
@@ -1,540 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013-2020 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include "private/autogen/config.h"
|
||||
#include "private/private.h"
|
||||
#include "private/misc.h"
|
||||
|
||||
int hwloc_topology_diff_destroy(hwloc_topology_diff_t diff)
|
||||
{
|
||||
hwloc_topology_diff_t next;
|
||||
while (diff) {
|
||||
next = diff->generic.next;
|
||||
switch (diff->generic.type) {
|
||||
default:
|
||||
break;
|
||||
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR:
|
||||
switch (diff->obj_attr.diff.generic.type) {
|
||||
default:
|
||||
break;
|
||||
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME:
|
||||
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO:
|
||||
free(diff->obj_attr.diff.string.name);
|
||||
free(diff->obj_attr.diff.string.oldvalue);
|
||||
free(diff->obj_attr.diff.string.newvalue);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
free(diff);
|
||||
diff = next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************
|
||||
* Computing diffs
|
||||
*/
|
||||
|
||||
static void hwloc_append_diff(hwloc_topology_diff_t newdiff,
|
||||
hwloc_topology_diff_t *firstdiffp,
|
||||
hwloc_topology_diff_t *lastdiffp)
|
||||
{
|
||||
if (*firstdiffp)
|
||||
(*lastdiffp)->generic.next = newdiff;
|
||||
else
|
||||
*firstdiffp = newdiff;
|
||||
*lastdiffp = newdiff;
|
||||
newdiff->generic.next = NULL;
|
||||
}
|
||||
|
||||
static int hwloc_append_diff_too_complex(hwloc_obj_t obj1,
|
||||
hwloc_topology_diff_t *firstdiffp,
|
||||
hwloc_topology_diff_t *lastdiffp)
|
||||
{
|
||||
hwloc_topology_diff_t newdiff;
|
||||
newdiff = malloc(sizeof(*newdiff));
|
||||
if (!newdiff)
|
||||
return -1;
|
||||
|
||||
newdiff->too_complex.type = HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX;
|
||||
newdiff->too_complex.obj_depth = obj1->depth;
|
||||
newdiff->too_complex.obj_index = obj1->logical_index;
|
||||
hwloc_append_diff(newdiff, firstdiffp, lastdiffp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hwloc_append_diff_obj_attr_string(hwloc_obj_t obj,
|
||||
hwloc_topology_diff_obj_attr_type_t type,
|
||||
const char *name,
|
||||
const char *oldvalue,
|
||||
const char *newvalue,
|
||||
hwloc_topology_diff_t *firstdiffp,
|
||||
hwloc_topology_diff_t *lastdiffp)
|
||||
{
|
||||
hwloc_topology_diff_t newdiff;
|
||||
newdiff = malloc(sizeof(*newdiff));
|
||||
if (!newdiff)
|
||||
return -1;
|
||||
|
||||
newdiff->obj_attr.type = HWLOC_TOPOLOGY_DIFF_OBJ_ATTR;
|
||||
newdiff->obj_attr.obj_depth = obj->depth;
|
||||
newdiff->obj_attr.obj_index = obj->logical_index;
|
||||
newdiff->obj_attr.diff.string.type = type;
|
||||
newdiff->obj_attr.diff.string.name = name ? strdup(name) : NULL;
|
||||
newdiff->obj_attr.diff.string.oldvalue = oldvalue ? strdup(oldvalue) : NULL;
|
||||
newdiff->obj_attr.diff.string.newvalue = newvalue ? strdup(newvalue) : NULL;
|
||||
hwloc_append_diff(newdiff, firstdiffp, lastdiffp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hwloc_append_diff_obj_attr_uint64(hwloc_obj_t obj,
|
||||
hwloc_topology_diff_obj_attr_type_t type,
|
||||
hwloc_uint64_t idx,
|
||||
hwloc_uint64_t oldvalue,
|
||||
hwloc_uint64_t newvalue,
|
||||
hwloc_topology_diff_t *firstdiffp,
|
||||
hwloc_topology_diff_t *lastdiffp)
|
||||
{
|
||||
hwloc_topology_diff_t newdiff;
|
||||
newdiff = malloc(sizeof(*newdiff));
|
||||
if (!newdiff)
|
||||
return -1;
|
||||
|
||||
newdiff->obj_attr.type = HWLOC_TOPOLOGY_DIFF_OBJ_ATTR;
|
||||
newdiff->obj_attr.obj_depth = obj->depth;
|
||||
newdiff->obj_attr.obj_index = obj->logical_index;
|
||||
newdiff->obj_attr.diff.uint64.type = type;
|
||||
newdiff->obj_attr.diff.uint64.index = idx;
|
||||
newdiff->obj_attr.diff.uint64.oldvalue = oldvalue;
|
||||
newdiff->obj_attr.diff.uint64.newvalue = newvalue;
|
||||
hwloc_append_diff(newdiff, firstdiffp, lastdiffp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_diff_trees(hwloc_topology_t topo1, hwloc_obj_t obj1,
|
||||
hwloc_topology_t topo2, hwloc_obj_t obj2,
|
||||
unsigned flags,
|
||||
hwloc_topology_diff_t *firstdiffp, hwloc_topology_diff_t *lastdiffp)
|
||||
{
|
||||
unsigned i;
|
||||
int err;
|
||||
hwloc_obj_t child1, child2;
|
||||
|
||||
if (obj1->depth != obj2->depth)
|
||||
goto out_too_complex;
|
||||
|
||||
if (obj1->type != obj2->type)
|
||||
goto out_too_complex;
|
||||
if ((!obj1->subtype) != (!obj2->subtype)
|
||||
|| (obj1->subtype && strcmp(obj1->subtype, obj2->subtype)))
|
||||
goto out_too_complex;
|
||||
|
||||
if (obj1->os_index != obj2->os_index)
|
||||
/* we could allow different os_index for non-PU non-NUMAnode objects
|
||||
* but it's likely useless anyway */
|
||||
goto out_too_complex;
|
||||
|
||||
#define _SETS_DIFFERENT(_set1, _set2) \
|
||||
( ( !(_set1) != !(_set2) ) \
|
||||
|| ( (_set1) && !hwloc_bitmap_isequal(_set1, _set2) ) )
|
||||
#define SETS_DIFFERENT(_set, _obj1, _obj2) _SETS_DIFFERENT((_obj1)->_set, (_obj2)->_set)
|
||||
if (SETS_DIFFERENT(cpuset, obj1, obj2)
|
||||
|| SETS_DIFFERENT(complete_cpuset, obj1, obj2)
|
||||
|| SETS_DIFFERENT(nodeset, obj1, obj2)
|
||||
|| SETS_DIFFERENT(complete_nodeset, obj1, obj2))
|
||||
goto out_too_complex;
|
||||
|
||||
/* no need to check logical_index, sibling_rank, symmetric_subtree,
|
||||
* the parents did it */
|
||||
|
||||
/* gp_index don't have to be strictly identical */
|
||||
|
||||
if ((!obj1->name) != (!obj2->name)
|
||||
|| (obj1->name && strcmp(obj1->name, obj2->name))) {
|
||||
err = hwloc_append_diff_obj_attr_string(obj1,
|
||||
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME,
|
||||
NULL,
|
||||
obj1->name,
|
||||
obj2->name,
|
||||
firstdiffp, lastdiffp);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* type-specific attrs */
|
||||
switch (obj1->type) {
|
||||
default:
|
||||
break;
|
||||
case HWLOC_OBJ_NUMANODE:
|
||||
if (obj1->attr->numanode.local_memory != obj2->attr->numanode.local_memory) {
|
||||
err = hwloc_append_diff_obj_attr_uint64(obj1,
|
||||
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE,
|
||||
0,
|
||||
obj1->attr->numanode.local_memory,
|
||||
obj2->attr->numanode.local_memory,
|
||||
firstdiffp, lastdiffp);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
/* ignore memory page_types */
|
||||
break;
|
||||
case HWLOC_OBJ_L1CACHE:
|
||||
case HWLOC_OBJ_L2CACHE:
|
||||
case HWLOC_OBJ_L3CACHE:
|
||||
case HWLOC_OBJ_L4CACHE:
|
||||
case HWLOC_OBJ_L5CACHE:
|
||||
case HWLOC_OBJ_L1ICACHE:
|
||||
case HWLOC_OBJ_L2ICACHE:
|
||||
case HWLOC_OBJ_L3ICACHE:
|
||||
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->cache)))
|
||||
goto out_too_complex;
|
||||
break;
|
||||
case HWLOC_OBJ_GROUP:
|
||||
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->group)))
|
||||
goto out_too_complex;
|
||||
break;
|
||||
case HWLOC_OBJ_PCI_DEVICE:
|
||||
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->pcidev)))
|
||||
goto out_too_complex;
|
||||
break;
|
||||
case HWLOC_OBJ_BRIDGE:
|
||||
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->bridge)))
|
||||
goto out_too_complex;
|
||||
break;
|
||||
case HWLOC_OBJ_OS_DEVICE:
|
||||
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->osdev)))
|
||||
goto out_too_complex;
|
||||
break;
|
||||
}
|
||||
|
||||
/* infos */
|
||||
if (obj1->infos_count != obj2->infos_count)
|
||||
goto out_too_complex;
|
||||
for(i=0; i<obj1->infos_count; i++) {
|
||||
struct hwloc_info_s *info1 = &obj1->infos[i], *info2 = &obj2->infos[i];
|
||||
if (strcmp(info1->name, info2->name))
|
||||
goto out_too_complex;
|
||||
if (strcmp(obj1->infos[i].value, obj2->infos[i].value)) {
|
||||
err = hwloc_append_diff_obj_attr_string(obj1,
|
||||
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO,
|
||||
info1->name,
|
||||
info1->value,
|
||||
info2->value,
|
||||
firstdiffp, lastdiffp);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* ignore userdata */
|
||||
|
||||
/* children */
|
||||
for(child1 = obj1->first_child, child2 = obj2->first_child;
|
||||
child1 != NULL && child2 != NULL;
|
||||
child1 = child1->next_sibling, child2 = child2->next_sibling) {
|
||||
err = hwloc_diff_trees(topo1, child1,
|
||||
topo2, child2,
|
||||
flags,
|
||||
firstdiffp, lastdiffp);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
if (child1 || child2)
|
||||
goto out_too_complex;
|
||||
|
||||
/* memory children */
|
||||
for(child1 = obj1->memory_first_child, child2 = obj2->memory_first_child;
|
||||
child1 != NULL && child2 != NULL;
|
||||
child1 = child1->next_sibling, child2 = child2->next_sibling) {
|
||||
err = hwloc_diff_trees(topo1, child1,
|
||||
topo2, child2,
|
||||
flags,
|
||||
firstdiffp, lastdiffp);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
if (child1 || child2)
|
||||
goto out_too_complex;
|
||||
|
||||
/* I/O children */
|
||||
for(child1 = obj1->io_first_child, child2 = obj2->io_first_child;
|
||||
child1 != NULL && child2 != NULL;
|
||||
child1 = child1->next_sibling, child2 = child2->next_sibling) {
|
||||
err = hwloc_diff_trees(topo1, child1,
|
||||
topo2, child2,
|
||||
flags,
|
||||
firstdiffp, lastdiffp);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
if (child1 || child2)
|
||||
goto out_too_complex;
|
||||
|
||||
/* misc children */
|
||||
for(child1 = obj1->misc_first_child, child2 = obj2->misc_first_child;
|
||||
child1 != NULL && child2 != NULL;
|
||||
child1 = child1->next_sibling, child2 = child2->next_sibling) {
|
||||
err = hwloc_diff_trees(topo1, child1,
|
||||
topo2, child2,
|
||||
flags,
|
||||
firstdiffp, lastdiffp);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
if (child1 || child2)
|
||||
goto out_too_complex;
|
||||
|
||||
return 0;
|
||||
|
||||
out_too_complex:
|
||||
hwloc_append_diff_too_complex(obj1, firstdiffp, lastdiffp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hwloc_topology_diff_build(hwloc_topology_t topo1,
|
||||
hwloc_topology_t topo2,
|
||||
unsigned long flags,
|
||||
hwloc_topology_diff_t *diffp)
|
||||
{
|
||||
hwloc_topology_diff_t lastdiff, tmpdiff;
|
||||
struct hwloc_internal_distances_s *dist1, *dist2;
|
||||
unsigned i;
|
||||
int err;
|
||||
|
||||
if (!topo1->is_loaded || !topo2->is_loaded) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags != 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*diffp = NULL;
|
||||
err = hwloc_diff_trees(topo1, hwloc_get_root_obj(topo1),
|
||||
topo2, hwloc_get_root_obj(topo2),
|
||||
flags,
|
||||
diffp, &lastdiff);
|
||||
if (!err) {
|
||||
tmpdiff = *diffp;
|
||||
while (tmpdiff) {
|
||||
if (tmpdiff->generic.type == HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX) {
|
||||
err = 1;
|
||||
break;
|
||||
}
|
||||
tmpdiff = tmpdiff->generic.next;
|
||||
}
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
if (SETS_DIFFERENT(allowed_cpuset, topo1, topo2)
|
||||
|| SETS_DIFFERENT(allowed_nodeset, topo1, topo2))
|
||||
goto roottoocomplex;
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
/* distances */
|
||||
hwloc_internal_distances_refresh(topo1);
|
||||
hwloc_internal_distances_refresh(topo2);
|
||||
dist1 = topo1->first_dist;
|
||||
dist2 = topo2->first_dist;
|
||||
while (dist1 || dist2) {
|
||||
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)))
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Applying diffs
|
||||
*/
|
||||
|
||||
static int
|
||||
hwloc_apply_diff_one(hwloc_topology_t topology,
|
||||
hwloc_topology_diff_t diff,
|
||||
unsigned long flags)
|
||||
{
|
||||
int reverse = !!(flags & HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE);
|
||||
|
||||
switch (diff->generic.type) {
|
||||
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR: {
|
||||
struct hwloc_topology_diff_obj_attr_s *obj_attr = &diff->obj_attr;
|
||||
hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, obj_attr->obj_depth, obj_attr->obj_index);
|
||||
if (!obj)
|
||||
return -1;
|
||||
|
||||
switch (obj_attr->diff.generic.type) {
|
||||
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE: {
|
||||
hwloc_obj_t tmpobj;
|
||||
hwloc_uint64_t oldvalue = reverse ? obj_attr->diff.uint64.newvalue : obj_attr->diff.uint64.oldvalue;
|
||||
hwloc_uint64_t newvalue = reverse ? obj_attr->diff.uint64.oldvalue : obj_attr->diff.uint64.newvalue;
|
||||
hwloc_uint64_t valuediff = newvalue - oldvalue;
|
||||
if (obj->type != HWLOC_OBJ_NUMANODE)
|
||||
return -1;
|
||||
if (obj->attr->numanode.local_memory != oldvalue)
|
||||
return -1;
|
||||
obj->attr->numanode.local_memory = newvalue;
|
||||
tmpobj = obj;
|
||||
while (tmpobj) {
|
||||
tmpobj->total_memory += valuediff;
|
||||
tmpobj = tmpobj->parent;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME: {
|
||||
const char *oldvalue = reverse ? obj_attr->diff.string.newvalue : obj_attr->diff.string.oldvalue;
|
||||
const char *newvalue = reverse ? obj_attr->diff.string.oldvalue : obj_attr->diff.string.newvalue;
|
||||
if (!obj->name || strcmp(obj->name, oldvalue))
|
||||
return -1;
|
||||
free(obj->name);
|
||||
obj->name = strdup(newvalue);
|
||||
break;
|
||||
}
|
||||
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO: {
|
||||
const char *name = obj_attr->diff.string.name;
|
||||
const char *oldvalue = reverse ? obj_attr->diff.string.newvalue : obj_attr->diff.string.oldvalue;
|
||||
const char *newvalue = reverse ? obj_attr->diff.string.oldvalue : obj_attr->diff.string.newvalue;
|
||||
unsigned i;
|
||||
int found = 0;
|
||||
for(i=0; i<obj->infos_count; i++) {
|
||||
struct hwloc_info_s *info = &obj->infos[i];
|
||||
if (!strcmp(info->name, name)
|
||||
&& !strcmp(info->value, oldvalue)) {
|
||||
free(info->value);
|
||||
info->value = strdup(newvalue);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hwloc_topology_diff_apply(hwloc_topology_t topology,
|
||||
hwloc_topology_diff_t diff,
|
||||
unsigned long flags)
|
||||
{
|
||||
hwloc_topology_diff_t tmpdiff, tmpdiff2;
|
||||
int err, nr;
|
||||
|
||||
if (!topology->is_loaded) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (topology->adopted_shmem_addr) {
|
||||
errno = EPERM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags & ~HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmpdiff = diff;
|
||||
nr = 0;
|
||||
while (tmpdiff) {
|
||||
nr++;
|
||||
err = hwloc_apply_diff_one(topology, tmpdiff, flags);
|
||||
if (err < 0)
|
||||
goto cancel;
|
||||
tmpdiff = tmpdiff->generic.next;
|
||||
}
|
||||
return 0;
|
||||
|
||||
cancel:
|
||||
tmpdiff2 = tmpdiff;
|
||||
tmpdiff = diff;
|
||||
while (tmpdiff != tmpdiff2) {
|
||||
hwloc_apply_diff_one(topology, tmpdiff, flags ^ HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE);
|
||||
tmpdiff = tmpdiff->generic.next;
|
||||
}
|
||||
errno = EINVAL;
|
||||
return -nr; /* return the index (starting at 1) of the first element that couldn't be applied */
|
||||
}
|
||||
1509
src/3rdparty/hwloc/src/distances.c
vendored
1509
src/3rdparty/hwloc/src/distances.c
vendored
File diff suppressed because it is too large
Load Diff
1199
src/3rdparty/hwloc/src/memattrs.c
vendored
1199
src/3rdparty/hwloc/src/memattrs.c
vendored
File diff suppressed because it is too large
Load Diff
153
src/3rdparty/hwloc/src/misc.c
vendored
153
src/3rdparty/hwloc/src/misc.c
vendored
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "private/autogen/config.h"
|
||||
#include "private/private.h"
|
||||
#include "private/misc.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#ifdef HAVE_SYS_UTSNAME_H
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef HAVE_PROGRAM_INVOCATION_NAME
|
||||
#include <errno.h>
|
||||
extern char *program_invocation_name;
|
||||
#endif
|
||||
#ifdef HAVE___PROGNAME
|
||||
extern char *__progname;
|
||||
#endif
|
||||
|
||||
#ifndef HWLOC_HAVE_CORRECT_SNPRINTF
|
||||
int hwloc_snprintf(char *str, size_t size, const char *format, ...)
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
static char bin;
|
||||
size_t fakesize;
|
||||
char *fakestr;
|
||||
|
||||
/* Some systems crash on str == NULL */
|
||||
if (!size) {
|
||||
str = &bin;
|
||||
size = 1;
|
||||
}
|
||||
|
||||
va_start(ap, format);
|
||||
ret = vsnprintf(str, size, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (ret >= 0 && (size_t) ret != size-1)
|
||||
return ret;
|
||||
|
||||
/* vsnprintf returned size-1 or -1. That could be a system which reports the
|
||||
* written data and not the actually required room. Try increasing buffer
|
||||
* size to get the latter. */
|
||||
|
||||
fakesize = size;
|
||||
fakestr = NULL;
|
||||
do {
|
||||
fakesize *= 2;
|
||||
free(fakestr);
|
||||
fakestr = malloc(fakesize);
|
||||
if (NULL == fakestr)
|
||||
return -1;
|
||||
va_start(ap, format);
|
||||
errno = 0;
|
||||
ret = vsnprintf(fakestr, fakesize, format, ap);
|
||||
va_end(ap);
|
||||
} while ((size_t) ret == fakesize-1 || (ret < 0 && (!errno || errno == ERANGE)));
|
||||
|
||||
if (ret >= 0 && size) {
|
||||
if (size > (size_t) ret+1)
|
||||
size = ret+1;
|
||||
memcpy(str, fakestr, size-1);
|
||||
str[size-1] = 0;
|
||||
}
|
||||
free(fakestr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
void hwloc_add_uname_info(struct hwloc_topology *topology __hwloc_attribute_unused,
|
||||
void *cached_uname __hwloc_attribute_unused)
|
||||
{
|
||||
#ifdef HAVE_UNAME
|
||||
struct utsname _utsname, *utsname;
|
||||
|
||||
if (hwloc_obj_get_info_by_name(topology->levels[0][0], "OSName"))
|
||||
/* don't annotate twice */
|
||||
return;
|
||||
|
||||
if (cached_uname)
|
||||
utsname = (struct utsname *) cached_uname;
|
||||
else {
|
||||
utsname = &_utsname;
|
||||
if (uname(utsname) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (*utsname->sysname)
|
||||
hwloc_obj_add_info(topology->levels[0][0], "OSName", utsname->sysname);
|
||||
if (*utsname->release)
|
||||
hwloc_obj_add_info(topology->levels[0][0], "OSRelease", utsname->release);
|
||||
if (*utsname->version)
|
||||
hwloc_obj_add_info(topology->levels[0][0], "OSVersion", utsname->version);
|
||||
if (*utsname->nodename)
|
||||
hwloc_obj_add_info(topology->levels[0][0], "HostName", utsname->nodename);
|
||||
if (*utsname->machine)
|
||||
hwloc_obj_add_info(topology->levels[0][0], "Architecture", utsname->machine);
|
||||
#endif /* HAVE_UNAME */
|
||||
}
|
||||
|
||||
char *
|
||||
hwloc_progname(struct hwloc_topology *topology __hwloc_attribute_unused)
|
||||
{
|
||||
#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)
|
||||
return NULL;
|
||||
local_basename = strrchr(name, '\\');
|
||||
if (!local_basename)
|
||||
local_basename = name;
|
||||
else
|
||||
local_basename++;
|
||||
return strdup(local_basename);
|
||||
#else /* !HAVE_GETMODULEFILENAME */
|
||||
const char *name, *local_basename;
|
||||
#if HAVE_DECL_GETPROGNAME
|
||||
name = getprogname(); /* FreeBSD, NetBSD, some Solaris */
|
||||
#elif HAVE_DECL_GETEXECNAME
|
||||
name = getexecname(); /* Solaris */
|
||||
#elif defined HAVE_PROGRAM_INVOCATION_NAME
|
||||
name = program_invocation_name; /* Glibc. BGQ CNK. */
|
||||
/* could use program_invocation_short_name directly, but we have the code to remove the path below anyway */
|
||||
#elif defined HAVE___PROGNAME
|
||||
name = __progname; /* fallback for most unix, used for OpenBSD */
|
||||
#else
|
||||
/* TODO: _NSGetExecutablePath(path, &size) on Darwin */
|
||||
/* TODO: AIX, HPUX */
|
||||
name = NULL;
|
||||
#endif
|
||||
if (!name)
|
||||
return NULL;
|
||||
local_basename = strrchr(name, '/');
|
||||
if (!local_basename)
|
||||
local_basename = name;
|
||||
else
|
||||
local_basename++;
|
||||
return strdup(local_basename);
|
||||
#endif /* !HAVE_GETMODULEFILENAME */
|
||||
}
|
||||
1052
src/3rdparty/hwloc/src/pci-common.c
vendored
1052
src/3rdparty/hwloc/src/pci-common.c
vendored
File diff suppressed because it is too large
Load Diff
300
src/3rdparty/hwloc/src/shmem.c
vendored
300
src/3rdparty/hwloc/src/shmem.c
vendored
@@ -1,300 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2017-2020 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include "private/autogen/config.h"
|
||||
#include "hwloc.h"
|
||||
#include "hwloc/shmem.h"
|
||||
#include "private/private.h"
|
||||
|
||||
#ifndef HWLOC_WIN_SYS
|
||||
|
||||
#include <sys/mman.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
#define HWLOC_SHMEM_HEADER_VERSION 1
|
||||
|
||||
struct hwloc_shmem_header {
|
||||
uint32_t header_version; /* sanity check */
|
||||
uint32_t header_length; /* where the actual topology starts in the file/mapping */
|
||||
uint64_t mmap_address; /* virtual address to pass to mmap */
|
||||
uint64_t mmap_length; /* length to pass to mmap (includes the header) */
|
||||
};
|
||||
|
||||
#define HWLOC_SHMEM_MALLOC_ALIGN 8UL
|
||||
|
||||
static void *
|
||||
tma_shmem_malloc(struct hwloc_tma * tma,
|
||||
size_t length)
|
||||
{
|
||||
void *current = tma->data;
|
||||
tma->data = (char*)tma->data + ((length + HWLOC_SHMEM_MALLOC_ALIGN - 1) & ~(HWLOC_SHMEM_MALLOC_ALIGN - 1));
|
||||
return current;
|
||||
|
||||
}
|
||||
|
||||
static void *
|
||||
tma_get_length_malloc(struct hwloc_tma * tma,
|
||||
size_t length)
|
||||
{
|
||||
size_t *tma_length = tma->data;
|
||||
*tma_length += (length + HWLOC_SHMEM_MALLOC_ALIGN - 1) & ~(HWLOC_SHMEM_MALLOC_ALIGN - 1);
|
||||
return malloc(length);
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_shmem_topology_get_length(hwloc_topology_t topology,
|
||||
size_t *lengthp,
|
||||
unsigned long flags)
|
||||
{
|
||||
hwloc_topology_t new;
|
||||
struct hwloc_tma tma;
|
||||
size_t length = 0;
|
||||
unsigned long pagesize = hwloc_getpagesize(); /* round-up to full page for mmap() */
|
||||
int err;
|
||||
|
||||
if (flags) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tma.malloc = tma_get_length_malloc;
|
||||
tma.dontfree = 0;
|
||||
tma.data = &length;
|
||||
|
||||
err = hwloc__topology_dup(&new, topology, &tma);
|
||||
if (err < 0)
|
||||
return err;
|
||||
hwloc_topology_destroy(new);
|
||||
|
||||
*lengthp = (sizeof(struct hwloc_shmem_header) + length + pagesize - 1) & ~(pagesize - 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_shmem_topology_write(hwloc_topology_t topology,
|
||||
int fd, hwloc_uint64_t fileoffset,
|
||||
void *mmap_address, size_t length,
|
||||
unsigned long flags)
|
||||
{
|
||||
hwloc_topology_t new;
|
||||
struct hwloc_tma tma;
|
||||
struct hwloc_shmem_header header;
|
||||
void *mmap_res;
|
||||
int err;
|
||||
|
||||
if (flags) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* refresh old topology distances so that we don't uselessly duplicate invalid distances
|
||||
* 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);
|
||||
header.mmap_address = (uintptr_t) mmap_address;
|
||||
header.mmap_length = length;
|
||||
|
||||
err = lseek(fd, fileoffset, SEEK_SET);
|
||||
if (err < 0)
|
||||
return -1;
|
||||
|
||||
err = write(fd, &header, sizeof(header));
|
||||
if (err != sizeof(header))
|
||||
return -1;
|
||||
|
||||
err = ftruncate(fd, fileoffset + length);
|
||||
if (err < 0)
|
||||
return -1;
|
||||
|
||||
mmap_res = mmap(mmap_address, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, fileoffset);
|
||||
if (mmap_res == MAP_FAILED)
|
||||
return -1;
|
||||
if (mmap_res != mmap_address) {
|
||||
munmap(mmap_res, length);
|
||||
errno = EBUSY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tma.malloc = tma_shmem_malloc;
|
||||
tma.dontfree = 1;
|
||||
tma.data = (char *)mmap_res + sizeof(header);
|
||||
err = hwloc__topology_dup(&new, topology, &tma);
|
||||
if (err < 0)
|
||||
return err;
|
||||
assert((char*)new == (char*)mmap_address + sizeof(header));
|
||||
|
||||
assert((char *)mmap_res <= (char *)mmap_address + length);
|
||||
|
||||
/* 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);
|
||||
hwloc_components_fini();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp,
|
||||
int fd, hwloc_uint64_t fileoffset,
|
||||
void *mmap_address, size_t length,
|
||||
unsigned long flags)
|
||||
{
|
||||
hwloc_topology_t new, old;
|
||||
struct hwloc_shmem_header header;
|
||||
void *mmap_res;
|
||||
int err;
|
||||
|
||||
if (flags) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = lseek(fd, fileoffset, SEEK_SET);
|
||||
if (err < 0)
|
||||
return -1;
|
||||
|
||||
err = read(fd, &header, sizeof(header));
|
||||
if (err != sizeof(header))
|
||||
return -1;
|
||||
|
||||
if (header.header_version != HWLOC_SHMEM_HEADER_VERSION
|
||||
|| header.header_length != sizeof(header)
|
||||
|| header.mmap_address != (uintptr_t) mmap_address
|
||||
|| header.mmap_length != length) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
mmap_res = mmap(mmap_address, length, PROT_READ, MAP_SHARED, fd, fileoffset);
|
||||
if (mmap_res == MAP_FAILED)
|
||||
return -1;
|
||||
if (mmap_res != mmap_address) {
|
||||
errno = EBUSY;
|
||||
goto out_with_mmap;
|
||||
}
|
||||
|
||||
old = (hwloc_topology_t)((char*)mmap_address + sizeof(header));
|
||||
if (hwloc_topology_abi_check(old) < 0) {
|
||||
errno = EINVAL;
|
||||
goto out_with_mmap;
|
||||
}
|
||||
|
||||
/* enforced by dup() inside shmem_topology_write() */
|
||||
assert(old->is_loaded);
|
||||
assert(old->backends == NULL);
|
||||
assert(old->get_pci_busid_cpuset_backend == NULL);
|
||||
|
||||
hwloc_components_init();
|
||||
|
||||
/* duplicate the topology object so that we ca change use local binding_hooks
|
||||
* (those are likely not mapped at the same location in both processes).
|
||||
*/
|
||||
new = malloc(sizeof(struct hwloc_topology));
|
||||
if (!new)
|
||||
goto out_with_components;
|
||||
memcpy(new, old, sizeof(*old));
|
||||
new->tma = NULL;
|
||||
new->adopted_shmem_addr = mmap_address;
|
||||
new->adopted_shmem_length = length;
|
||||
new->topology_abi = HWLOC_TOPOLOGY_ABI;
|
||||
/* setting binding hooks will touch support arrays, so duplicate them too.
|
||||
* could avoid that by requesting a R/W mmap
|
||||
*/
|
||||
new->support.discovery = malloc(sizeof(*new->support.discovery));
|
||||
new->support.cpubind = malloc(sizeof(*new->support.cpubind));
|
||||
new->support.membind = malloc(sizeof(*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;
|
||||
new->userdata_import_cb = NULL;
|
||||
|
||||
#ifndef HWLOC_DEBUG
|
||||
if (getenv("HWLOC_DEBUG_CHECK"))
|
||||
#endif
|
||||
hwloc_topology_check(new);
|
||||
|
||||
*topologyp = new;
|
||||
return 0;
|
||||
|
||||
out_with_support:
|
||||
free(new->support.discovery);
|
||||
free(new->support.cpubind);
|
||||
free(new->support.membind);
|
||||
free(new->support.misc);
|
||||
free(new);
|
||||
out_with_components:
|
||||
hwloc_components_fini();
|
||||
out_with_mmap:
|
||||
munmap(mmap_res, length);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
hwloc__topology_disadopt(hwloc_topology_t topology)
|
||||
{
|
||||
hwloc_components_fini();
|
||||
munmap(topology->adopted_shmem_addr, topology->adopted_shmem_length);
|
||||
free(topology->support.discovery);
|
||||
free(topology->support.cpubind);
|
||||
free(topology->support.membind);
|
||||
free(topology->support.misc);
|
||||
free(topology);
|
||||
}
|
||||
|
||||
#else /* HWLOC_WIN_SYS */
|
||||
|
||||
int
|
||||
hwloc_shmem_topology_get_length(hwloc_topology_t topology __hwloc_attribute_unused,
|
||||
size_t *lengthp __hwloc_attribute_unused,
|
||||
unsigned long flags __hwloc_attribute_unused)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_shmem_topology_write(hwloc_topology_t topology __hwloc_attribute_unused,
|
||||
int fd __hwloc_attribute_unused, hwloc_uint64_t fileoffset __hwloc_attribute_unused,
|
||||
void *mmap_address __hwloc_attribute_unused, size_t length __hwloc_attribute_unused,
|
||||
unsigned long flags __hwloc_attribute_unused)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp __hwloc_attribute_unused,
|
||||
int fd __hwloc_attribute_unused, hwloc_uint64_t fileoffset __hwloc_attribute_unused,
|
||||
void *mmap_address __hwloc_attribute_unused, size_t length __hwloc_attribute_unused,
|
||||
unsigned long flags __hwloc_attribute_unused)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
hwloc__topology_disadopt(hwloc_topology_t topology __hwloc_attribute_unused)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* HWLOC_WIN_SYS */
|
||||
15
src/3rdparty/hwloc/src/static-components.h
vendored
15
src/3rdparty/hwloc/src/static-components.h
vendored
@@ -1,15 +0,0 @@
|
||||
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;
|
||||
static const struct hwloc_component * hwloc_static_components[] = {
|
||||
&hwloc_noos_component,
|
||||
&hwloc_xml_component,
|
||||
&hwloc_synthetic_component,
|
||||
&hwloc_xml_nolibxml_component,
|
||||
&hwloc_windows_component,
|
||||
&hwloc_x86_component,
|
||||
NULL
|
||||
};
|
||||
80
src/3rdparty/hwloc/src/topology-noos.c
vendored
80
src/3rdparty/hwloc/src/topology-noos.c
vendored
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2019 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.
|
||||
*/
|
||||
|
||||
#include "private/autogen/config.h"
|
||||
#include "hwloc.h"
|
||||
#include "private/private.h"
|
||||
|
||||
static int
|
||||
hwloc_look_noos(struct hwloc_backend *backend, struct hwloc_disc_status *dstatus)
|
||||
{
|
||||
/*
|
||||
* This backend uses the underlying OS.
|
||||
* However we don't enforce topology->is_thissystem so that
|
||||
* we may still force use this backend when debugging with !thissystem.
|
||||
*/
|
||||
|
||||
struct hwloc_topology *topology = backend->topology;
|
||||
int64_t memsize;
|
||||
|
||||
assert(dstatus->phase == HWLOC_DISC_PHASE_CPU);
|
||||
|
||||
if (!topology->levels[0][0]->cpuset) {
|
||||
int nbprocs;
|
||||
/* Nobody (even the x86 backend) created objects yet, setup basic objects */
|
||||
|
||||
nbprocs = hwloc_fallback_nbprocessors(0);
|
||||
if (nbprocs >= 1)
|
||||
topology->support.discovery->pu = 1;
|
||||
else
|
||||
nbprocs = 1;
|
||||
hwloc_alloc_root_sets(topology->levels[0][0]);
|
||||
hwloc_setup_pu_level(topology, nbprocs);
|
||||
}
|
||||
|
||||
memsize = hwloc_fallback_memsize();
|
||||
if (memsize > 0)
|
||||
topology->machine_memory.local_memory = memsize;;
|
||||
|
||||
hwloc_add_uname_info(topology, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct hwloc_backend *
|
||||
hwloc_noos_component_instantiate(struct hwloc_topology *topology,
|
||||
struct hwloc_disc_component *component,
|
||||
unsigned excluded_phases __hwloc_attribute_unused,
|
||||
const void *_data1 __hwloc_attribute_unused,
|
||||
const void *_data2 __hwloc_attribute_unused,
|
||||
const void *_data3 __hwloc_attribute_unused)
|
||||
{
|
||||
struct hwloc_backend *backend;
|
||||
backend = hwloc_backend_alloc(topology, component);
|
||||
if (!backend)
|
||||
return NULL;
|
||||
backend->discover = hwloc_look_noos;
|
||||
return backend;
|
||||
}
|
||||
|
||||
static struct hwloc_disc_component hwloc_noos_disc_component = {
|
||||
"no_os",
|
||||
HWLOC_DISC_PHASE_CPU,
|
||||
HWLOC_DISC_PHASE_GLOBAL,
|
||||
hwloc_noos_component_instantiate,
|
||||
40, /* lower than native OS component, higher than globals */
|
||||
1,
|
||||
NULL
|
||||
};
|
||||
|
||||
const struct hwloc_component hwloc_noos_component = {
|
||||
HWLOC_COMPONENT_ABI,
|
||||
NULL, NULL,
|
||||
HWLOC_COMPONENT_TYPE_DISC,
|
||||
0,
|
||||
&hwloc_noos_disc_component
|
||||
};
|
||||
1564
src/3rdparty/hwloc/src/topology-synthetic.c
vendored
1564
src/3rdparty/hwloc/src/topology-synthetic.c
vendored
File diff suppressed because it is too large
Load Diff
1427
src/3rdparty/hwloc/src/topology-windows.c
vendored
1427
src/3rdparty/hwloc/src/topology-windows.c
vendored
File diff suppressed because it is too large
Load Diff
1861
src/3rdparty/hwloc/src/topology-x86.c
vendored
1861
src/3rdparty/hwloc/src/topology-x86.c
vendored
File diff suppressed because it is too large
Load Diff
907
src/3rdparty/hwloc/src/topology-xml-nolibxml.c
vendored
907
src/3rdparty/hwloc/src/topology-xml-nolibxml.c
vendored
@@ -1,907 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "private/autogen/config.h"
|
||||
#include "hwloc.h"
|
||||
#include "hwloc/plugins.h"
|
||||
#include "private/private.h"
|
||||
#include "private/misc.h"
|
||||
#include "private/xml.h"
|
||||
#include "private/debug.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/*******************
|
||||
* Import routines *
|
||||
*******************/
|
||||
|
||||
struct hwloc__nolibxml_backend_data_s {
|
||||
size_t buflen; /* size of both buffer, set during backend_init() */
|
||||
char *buffer; /* allocated and filled during backend_init() */
|
||||
};
|
||||
|
||||
typedef struct hwloc__nolibxml_import_state_data_s {
|
||||
char *tagbuffer; /* buffer containing the next tag */
|
||||
char *attrbuffer; /* buffer containing the next attribute of the current node */
|
||||
const char *tagname; /* tag name of the current node */
|
||||
int closed; /* set if the current node is auto-closing */
|
||||
} __hwloc_attribute_may_alias * hwloc__nolibxml_import_state_data_t;
|
||||
|
||||
static char *
|
||||
hwloc__nolibxml_import_ignore_spaces(char *buffer)
|
||||
{
|
||||
return buffer + strspn(buffer, " \t\n");
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc__nolibxml_import_next_attr(hwloc__xml_import_state_t state, char **namep, char **valuep)
|
||||
{
|
||||
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
|
||||
size_t namelen;
|
||||
size_t len, escaped;
|
||||
char *buffer, *value, *end;
|
||||
|
||||
if (!nstate->attrbuffer)
|
||||
return -1;
|
||||
|
||||
/* find the beginning of an attribute */
|
||||
buffer = hwloc__nolibxml_import_ignore_spaces(nstate->attrbuffer);
|
||||
namelen = strspn(buffer, "abcdefghijklmnopqrstuvwxyz_");
|
||||
if (buffer[namelen] != '=' || buffer[namelen+1] != '\"')
|
||||
return -1;
|
||||
buffer[namelen] = '\0';
|
||||
*namep = buffer;
|
||||
|
||||
/* find the beginning of its value, and unescape it */
|
||||
*valuep = value = buffer+namelen+2;
|
||||
len = 0; escaped = 0;
|
||||
while (value[len+escaped] != '\"') {
|
||||
if (value[len+escaped] == '&') {
|
||||
if (!strncmp(&value[1+len+escaped], "#10;", 4)) {
|
||||
escaped += 4;
|
||||
value[len] = '\n';
|
||||
} else if (!strncmp(&value[1+len+escaped], "#13;", 4)) {
|
||||
escaped += 4;
|
||||
value[len] = '\r';
|
||||
} else if (!strncmp(&value[1+len+escaped], "#9;", 3)) {
|
||||
escaped += 3;
|
||||
value[len] = '\t';
|
||||
} else if (!strncmp(&value[1+len+escaped], "quot;", 5)) {
|
||||
escaped += 5;
|
||||
value[len] = '\"';
|
||||
} else if (!strncmp(&value[1+len+escaped], "lt;", 3)) {
|
||||
escaped += 3;
|
||||
value[len] = '<';
|
||||
} else if (!strncmp(&value[1+len+escaped], "gt;", 3)) {
|
||||
escaped += 3;
|
||||
value[len] = '>';
|
||||
} else if (!strncmp(&value[1+len+escaped], "amp;", 4)) {
|
||||
escaped += 4;
|
||||
value[len] = '&';
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
value[len] = value[len+escaped];
|
||||
}
|
||||
len++;
|
||||
if (value[len+escaped] == '\0')
|
||||
return -1;
|
||||
}
|
||||
value[len] = '\0';
|
||||
|
||||
/* find next attribute */
|
||||
end = &value[len+escaped+1]; /* skip the ending " */
|
||||
nstate->attrbuffer = hwloc__nolibxml_import_ignore_spaces(end);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc__nolibxml_import_find_child(hwloc__xml_import_state_t state,
|
||||
hwloc__xml_import_state_t childstate,
|
||||
char **tagp)
|
||||
{
|
||||
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
|
||||
hwloc__nolibxml_import_state_data_t nchildstate = (void*) childstate->data;
|
||||
char *buffer = nstate->tagbuffer;
|
||||
char *end;
|
||||
char *tag;
|
||||
size_t namelen;
|
||||
|
||||
childstate->parent = state;
|
||||
childstate->global = state->global;
|
||||
|
||||
/* auto-closed tags have no children */
|
||||
if (nstate->closed)
|
||||
return 0;
|
||||
|
||||
/* find the beginning of the tag */
|
||||
buffer = hwloc__nolibxml_import_ignore_spaces(buffer);
|
||||
if (buffer[0] != '<')
|
||||
return -1;
|
||||
buffer++;
|
||||
|
||||
/* if closing tag, return nothing and do not advance */
|
||||
if (buffer[0] == '/')
|
||||
return 0;
|
||||
|
||||
/* normal tag */
|
||||
nchildstate->tagname = tag = buffer;
|
||||
|
||||
/* find the end, mark it and return it */
|
||||
end = strchr(buffer, '>');
|
||||
if (!end)
|
||||
return -1;
|
||||
end[0] = '\0';
|
||||
nchildstate->tagbuffer = end+1;
|
||||
|
||||
/* handle auto-closing tags */
|
||||
if (end[-1] == '/') {
|
||||
nchildstate->closed = 1;
|
||||
end[-1] = '\0';
|
||||
} else
|
||||
nchildstate->closed = 0;
|
||||
|
||||
/* find attributes */
|
||||
namelen = strspn(buffer, "abcdefghijklmnopqrstuvwxyz1234567890_");
|
||||
|
||||
if (buffer[namelen] == '\0') {
|
||||
/* no attributes */
|
||||
nchildstate->attrbuffer = NULL;
|
||||
*tagp = tag;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (buffer[namelen] != ' ')
|
||||
return -1;
|
||||
|
||||
/* found a space, likely starting attributes */
|
||||
buffer[namelen] = '\0';
|
||||
nchildstate->attrbuffer = buffer+namelen+1;
|
||||
*tagp = tag;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc__nolibxml_import_close_tag(hwloc__xml_import_state_t state)
|
||||
{
|
||||
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
|
||||
char *buffer = nstate->tagbuffer;
|
||||
char *end;
|
||||
|
||||
/* auto-closed tags need nothing */
|
||||
if (nstate->closed)
|
||||
return 0;
|
||||
|
||||
/* find the beginning of the tag */
|
||||
buffer = hwloc__nolibxml_import_ignore_spaces(buffer);
|
||||
if (buffer[0] != '<')
|
||||
return -1;
|
||||
buffer++;
|
||||
|
||||
/* find the end, mark it and return it to the parent */
|
||||
end = strchr(buffer, '>');
|
||||
if (!end)
|
||||
return -1;
|
||||
end[0] = '\0';
|
||||
nstate->tagbuffer = end+1;
|
||||
|
||||
/* if closing tag, return nothing */
|
||||
if (buffer[0] != '/' || strcmp(buffer+1, nstate->tagname) )
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
hwloc__nolibxml_import_close_child(hwloc__xml_import_state_t state)
|
||||
{
|
||||
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
|
||||
hwloc__nolibxml_import_state_data_t nparent = (void*) state->parent->data;
|
||||
nparent->tagbuffer = nstate->tagbuffer;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc__nolibxml_import_get_content(hwloc__xml_import_state_t state,
|
||||
const char **beginp, size_t expected_length)
|
||||
{
|
||||
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
|
||||
char *buffer = nstate->tagbuffer;
|
||||
size_t length;
|
||||
char *end;
|
||||
|
||||
/* auto-closed tags have no content */
|
||||
if (nstate->closed) {
|
||||
if (expected_length)
|
||||
return -1;
|
||||
*beginp = "";
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* find the next tag, where the content ends */
|
||||
end = strchr(buffer, '<');
|
||||
if (!end)
|
||||
return -1;
|
||||
|
||||
length = (size_t) (end-buffer);
|
||||
if (length != expected_length)
|
||||
return -1;
|
||||
nstate->tagbuffer = end;
|
||||
*end = '\0'; /* mark as 0-terminated for now */
|
||||
*beginp = buffer;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
hwloc__nolibxml_import_close_content(hwloc__xml_import_state_t state)
|
||||
{
|
||||
/* put back the '<' that we overwrote to 0-terminate the content */
|
||||
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
|
||||
if (!nstate->closed)
|
||||
*nstate->tagbuffer = '<';
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_nolibxml_look_init(struct hwloc_xml_backend_data_s *bdata,
|
||||
struct hwloc__xml_import_state_s *state)
|
||||
{
|
||||
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
|
||||
struct hwloc__nolibxml_backend_data_s *nbdata = bdata->data;
|
||||
unsigned major, minor;
|
||||
char *end;
|
||||
char *buffer = nbdata->buffer;
|
||||
const char *tagname;
|
||||
|
||||
HWLOC_BUILD_ASSERT(sizeof(*nstate) <= sizeof(state->data));
|
||||
|
||||
/* skip headers */
|
||||
while (!strncmp(buffer, "<?xml ", 6) || !strncmp(buffer, "<!DOCTYPE ", 10)) {
|
||||
buffer = strchr(buffer, '\n');
|
||||
if (!buffer)
|
||||
goto failed;
|
||||
buffer++;
|
||||
}
|
||||
|
||||
/* find topology tag */
|
||||
if (sscanf(buffer, "<topology version=\"%u.%u\">", &major, &minor) == 2) {
|
||||
bdata->version_major = major;
|
||||
bdata->version_minor = minor;
|
||||
end = strchr(buffer, '>') + 1;
|
||||
tagname = "topology";
|
||||
} else if (!strncmp(buffer, "<topology>", 10)) {
|
||||
bdata->version_major = 1;
|
||||
bdata->version_minor = 0;
|
||||
end = buffer + 10;
|
||||
tagname = "topology";
|
||||
} else if (!strncmp(buffer, "<root>", 6)) {
|
||||
bdata->version_major = 0;
|
||||
bdata->version_minor = 9;
|
||||
end = buffer + 6;
|
||||
tagname = "root";
|
||||
} else
|
||||
goto failed;
|
||||
|
||||
state->global->next_attr = hwloc__nolibxml_import_next_attr;
|
||||
state->global->find_child = hwloc__nolibxml_import_find_child;
|
||||
state->global->close_tag = hwloc__nolibxml_import_close_tag;
|
||||
state->global->close_child = hwloc__nolibxml_import_close_child;
|
||||
state->global->get_content = hwloc__nolibxml_import_get_content;
|
||||
state->global->close_content = hwloc__nolibxml_import_close_content;
|
||||
state->parent = NULL;
|
||||
nstate->closed = 0;
|
||||
nstate->tagbuffer = end;
|
||||
nstate->tagname = tagname;
|
||||
nstate->attrbuffer = NULL;
|
||||
return 0; /* success */
|
||||
|
||||
failed:
|
||||
return -1; /* failed */
|
||||
}
|
||||
|
||||
/* can be called at the end of the import (to cleanup things early),
|
||||
* or by backend_exit() if load failed for other reasons.
|
||||
*/
|
||||
static void
|
||||
hwloc_nolibxml_free_buffers(struct hwloc_xml_backend_data_s *bdata)
|
||||
{
|
||||
struct hwloc__nolibxml_backend_data_s *nbdata = bdata->data;
|
||||
if (nbdata->buffer) {
|
||||
free(nbdata->buffer);
|
||||
nbdata->buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hwloc_nolibxml_look_done(struct hwloc_xml_backend_data_s *bdata, int result)
|
||||
{
|
||||
hwloc_nolibxml_free_buffers(bdata);
|
||||
|
||||
if (result < 0 && hwloc__xml_verbose())
|
||||
fprintf(stderr, "Failed to parse XML input with the minimalistic parser. If it was not\n"
|
||||
"generated by hwloc, try enabling full XML support with libxml2.\n");
|
||||
}
|
||||
|
||||
/********************
|
||||
* Backend routines *
|
||||
********************/
|
||||
|
||||
static void
|
||||
hwloc_nolibxml_backend_exit(struct hwloc_xml_backend_data_s *bdata)
|
||||
{
|
||||
struct hwloc__nolibxml_backend_data_s *nbdata = bdata->data;
|
||||
hwloc_nolibxml_free_buffers(bdata);
|
||||
free(nbdata);
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_nolibxml_read_file(const char *xmlpath, char **bufferp, size_t *buflenp)
|
||||
{
|
||||
FILE * file;
|
||||
size_t buflen, offset, readlen;
|
||||
struct stat statbuf;
|
||||
char *buffer, *tmp;
|
||||
size_t ret;
|
||||
|
||||
if (!strcmp(xmlpath, "-"))
|
||||
xmlpath = "/dev/stdin";
|
||||
|
||||
file = fopen(xmlpath, "r");
|
||||
if (!file)
|
||||
goto out;
|
||||
|
||||
/* find the required buffer size for regular files, or use 4k when unknown, we'll realloc later if needed */
|
||||
buflen = 4096;
|
||||
if (!stat(xmlpath, &statbuf))
|
||||
if (S_ISREG(statbuf.st_mode))
|
||||
buflen = statbuf.st_size+1; /* one additional byte so that the first fread() gets EOF too */
|
||||
|
||||
buffer = malloc(buflen+1); /* one more byte for the ending \0 */
|
||||
if (!buffer)
|
||||
goto out_with_file;
|
||||
|
||||
offset = 0; readlen = buflen;
|
||||
while (1) {
|
||||
ret = fread(buffer+offset, 1, readlen, file);
|
||||
|
||||
offset += ret;
|
||||
buffer[offset] = 0;
|
||||
|
||||
if (ret != readlen)
|
||||
break;
|
||||
|
||||
buflen *= 2;
|
||||
tmp = realloc(buffer, buflen+1);
|
||||
if (!tmp)
|
||||
goto out_with_buffer;
|
||||
buffer = tmp;
|
||||
readlen = buflen/2;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
*bufferp = buffer;
|
||||
*buflenp = offset+1;
|
||||
return 0;
|
||||
|
||||
out_with_buffer:
|
||||
free(buffer);
|
||||
out_with_file:
|
||||
fclose(file);
|
||||
out:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_nolibxml_backend_init(struct hwloc_xml_backend_data_s *bdata,
|
||||
const char *xmlpath, const char *xmlbuffer, int xmlbuflen)
|
||||
{
|
||||
struct hwloc__nolibxml_backend_data_s *nbdata = malloc(sizeof(*nbdata));
|
||||
|
||||
if (!nbdata)
|
||||
goto out;
|
||||
bdata->data = nbdata;
|
||||
|
||||
if (xmlbuffer) {
|
||||
nbdata->buffer = malloc(xmlbuflen+1);
|
||||
if (!nbdata->buffer)
|
||||
goto out_with_nbdata;
|
||||
nbdata->buflen = xmlbuflen+1;
|
||||
memcpy(nbdata->buffer, xmlbuffer, xmlbuflen);
|
||||
nbdata->buffer[xmlbuflen] = '\0';
|
||||
|
||||
} else {
|
||||
int err = hwloc_nolibxml_read_file(xmlpath, &nbdata->buffer, &nbdata->buflen);
|
||||
if (err < 0)
|
||||
goto out_with_nbdata;
|
||||
}
|
||||
|
||||
bdata->look_init = hwloc_nolibxml_look_init;
|
||||
bdata->look_done = hwloc_nolibxml_look_done;
|
||||
bdata->backend_exit = hwloc_nolibxml_backend_exit;
|
||||
return 0;
|
||||
|
||||
out_with_nbdata:
|
||||
free(nbdata);
|
||||
out:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_nolibxml_import_diff(struct hwloc__xml_import_state_s *state,
|
||||
const char *xmlpath, const char *xmlbuffer, int xmlbuflen,
|
||||
hwloc_topology_diff_t *firstdiffp, char **refnamep)
|
||||
{
|
||||
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
|
||||
struct hwloc__xml_import_state_s childstate;
|
||||
char *refname = NULL;
|
||||
char *buffer, *tmp, *tag;
|
||||
size_t buflen;
|
||||
int ret;
|
||||
|
||||
HWLOC_BUILD_ASSERT(sizeof(*nstate) <= sizeof(state->data));
|
||||
|
||||
if (xmlbuffer) {
|
||||
buffer = malloc(xmlbuflen);
|
||||
if (!buffer)
|
||||
goto out;
|
||||
memcpy(buffer, xmlbuffer, xmlbuflen);
|
||||
buflen = xmlbuflen;
|
||||
|
||||
} else {
|
||||
ret = hwloc_nolibxml_read_file(xmlpath, &buffer, &buflen);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* skip headers */
|
||||
tmp = buffer;
|
||||
while (!strncmp(tmp, "<?xml ", 6) || !strncmp(tmp, "<!DOCTYPE ", 10)) {
|
||||
tmp = strchr(tmp, '\n');
|
||||
if (!tmp)
|
||||
goto out_with_buffer;
|
||||
tmp++;
|
||||
}
|
||||
|
||||
state->global->next_attr = hwloc__nolibxml_import_next_attr;
|
||||
state->global->find_child = hwloc__nolibxml_import_find_child;
|
||||
state->global->close_tag = hwloc__nolibxml_import_close_tag;
|
||||
state->global->close_child = hwloc__nolibxml_import_close_child;
|
||||
state->global->get_content = hwloc__nolibxml_import_get_content;
|
||||
state->global->close_content = hwloc__nolibxml_import_close_content;
|
||||
state->parent = NULL;
|
||||
nstate->closed = 0;
|
||||
nstate->tagbuffer = tmp;
|
||||
nstate->tagname = NULL;
|
||||
nstate->attrbuffer = NULL;
|
||||
|
||||
/* find root */
|
||||
ret = hwloc__nolibxml_import_find_child(state, &childstate, &tag);
|
||||
if (ret < 0)
|
||||
goto out_with_buffer;
|
||||
if (!tag || strcmp(tag, "topologydiff"))
|
||||
goto out_with_buffer;
|
||||
|
||||
while (1) {
|
||||
char *attrname, *attrvalue;
|
||||
if (hwloc__nolibxml_import_next_attr(&childstate, &attrname, &attrvalue) < 0)
|
||||
break;
|
||||
if (!strcmp(attrname, "refname")) {
|
||||
free(refname);
|
||||
refname = strdup(attrvalue);
|
||||
} else
|
||||
goto out_with_buffer;
|
||||
}
|
||||
|
||||
ret = hwloc__xml_import_diff(&childstate, firstdiffp);
|
||||
if (refnamep && !ret)
|
||||
*refnamep = refname;
|
||||
else
|
||||
free(refname);
|
||||
|
||||
free(buffer);
|
||||
return ret;
|
||||
|
||||
out_with_buffer:
|
||||
free(buffer);
|
||||
free(refname);
|
||||
out:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*******************
|
||||
* Export routines *
|
||||
*******************/
|
||||
|
||||
typedef struct hwloc__nolibxml_export_state_data_s {
|
||||
char *buffer; /* (moving) buffer where to write */
|
||||
size_t written; /* how many bytes were written (or would have be written if not truncated) */
|
||||
size_t remaining; /* how many bytes are still available in the buffer */
|
||||
unsigned indent; /* indentation level for the next line */
|
||||
unsigned nr_children;
|
||||
unsigned has_content;
|
||||
} __hwloc_attribute_may_alias * hwloc__nolibxml_export_state_data_t;
|
||||
|
||||
static void
|
||||
hwloc__nolibxml_export_update_buffer(hwloc__nolibxml_export_state_data_t ndata, int res)
|
||||
{
|
||||
if (res >= 0) {
|
||||
ndata->written += res;
|
||||
if (res >= (int) ndata->remaining)
|
||||
res = ndata->remaining>0 ? (int)ndata->remaining-1 : 0;
|
||||
ndata->buffer += res;
|
||||
ndata->remaining -= res;
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
hwloc__nolibxml_export_escape_string(const char *src)
|
||||
{
|
||||
size_t fulllen, sublen;
|
||||
char *escaped, *dst;
|
||||
|
||||
fulllen = strlen(src);
|
||||
|
||||
sublen = strcspn(src, "\n\r\t\"<>&");
|
||||
if (sublen == fulllen)
|
||||
return NULL; /* nothing to escape */
|
||||
|
||||
escaped = malloc(fulllen*6+1); /* escaped chars are replaced by at most 6 char */
|
||||
dst = escaped;
|
||||
|
||||
memcpy(dst, src, sublen);
|
||||
src += sublen;
|
||||
dst += sublen;
|
||||
|
||||
while (*src) {
|
||||
int replen;
|
||||
switch (*src) {
|
||||
case '\n': strcpy(dst, " "); replen=5; break;
|
||||
case '\r': strcpy(dst, " "); replen=5; break;
|
||||
case '\t': strcpy(dst, "	"); replen=4; break;
|
||||
case '\"': strcpy(dst, """); replen=6; break;
|
||||
case '<': strcpy(dst, "<"); replen=4; break;
|
||||
case '>': strcpy(dst, ">"); replen=4; break;
|
||||
case '&': strcpy(dst, "&"); replen=5; break;
|
||||
default: replen=0; break;
|
||||
}
|
||||
dst+=replen; src++;
|
||||
|
||||
sublen = strcspn(src, "\n\r\t\"<>&");
|
||||
memcpy(dst, src, sublen);
|
||||
src += sublen;
|
||||
dst += sublen;
|
||||
}
|
||||
|
||||
*dst = 0;
|
||||
return escaped;
|
||||
}
|
||||
|
||||
static void
|
||||
hwloc__nolibxml_export_new_child(hwloc__xml_export_state_t parentstate,
|
||||
hwloc__xml_export_state_t state,
|
||||
const char *name)
|
||||
{
|
||||
hwloc__nolibxml_export_state_data_t npdata = (void *) parentstate->data;
|
||||
hwloc__nolibxml_export_state_data_t ndata = (void *) state->data;
|
||||
int res;
|
||||
|
||||
assert(!npdata->has_content);
|
||||
if (!npdata->nr_children) {
|
||||
res = hwloc_snprintf(npdata->buffer, npdata->remaining, ">\n");
|
||||
hwloc__nolibxml_export_update_buffer(npdata, res);
|
||||
}
|
||||
npdata->nr_children++;
|
||||
|
||||
state->parent = parentstate;
|
||||
state->new_child = parentstate->new_child;
|
||||
state->new_prop = parentstate->new_prop;
|
||||
state->add_content = parentstate->add_content;
|
||||
state->end_object = parentstate->end_object;
|
||||
state->global = parentstate->global;
|
||||
|
||||
ndata->buffer = npdata->buffer;
|
||||
ndata->written = npdata->written;
|
||||
ndata->remaining = npdata->remaining;
|
||||
ndata->indent = npdata->indent + 2;
|
||||
|
||||
ndata->nr_children = 0;
|
||||
ndata->has_content = 0;
|
||||
|
||||
res = hwloc_snprintf(ndata->buffer, ndata->remaining, "%*s<%s", (int) npdata->indent, "", name);
|
||||
hwloc__nolibxml_export_update_buffer(ndata, res);
|
||||
}
|
||||
|
||||
static void
|
||||
hwloc__nolibxml_export_new_prop(hwloc__xml_export_state_t state, const char *name, const char *value)
|
||||
{
|
||||
hwloc__nolibxml_export_state_data_t ndata = (void *) state->data;
|
||||
char *escaped = hwloc__nolibxml_export_escape_string(value);
|
||||
int res = hwloc_snprintf(ndata->buffer, ndata->remaining, " %s=\"%s\"", name, escaped ? (const char *) escaped : value);
|
||||
hwloc__nolibxml_export_update_buffer(ndata, res);
|
||||
free(escaped);
|
||||
}
|
||||
|
||||
static void
|
||||
hwloc__nolibxml_export_end_object(hwloc__xml_export_state_t state, const char *name)
|
||||
{
|
||||
hwloc__nolibxml_export_state_data_t ndata = (void *) state->data;
|
||||
hwloc__nolibxml_export_state_data_t npdata = (void *) state->parent->data;
|
||||
int res;
|
||||
|
||||
assert (!(ndata->has_content && ndata->nr_children));
|
||||
if (ndata->has_content) {
|
||||
res = hwloc_snprintf(ndata->buffer, ndata->remaining, "</%s>\n", name);
|
||||
} else if (ndata->nr_children) {
|
||||
res = hwloc_snprintf(ndata->buffer, ndata->remaining, "%*s</%s>\n", (int) npdata->indent, "", name);
|
||||
} else {
|
||||
res = hwloc_snprintf(ndata->buffer, ndata->remaining, "/>\n");
|
||||
}
|
||||
hwloc__nolibxml_export_update_buffer(ndata, res);
|
||||
|
||||
npdata->buffer = ndata->buffer;
|
||||
npdata->written = ndata->written;
|
||||
npdata->remaining = ndata->remaining;
|
||||
}
|
||||
|
||||
static void
|
||||
hwloc__nolibxml_export_add_content(hwloc__xml_export_state_t state, const char *buffer, size_t length __hwloc_attribute_unused)
|
||||
{
|
||||
hwloc__nolibxml_export_state_data_t ndata = (void *) state->data;
|
||||
int res;
|
||||
|
||||
assert(!ndata->nr_children);
|
||||
if (!ndata->has_content) {
|
||||
res = hwloc_snprintf(ndata->buffer, ndata->remaining, ">");
|
||||
hwloc__nolibxml_export_update_buffer(ndata, res);
|
||||
}
|
||||
ndata->has_content = 1;
|
||||
|
||||
res = hwloc_snprintf(ndata->buffer, ndata->remaining, "%s", buffer);
|
||||
hwloc__nolibxml_export_update_buffer(ndata, res);
|
||||
}
|
||||
|
||||
static size_t
|
||||
hwloc___nolibxml_prepare_export(hwloc_topology_t topology, struct hwloc__xml_export_data_s *edata,
|
||||
char *xmlbuffer, int buflen, unsigned long flags)
|
||||
{
|
||||
struct hwloc__xml_export_state_s state, childstate;
|
||||
hwloc__nolibxml_export_state_data_t ndata = (void *) &state.data;
|
||||
int v1export = flags & HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1;
|
||||
int res;
|
||||
|
||||
HWLOC_BUILD_ASSERT(sizeof(*ndata) <= sizeof(state.data));
|
||||
|
||||
state.new_child = hwloc__nolibxml_export_new_child;
|
||||
state.new_prop = hwloc__nolibxml_export_new_prop;
|
||||
state.add_content = hwloc__nolibxml_export_add_content;
|
||||
state.end_object = hwloc__nolibxml_export_end_object;
|
||||
state.global = edata;
|
||||
|
||||
ndata->indent = 0;
|
||||
ndata->written = 0;
|
||||
ndata->buffer = xmlbuffer;
|
||||
ndata->remaining = buflen;
|
||||
|
||||
ndata->nr_children = 1; /* don't close a non-existing previous tag when opening the topology tag */
|
||||
ndata->has_content = 0;
|
||||
|
||||
res = hwloc_snprintf(ndata->buffer, ndata->remaining,
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<!DOCTYPE topology SYSTEM \"%s\">\n", v1export ? "hwloc.dtd" : "hwloc2.dtd");
|
||||
hwloc__nolibxml_export_update_buffer(ndata, res);
|
||||
hwloc__nolibxml_export_new_child(&state, &childstate, "topology");
|
||||
if (!(flags & HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1))
|
||||
hwloc__nolibxml_export_new_prop(&childstate, "version", "2.0");
|
||||
hwloc__xml_export_topology (&childstate, topology, flags);
|
||||
hwloc__nolibxml_export_end_object(&childstate, "topology");
|
||||
|
||||
return ndata->written+1; /* ending \0 */
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_nolibxml_export_buffer(hwloc_topology_t topology, struct hwloc__xml_export_data_s *edata,
|
||||
char **bufferp, int *buflenp, unsigned long flags)
|
||||
{
|
||||
char *buffer;
|
||||
size_t bufferlen, res;
|
||||
|
||||
bufferlen = 16384; /* random guess for large enough default */
|
||||
buffer = malloc(bufferlen);
|
||||
if (!buffer)
|
||||
return -1;
|
||||
res = hwloc___nolibxml_prepare_export(topology, edata, buffer, (int)bufferlen, flags);
|
||||
|
||||
if (res > bufferlen) {
|
||||
char *tmp = realloc(buffer, res);
|
||||
if (!tmp) {
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
buffer = tmp;
|
||||
hwloc___nolibxml_prepare_export(topology, edata, buffer, (int)res, flags);
|
||||
}
|
||||
|
||||
*bufferp = buffer;
|
||||
*buflenp = (int)res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_nolibxml_export_file(hwloc_topology_t topology, struct hwloc__xml_export_data_s *edata,
|
||||
const char *filename, unsigned long flags)
|
||||
{
|
||||
FILE *file;
|
||||
char *buffer;
|
||||
int bufferlen;
|
||||
int ret;
|
||||
|
||||
ret = hwloc_nolibxml_export_buffer(topology, edata, &buffer, &bufferlen, flags);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
if (!strcmp(filename, "-")) {
|
||||
file = stdout;
|
||||
} else {
|
||||
file = fopen(filename, "w");
|
||||
if (!file) {
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = (int)fwrite(buffer, 1, bufferlen-1 /* don't write the ending \0 */, file);
|
||||
if (ret == bufferlen-1) {
|
||||
ret = 0;
|
||||
} else {
|
||||
errno = ferror(file);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
|
||||
if (file != stdout)
|
||||
fclose(file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static size_t
|
||||
hwloc___nolibxml_prepare_export_diff(hwloc_topology_diff_t diff, const char *refname, char *xmlbuffer, int buflen)
|
||||
{
|
||||
struct hwloc__xml_export_state_s state, childstate;
|
||||
hwloc__nolibxml_export_state_data_t ndata = (void *) &state.data;
|
||||
int res;
|
||||
|
||||
HWLOC_BUILD_ASSERT(sizeof(*ndata) <= sizeof(state.data));
|
||||
|
||||
state.new_child = hwloc__nolibxml_export_new_child;
|
||||
state.new_prop = hwloc__nolibxml_export_new_prop;
|
||||
state.add_content = hwloc__nolibxml_export_add_content;
|
||||
state.end_object = hwloc__nolibxml_export_end_object;
|
||||
state.global = NULL;
|
||||
|
||||
ndata->indent = 0;
|
||||
ndata->written = 0;
|
||||
ndata->buffer = xmlbuffer;
|
||||
ndata->remaining = buflen;
|
||||
|
||||
ndata->nr_children = 1; /* don't close a non-existing previous tag when opening the topology tag */
|
||||
ndata->has_content = 0;
|
||||
|
||||
res = hwloc_snprintf(ndata->buffer, ndata->remaining,
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<!DOCTYPE topologydiff SYSTEM \"hwloc2-diff.dtd\">\n");
|
||||
hwloc__nolibxml_export_update_buffer(ndata, res);
|
||||
hwloc__nolibxml_export_new_child(&state, &childstate, "topologydiff");
|
||||
if (refname)
|
||||
hwloc__nolibxml_export_new_prop(&childstate, "refname", refname);
|
||||
hwloc__xml_export_diff (&childstate, diff);
|
||||
hwloc__nolibxml_export_end_object(&childstate, "topologydiff");
|
||||
|
||||
return ndata->written+1;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_nolibxml_export_diff_buffer(hwloc_topology_diff_t diff, const char *refname, char **bufferp, int *buflenp)
|
||||
{
|
||||
char *buffer;
|
||||
size_t bufferlen, res;
|
||||
|
||||
bufferlen = 16384; /* random guess for large enough default */
|
||||
buffer = malloc(bufferlen);
|
||||
if (!buffer)
|
||||
return -1;
|
||||
res = hwloc___nolibxml_prepare_export_diff(diff, refname, buffer, (int)bufferlen);
|
||||
|
||||
if (res > bufferlen) {
|
||||
char *tmp = realloc(buffer, res);
|
||||
if (!tmp) {
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
buffer = tmp;
|
||||
hwloc___nolibxml_prepare_export_diff(diff, refname, buffer, (int)res);
|
||||
}
|
||||
|
||||
*bufferp = buffer;
|
||||
*buflenp = (int)res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc_nolibxml_export_diff_file(hwloc_topology_diff_t diff, const char *refname, const char *filename)
|
||||
{
|
||||
FILE *file;
|
||||
char *buffer;
|
||||
int bufferlen;
|
||||
int ret;
|
||||
|
||||
ret = hwloc_nolibxml_export_diff_buffer(diff, refname, &buffer, &bufferlen);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
if (!strcmp(filename, "-")) {
|
||||
file = stdout;
|
||||
} else {
|
||||
file = fopen(filename, "w");
|
||||
if (!file) {
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = (int)fwrite(buffer, 1, bufferlen-1 /* don't write the ending \0 */, file);
|
||||
if (ret == bufferlen-1) {
|
||||
ret = 0;
|
||||
} else {
|
||||
errno = ferror(file);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
|
||||
if (file != stdout)
|
||||
fclose(file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
hwloc_nolibxml_free_buffer(void *xmlbuffer)
|
||||
{
|
||||
free(xmlbuffer);
|
||||
}
|
||||
|
||||
/*************
|
||||
* Callbacks *
|
||||
*************/
|
||||
|
||||
static struct hwloc_xml_callbacks hwloc_xml_nolibxml_callbacks = {
|
||||
hwloc_nolibxml_backend_init,
|
||||
hwloc_nolibxml_export_file,
|
||||
hwloc_nolibxml_export_buffer,
|
||||
hwloc_nolibxml_free_buffer,
|
||||
hwloc_nolibxml_import_diff,
|
||||
hwloc_nolibxml_export_diff_file,
|
||||
hwloc_nolibxml_export_diff_buffer
|
||||
};
|
||||
|
||||
static struct hwloc_xml_component hwloc_nolibxml_xml_component = {
|
||||
&hwloc_xml_nolibxml_callbacks,
|
||||
NULL
|
||||
};
|
||||
|
||||
const struct hwloc_component hwloc_xml_nolibxml_component = {
|
||||
HWLOC_COMPONENT_ABI,
|
||||
NULL, NULL,
|
||||
HWLOC_COMPONENT_TYPE_XML,
|
||||
0,
|
||||
&hwloc_nolibxml_xml_component
|
||||
};
|
||||
3705
src/3rdparty/hwloc/src/topology-xml.c
vendored
3705
src/3rdparty/hwloc/src/topology-xml.c
vendored
File diff suppressed because it is too large
Load Diff
5170
src/3rdparty/hwloc/src/topology.c
vendored
5170
src/3rdparty/hwloc/src/topology.c
vendored
File diff suppressed because it is too large
Load Diff
837
src/3rdparty/hwloc/src/traversal.c
vendored
837
src/3rdparty/hwloc/src/traversal.c
vendored
@@ -1,837 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2021 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.
|
||||
*/
|
||||
|
||||
#include "private/autogen/config.h"
|
||||
#include "hwloc.h"
|
||||
#include "private/private.h"
|
||||
#include "private/misc.h"
|
||||
#include "private/debug.h"
|
||||
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif /* HAVE_STRINGS_H */
|
||||
|
||||
int
|
||||
hwloc_get_type_depth (struct hwloc_topology *topology, hwloc_obj_type_t type)
|
||||
{
|
||||
HWLOC_BUILD_ASSERT(HWLOC_OBJ_TYPE_MIN == 0);
|
||||
if ((unsigned) type >= HWLOC_OBJ_TYPE_MAX)
|
||||
return HWLOC_TYPE_DEPTH_UNKNOWN;
|
||||
else
|
||||
return topology->type_depth[type];
|
||||
}
|
||||
|
||||
hwloc_obj_type_t
|
||||
hwloc_get_depth_type (hwloc_topology_t topology, int depth)
|
||||
{
|
||||
if ((unsigned)depth >= topology->nb_levels)
|
||||
switch (depth) {
|
||||
case HWLOC_TYPE_DEPTH_NUMANODE:
|
||||
return HWLOC_OBJ_NUMANODE;
|
||||
case HWLOC_TYPE_DEPTH_BRIDGE:
|
||||
return HWLOC_OBJ_BRIDGE;
|
||||
case HWLOC_TYPE_DEPTH_PCI_DEVICE:
|
||||
return HWLOC_OBJ_PCI_DEVICE;
|
||||
case HWLOC_TYPE_DEPTH_OS_DEVICE:
|
||||
return HWLOC_OBJ_OS_DEVICE;
|
||||
case HWLOC_TYPE_DEPTH_MISC:
|
||||
return HWLOC_OBJ_MISC;
|
||||
case HWLOC_TYPE_DEPTH_MEMCACHE:
|
||||
return HWLOC_OBJ_MEMCACHE;
|
||||
default:
|
||||
return HWLOC_OBJ_TYPE_NONE;
|
||||
}
|
||||
return topology->levels[depth][0]->type;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_get_memory_parents_depth (hwloc_topology_t topology)
|
||||
{
|
||||
int depth = HWLOC_TYPE_DEPTH_UNKNOWN;
|
||||
/* memory leaves are always NUMA nodes for now, no need to check parents of other memory types */
|
||||
hwloc_obj_t numa = hwloc_get_obj_by_depth(topology, HWLOC_TYPE_DEPTH_NUMANODE, 0);
|
||||
assert(numa);
|
||||
while (numa) {
|
||||
hwloc_obj_t parent = numa->parent;
|
||||
/* walk-up the memory hierarchy */
|
||||
while (hwloc__obj_type_is_memory(parent->type))
|
||||
parent = parent->parent;
|
||||
|
||||
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
|
||||
depth = parent->depth;
|
||||
else if (depth != parent->depth)
|
||||
return HWLOC_TYPE_DEPTH_MULTIPLE;
|
||||
|
||||
numa = numa->next_cousin;
|
||||
}
|
||||
|
||||
assert(depth >= 0);
|
||||
return depth;
|
||||
}
|
||||
|
||||
unsigned
|
||||
hwloc_get_nbobjs_by_depth (struct hwloc_topology *topology, int depth)
|
||||
{
|
||||
if ((unsigned)depth >= topology->nb_levels) {
|
||||
unsigned l = HWLOC_SLEVEL_FROM_DEPTH(depth);
|
||||
if (l < HWLOC_NR_SLEVELS)
|
||||
return topology->slevels[l].nbobjs;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return topology->level_nbobjects[depth];
|
||||
}
|
||||
|
||||
struct hwloc_obj *
|
||||
hwloc_get_obj_by_depth (struct hwloc_topology *topology, int depth, unsigned idx)
|
||||
{
|
||||
if ((unsigned)depth >= topology->nb_levels) {
|
||||
unsigned l = HWLOC_SLEVEL_FROM_DEPTH(depth);
|
||||
if (l < HWLOC_NR_SLEVELS)
|
||||
return idx < topology->slevels[l].nbobjs ? topology->slevels[l].objs[idx] : NULL;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
if (idx >= topology->level_nbobjects[depth])
|
||||
return NULL;
|
||||
return topology->levels[depth][idx];
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_obj_type_is_normal(hwloc_obj_type_t type)
|
||||
{
|
||||
return hwloc__obj_type_is_normal(type);
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_obj_type_is_memory(hwloc_obj_type_t type)
|
||||
{
|
||||
return hwloc__obj_type_is_memory(type);
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_obj_type_is_io(hwloc_obj_type_t type)
|
||||
{
|
||||
return hwloc__obj_type_is_io(type);
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_obj_type_is_cache(hwloc_obj_type_t type)
|
||||
{
|
||||
return hwloc__obj_type_is_cache(type);
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_obj_type_is_dcache(hwloc_obj_type_t type)
|
||||
{
|
||||
return hwloc__obj_type_is_dcache(type);
|
||||
}
|
||||
|
||||
int
|
||||
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;
|
||||
unsigned i,src_nbobjects;
|
||||
unsigned stored = 0;
|
||||
|
||||
if (!src->cpuset)
|
||||
return 0;
|
||||
|
||||
src_nbobjects = topology->level_nbobjects[src->depth];
|
||||
src_objs = topology->levels[src->depth];
|
||||
|
||||
parent = src;
|
||||
while (stored < max) {
|
||||
while (1) {
|
||||
nextparent = parent->parent;
|
||||
if (!nextparent)
|
||||
goto out;
|
||||
if (!hwloc_bitmap_isequal(parent->cpuset, nextparent->cpuset))
|
||||
break;
|
||||
parent = nextparent;
|
||||
}
|
||||
|
||||
/* traverse src's objects and find those that are in nextparent and were not in parent */
|
||||
for(i=0; i<src_nbobjects; i++) {
|
||||
if (hwloc_bitmap_isincluded(src_objs[i]->cpuset, nextparent->cpuset)
|
||||
&& !hwloc_bitmap_isincluded(src_objs[i]->cpuset, parent->cpuset)) {
|
||||
objs[stored++] = src_objs[i];
|
||||
if (stored == max)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
parent = nextparent;
|
||||
}
|
||||
|
||||
out:
|
||||
return stored;
|
||||
}
|
||||
|
||||
static int
|
||||
hwloc__get_largest_objs_inside_cpuset (struct hwloc_obj *current, hwloc_const_bitmap_t set,
|
||||
struct hwloc_obj ***res, int *max)
|
||||
{
|
||||
int gotten = 0;
|
||||
unsigned i;
|
||||
|
||||
/* the caller must ensure this */
|
||||
if (*max <= 0)
|
||||
return 0;
|
||||
|
||||
if (hwloc_bitmap_isequal(current->cpuset, set)) {
|
||||
**res = current;
|
||||
(*res)++;
|
||||
(*max)--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i=0; i<current->arity; i++) {
|
||||
hwloc_bitmap_t subset;
|
||||
int ret;
|
||||
|
||||
/* split out the cpuset part corresponding to this child and see if there's anything to do */
|
||||
if (!hwloc_bitmap_intersects(set,current->children[i]->cpuset))
|
||||
continue;
|
||||
|
||||
subset = hwloc_bitmap_dup(set);
|
||||
hwloc_bitmap_and(subset, subset, current->children[i]->cpuset);
|
||||
ret = hwloc__get_largest_objs_inside_cpuset (current->children[i], subset, res, max);
|
||||
gotten += ret;
|
||||
hwloc_bitmap_free(subset);
|
||||
|
||||
/* if no more room to store remaining objects, return what we got so far */
|
||||
if (!*max)
|
||||
break;
|
||||
}
|
||||
|
||||
return gotten;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_get_largest_objs_inside_cpuset (struct hwloc_topology *topology, hwloc_const_bitmap_t set,
|
||||
struct hwloc_obj **objs, int max)
|
||||
{
|
||||
struct hwloc_obj *current = topology->levels[0][0];
|
||||
|
||||
if (!hwloc_bitmap_isincluded(set, current->cpuset))
|
||||
return -1;
|
||||
|
||||
if (max <= 0)
|
||||
return 0;
|
||||
|
||||
return hwloc__get_largest_objs_inside_cpuset (current, set, &objs, &max);
|
||||
}
|
||||
|
||||
const char *
|
||||
hwloc_obj_type_string (hwloc_obj_type_t obj)
|
||||
{
|
||||
switch (obj)
|
||||
{
|
||||
case HWLOC_OBJ_MACHINE: return "Machine";
|
||||
case HWLOC_OBJ_MISC: return "Misc";
|
||||
case HWLOC_OBJ_GROUP: return "Group";
|
||||
case HWLOC_OBJ_MEMCACHE: return "MemCache";
|
||||
case HWLOC_OBJ_NUMANODE: return "NUMANode";
|
||||
case HWLOC_OBJ_PACKAGE: return "Package";
|
||||
case HWLOC_OBJ_DIE: return "Die";
|
||||
case HWLOC_OBJ_L1CACHE: return "L1Cache";
|
||||
case HWLOC_OBJ_L2CACHE: return "L2Cache";
|
||||
case HWLOC_OBJ_L3CACHE: return "L3Cache";
|
||||
case HWLOC_OBJ_L4CACHE: return "L4Cache";
|
||||
case HWLOC_OBJ_L5CACHE: return "L5Cache";
|
||||
case HWLOC_OBJ_L1ICACHE: return "L1iCache";
|
||||
case HWLOC_OBJ_L2ICACHE: return "L2iCache";
|
||||
case HWLOC_OBJ_L3ICACHE: return "L3iCache";
|
||||
case HWLOC_OBJ_CORE: return "Core";
|
||||
case HWLOC_OBJ_BRIDGE: return "Bridge";
|
||||
case HWLOC_OBJ_PCI_DEVICE: return "PCIDev";
|
||||
case HWLOC_OBJ_OS_DEVICE: return "OSDev";
|
||||
case HWLOC_OBJ_PU: return "PU";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if string matches the given type at least on minmatch chars.
|
||||
* On success, return the address of where matching stop, either pointing to \0 or to a suffix (digits, colon, etc)
|
||||
* On error, return NULL;
|
||||
*/
|
||||
static __hwloc_inline const char *
|
||||
hwloc__type_match(const char *string,
|
||||
const char *type, /* type must be lowercase */
|
||||
size_t minmatch)
|
||||
{
|
||||
const char *s, *t;
|
||||
unsigned i;
|
||||
for(i=0, s=string, t=type; ; i++, s++, t++) {
|
||||
if (!*s) {
|
||||
/* string ends before type */
|
||||
if (i<minmatch)
|
||||
return NULL;
|
||||
else
|
||||
return s;
|
||||
}
|
||||
if (*s != *t && *s != *t + 'A' - 'a') {
|
||||
/* string is different */
|
||||
if ((*s >= 'a' && *s <= 'z') || (*s >= 'A' && *s <= 'Z') || *s == '-')
|
||||
/* valid character that doesn't match */
|
||||
return NULL;
|
||||
/* invalid character, we reached the end of the type namein string, stop matching here */
|
||||
if (i<minmatch)
|
||||
return NULL;
|
||||
else
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
|
||||
union hwloc_obj_attr_u *attrp, size_t attrsize)
|
||||
{
|
||||
hwloc_obj_type_t type = (hwloc_obj_type_t) -1;
|
||||
unsigned depthattr = (unsigned) -1;
|
||||
hwloc_obj_cache_type_t cachetypeattr = (hwloc_obj_cache_type_t) -1; /* unspecified */
|
||||
hwloc_obj_bridge_type_t ubtype = (hwloc_obj_bridge_type_t) -1;
|
||||
hwloc_obj_osdev_type_t ostype = (hwloc_obj_osdev_type_t) -1;
|
||||
char *end;
|
||||
|
||||
/* Never match the ending \0 since we want to match things like core:2 too.
|
||||
* We'll only compare the beginning substring only made of letters and dash.
|
||||
*/
|
||||
|
||||
/* types without a custom depth */
|
||||
|
||||
/* osdev subtype first to avoid conflicts coproc/core etc */
|
||||
if (hwloc__type_match(string, "osdev", 2)) {
|
||||
type = HWLOC_OBJ_OS_DEVICE;
|
||||
} else if (hwloc__type_match(string, "block", 4)) {
|
||||
type = HWLOC_OBJ_OS_DEVICE;
|
||||
ostype = HWLOC_OBJ_OSDEV_BLOCK;
|
||||
} else if (hwloc__type_match(string, "network", 3)) {
|
||||
type = HWLOC_OBJ_OS_DEVICE;
|
||||
ostype = HWLOC_OBJ_OSDEV_NETWORK;
|
||||
} else if (hwloc__type_match(string, "openfabrics", 7)) {
|
||||
type = HWLOC_OBJ_OS_DEVICE;
|
||||
ostype = HWLOC_OBJ_OSDEV_OPENFABRICS;
|
||||
} else if (hwloc__type_match(string, "dma", 3)) {
|
||||
type = HWLOC_OBJ_OS_DEVICE;
|
||||
ostype = HWLOC_OBJ_OSDEV_DMA;
|
||||
} else if (hwloc__type_match(string, "gpu", 3)) {
|
||||
type = HWLOC_OBJ_OS_DEVICE;
|
||||
ostype = HWLOC_OBJ_OSDEV_GPU;
|
||||
} else if (hwloc__type_match(string, "coproc", 5)
|
||||
|| hwloc__type_match(string, "co-processor", 6)) {
|
||||
type = HWLOC_OBJ_OS_DEVICE;
|
||||
ostype = HWLOC_OBJ_OSDEV_COPROC;
|
||||
|
||||
} else if (hwloc__type_match(string, "machine", 2)) {
|
||||
type = HWLOC_OBJ_MACHINE;
|
||||
} else if (hwloc__type_match(string, "numanode", 2)
|
||||
|| hwloc__type_match(string, "node", 2)) { /* for convenience */
|
||||
type = HWLOC_OBJ_NUMANODE;
|
||||
} else if (hwloc__type_match(string, "memcache", 5)
|
||||
|| hwloc__type_match(string, "memory-side cache", 8)) {
|
||||
type = HWLOC_OBJ_MEMCACHE;
|
||||
} else if (hwloc__type_match(string, "package", 2)
|
||||
|| hwloc__type_match(string, "socket", 2)) { /* backward compat with v1.10 */
|
||||
type = HWLOC_OBJ_PACKAGE;
|
||||
} else if (hwloc__type_match(string, "die", 2)) {
|
||||
type = HWLOC_OBJ_DIE;
|
||||
} else if (hwloc__type_match(string, "core", 2)) {
|
||||
type = HWLOC_OBJ_CORE;
|
||||
} else if (hwloc__type_match(string, "pu", 2)) {
|
||||
type = HWLOC_OBJ_PU;
|
||||
} else if (hwloc__type_match(string, "misc", 4)) {
|
||||
type = HWLOC_OBJ_MISC;
|
||||
|
||||
} else if (hwloc__type_match(string, "bridge", 4)) {
|
||||
type = HWLOC_OBJ_BRIDGE;
|
||||
} else if (hwloc__type_match(string, "hostbridge", 6)) {
|
||||
type = HWLOC_OBJ_BRIDGE;
|
||||
ubtype = HWLOC_OBJ_BRIDGE_HOST;
|
||||
} else if (hwloc__type_match(string, "pcibridge", 5)) {
|
||||
type = HWLOC_OBJ_BRIDGE;
|
||||
ubtype = HWLOC_OBJ_BRIDGE_PCI;
|
||||
/* if downstream_type can ever be non-PCI, we'll have to make strings more precise,
|
||||
* or relax the hwloc_type_sscanf test */
|
||||
|
||||
} else if (hwloc__type_match(string, "pcidev", 3)) {
|
||||
type = HWLOC_OBJ_PCI_DEVICE;
|
||||
|
||||
/* types with depthattr */
|
||||
} else if ((string[0] == 'l' || string[0] == 'L') && string[1] >= '0' && string[1] <= '9') {
|
||||
char *suffix;
|
||||
depthattr = strtol(string+1, &end, 10);
|
||||
if (*end == 'i' || *end == 'I') {
|
||||
if (depthattr >= 1 && depthattr <= 3) {
|
||||
type = HWLOC_OBJ_L1ICACHE + depthattr-1;
|
||||
cachetypeattr = HWLOC_OBJ_CACHE_INSTRUCTION;
|
||||
suffix = end+1;
|
||||
} else
|
||||
return -1;
|
||||
} else {
|
||||
if (depthattr >= 1 && depthattr <= 5) {
|
||||
type = HWLOC_OBJ_L1CACHE + depthattr-1;
|
||||
if (*end == 'd' || *end == 'D') {
|
||||
cachetypeattr = HWLOC_OBJ_CACHE_DATA;
|
||||
suffix = end+1;
|
||||
} else if (*end == 'u' || *end == 'U') {
|
||||
cachetypeattr = HWLOC_OBJ_CACHE_UNIFIED;
|
||||
suffix = end+1;
|
||||
} else {
|
||||
cachetypeattr = HWLOC_OBJ_CACHE_UNIFIED;
|
||||
suffix = end;
|
||||
}
|
||||
} else
|
||||
return -1;
|
||||
}
|
||||
/* check whether the optional suffix matches "cache" */
|
||||
if (!hwloc__type_match(suffix, "cache", 0))
|
||||
return -1;
|
||||
|
||||
} else if ((end = (char *) hwloc__type_match(string, "group", 2)) != NULL) {
|
||||
type = HWLOC_OBJ_GROUP;
|
||||
if (*end >= '0' && *end <= '9') {
|
||||
depthattr = strtol(end, &end, 10);
|
||||
}
|
||||
|
||||
} else
|
||||
return -1;
|
||||
|
||||
*typep = type;
|
||||
if (attrp) {
|
||||
if (hwloc__obj_type_is_cache(type) && attrsize >= sizeof(attrp->cache)) {
|
||||
attrp->cache.depth = depthattr;
|
||||
attrp->cache.type = cachetypeattr;
|
||||
} else if (type == HWLOC_OBJ_GROUP && attrsize >= sizeof(attrp->group)) {
|
||||
attrp->group.depth = depthattr;
|
||||
} else if (type == HWLOC_OBJ_BRIDGE && attrsize >= sizeof(attrp->bridge)) {
|
||||
attrp->bridge.upstream_type = ubtype;
|
||||
attrp->bridge.downstream_type = HWLOC_OBJ_BRIDGE_PCI;
|
||||
/* if downstream_type can ever be non-PCI, we'll have to make strings more precise,
|
||||
* or relax the hwloc_type_sscanf test */
|
||||
} else if (type == HWLOC_OBJ_OS_DEVICE && attrsize >= sizeof(attrp->osdev)) {
|
||||
attrp->osdev.type = ostype;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_type_sscanf_as_depth(const char *string, hwloc_obj_type_t *typep,
|
||||
hwloc_topology_t topology, int *depthp)
|
||||
{
|
||||
union hwloc_obj_attr_u attr;
|
||||
hwloc_obj_type_t type;
|
||||
int depth;
|
||||
int err;
|
||||
|
||||
err = hwloc_type_sscanf(string, &type, &attr, sizeof(attr));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
depth = hwloc_get_type_depth(topology, type);
|
||||
if (type == HWLOC_OBJ_GROUP
|
||||
&& depth == HWLOC_TYPE_DEPTH_MULTIPLE
|
||||
&& attr.group.depth != (unsigned)-1) {
|
||||
unsigned l;
|
||||
depth = HWLOC_TYPE_DEPTH_UNKNOWN;
|
||||
for(l=0; l<topology->nb_levels; l++) {
|
||||
if (topology->levels[l][0]->type == HWLOC_OBJ_GROUP
|
||||
&& topology->levels[l][0]->attr->group.depth == attr.group.depth) {
|
||||
depth = (int)l;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typep)
|
||||
*typep = type;
|
||||
*depthp = depth;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char* hwloc_obj_cache_type_letter(hwloc_obj_cache_type_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case HWLOC_OBJ_CACHE_UNIFIED: return "";
|
||||
case HWLOC_OBJ_CACHE_DATA: return "d";
|
||||
case HWLOC_OBJ_CACHE_INSTRUCTION: return "i";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_obj_type_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t obj, int verbose)
|
||||
{
|
||||
hwloc_obj_type_t type = obj->type;
|
||||
switch (type) {
|
||||
case HWLOC_OBJ_MISC:
|
||||
case HWLOC_OBJ_MACHINE:
|
||||
case HWLOC_OBJ_NUMANODE:
|
||||
case HWLOC_OBJ_MEMCACHE:
|
||||
case HWLOC_OBJ_PACKAGE:
|
||||
case HWLOC_OBJ_DIE:
|
||||
case HWLOC_OBJ_CORE:
|
||||
case HWLOC_OBJ_PU:
|
||||
return hwloc_snprintf(string, size, "%s", hwloc_obj_type_string(type));
|
||||
case HWLOC_OBJ_L1CACHE:
|
||||
case HWLOC_OBJ_L2CACHE:
|
||||
case HWLOC_OBJ_L3CACHE:
|
||||
case HWLOC_OBJ_L4CACHE:
|
||||
case HWLOC_OBJ_L5CACHE:
|
||||
case HWLOC_OBJ_L1ICACHE:
|
||||
case HWLOC_OBJ_L2ICACHE:
|
||||
case HWLOC_OBJ_L3ICACHE:
|
||||
return hwloc_snprintf(string, size, "L%u%s%s", obj->attr->cache.depth,
|
||||
hwloc_obj_cache_type_letter(obj->attr->cache.type),
|
||||
verbose ? "Cache" : "");
|
||||
case HWLOC_OBJ_GROUP:
|
||||
if (obj->attr->group.depth != (unsigned) -1)
|
||||
return hwloc_snprintf(string, size, "%s%u", hwloc_obj_type_string(type), obj->attr->group.depth);
|
||||
else
|
||||
return hwloc_snprintf(string, size, "%s", hwloc_obj_type_string(type));
|
||||
case HWLOC_OBJ_BRIDGE:
|
||||
/* if downstream_type can ever be non-PCI, we'll have to make strings more precise,
|
||||
* or relax the hwloc_type_sscanf test */
|
||||
assert(obj->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI);
|
||||
return hwloc_snprintf(string, size, obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI ? "PCIBridge" : "HostBridge");
|
||||
case HWLOC_OBJ_PCI_DEVICE:
|
||||
return hwloc_snprintf(string, size, "PCI");
|
||||
case HWLOC_OBJ_OS_DEVICE:
|
||||
switch (obj->attr->osdev.type) {
|
||||
case HWLOC_OBJ_OSDEV_BLOCK: return hwloc_snprintf(string, size, "Block");
|
||||
case HWLOC_OBJ_OSDEV_NETWORK: return hwloc_snprintf(string, size, verbose ? "Network" : "Net");
|
||||
case HWLOC_OBJ_OSDEV_OPENFABRICS: return hwloc_snprintf(string, size, "OpenFabrics");
|
||||
case HWLOC_OBJ_OSDEV_DMA: return hwloc_snprintf(string, size, "DMA");
|
||||
case HWLOC_OBJ_OSDEV_GPU: return hwloc_snprintf(string, size, "GPU");
|
||||
case HWLOC_OBJ_OSDEV_COPROC: return hwloc_snprintf(string, size, verbose ? "Co-Processor" : "CoProc");
|
||||
default:
|
||||
if (size > 0)
|
||||
*string = '\0';
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (size > 0)
|
||||
*string = '\0';
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t obj, const char * separator, int verbose)
|
||||
{
|
||||
const char *prefix = "";
|
||||
char *tmp = string;
|
||||
ssize_t tmplen = size;
|
||||
int ret = 0;
|
||||
int res;
|
||||
|
||||
/* make sure we output at least an empty string */
|
||||
if (size)
|
||||
*string = '\0';
|
||||
|
||||
/* print memory attributes */
|
||||
res = 0;
|
||||
if (verbose) {
|
||||
if (obj->type == HWLOC_OBJ_NUMANODE && obj->attr->numanode.local_memory)
|
||||
res = hwloc_snprintf(tmp, tmplen, "%slocal=%lu%s%stotal=%lu%s",
|
||||
prefix,
|
||||
(unsigned long) hwloc_memory_size_printf_value(obj->attr->numanode.local_memory, verbose),
|
||||
hwloc_memory_size_printf_unit(obj->attr->numanode.local_memory, verbose),
|
||||
separator,
|
||||
(unsigned long) hwloc_memory_size_printf_value(obj->total_memory, verbose),
|
||||
hwloc_memory_size_printf_unit(obj->total_memory, verbose));
|
||||
else if (obj->total_memory)
|
||||
res = hwloc_snprintf(tmp, tmplen, "%stotal=%lu%s",
|
||||
prefix,
|
||||
(unsigned long) hwloc_memory_size_printf_value(obj->total_memory, verbose),
|
||||
hwloc_memory_size_printf_unit(obj->total_memory, verbose));
|
||||
} else {
|
||||
if (obj->type == HWLOC_OBJ_NUMANODE && obj->attr->numanode.local_memory)
|
||||
res = hwloc_snprintf(tmp, tmplen, "%s%lu%s",
|
||||
prefix,
|
||||
(unsigned long) hwloc_memory_size_printf_value(obj->attr->numanode.local_memory, verbose),
|
||||
hwloc_memory_size_printf_unit(obj->attr->numanode.local_memory, verbose));
|
||||
}
|
||||
if (res < 0)
|
||||
return -1;
|
||||
ret += res;
|
||||
if (ret > 0)
|
||||
prefix = separator;
|
||||
if (res >= tmplen)
|
||||
res = tmplen>0 ? (int)tmplen - 1 : 0;
|
||||
tmp += res;
|
||||
tmplen -= res;
|
||||
|
||||
/* printf type-specific attributes */
|
||||
res = 0;
|
||||
switch (obj->type) {
|
||||
case HWLOC_OBJ_L1CACHE:
|
||||
case HWLOC_OBJ_L2CACHE:
|
||||
case HWLOC_OBJ_L3CACHE:
|
||||
case HWLOC_OBJ_L4CACHE:
|
||||
case HWLOC_OBJ_L5CACHE:
|
||||
case HWLOC_OBJ_L1ICACHE:
|
||||
case HWLOC_OBJ_L2ICACHE:
|
||||
case HWLOC_OBJ_L3ICACHE:
|
||||
case HWLOC_OBJ_MEMCACHE:
|
||||
if (verbose) {
|
||||
char assoc[32];
|
||||
if (obj->attr->cache.associativity == -1)
|
||||
snprintf(assoc, sizeof(assoc), "%sfully-associative", separator);
|
||||
else if (obj->attr->cache.associativity == 0)
|
||||
*assoc = '\0';
|
||||
else
|
||||
snprintf(assoc, sizeof(assoc), "%sways=%d", separator, obj->attr->cache.associativity);
|
||||
res = hwloc_snprintf(tmp, tmplen, "%ssize=%lu%s%slinesize=%u%s",
|
||||
prefix,
|
||||
(unsigned long) hwloc_memory_size_printf_value(obj->attr->cache.size, verbose),
|
||||
hwloc_memory_size_printf_unit(obj->attr->cache.size, verbose),
|
||||
separator, obj->attr->cache.linesize,
|
||||
assoc);
|
||||
} else
|
||||
res = hwloc_snprintf(tmp, tmplen, "%s%lu%s",
|
||||
prefix,
|
||||
(unsigned long) hwloc_memory_size_printf_value(obj->attr->cache.size, verbose),
|
||||
hwloc_memory_size_printf_unit(obj->attr->cache.size, verbose));
|
||||
break;
|
||||
case HWLOC_OBJ_BRIDGE:
|
||||
if (verbose) {
|
||||
char up[128], down[64];
|
||||
/* upstream is PCI or HOST */
|
||||
if (obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI) {
|
||||
char linkspeed[64]= "";
|
||||
if (obj->attr->pcidev.linkspeed)
|
||||
snprintf(linkspeed, sizeof(linkspeed), "%slink=%.2fGB/s", separator, obj->attr->pcidev.linkspeed);
|
||||
snprintf(up, sizeof(up), "busid=%04x:%02x:%02x.%01x%sid=%04x:%04x%sclass=%04x(%s)%s",
|
||||
obj->attr->pcidev.domain, obj->attr->pcidev.bus, obj->attr->pcidev.dev, obj->attr->pcidev.func, separator,
|
||||
obj->attr->pcidev.vendor_id, obj->attr->pcidev.device_id, separator,
|
||||
obj->attr->pcidev.class_id, hwloc_pci_class_string(obj->attr->pcidev.class_id), linkspeed);
|
||||
} else
|
||||
*up = '\0';
|
||||
/* downstream is_PCI */
|
||||
if (obj->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI) {
|
||||
snprintf(down, sizeof(down), "buses=%04x:[%02x-%02x]",
|
||||
obj->attr->bridge.downstream.pci.domain, obj->attr->bridge.downstream.pci.secondary_bus, obj->attr->bridge.downstream.pci.subordinate_bus);
|
||||
} else
|
||||
assert(0);
|
||||
if (*up)
|
||||
res = hwloc_snprintf(string, size, "%s%s%s", up, separator, down);
|
||||
else
|
||||
res = hwloc_snprintf(string, size, "%s", down);
|
||||
}
|
||||
break;
|
||||
case HWLOC_OBJ_PCI_DEVICE:
|
||||
if (verbose) {
|
||||
char linkspeed[64]= "";
|
||||
if (obj->attr->pcidev.linkspeed)
|
||||
snprintf(linkspeed, sizeof(linkspeed), "%slink=%.2fGB/s", separator, obj->attr->pcidev.linkspeed);
|
||||
res = hwloc_snprintf(string, size, "busid=%04x:%02x:%02x.%01x%sid=%04x:%04x%sclass=%04x(%s)%s",
|
||||
obj->attr->pcidev.domain, obj->attr->pcidev.bus, obj->attr->pcidev.dev, obj->attr->pcidev.func, separator,
|
||||
obj->attr->pcidev.vendor_id, obj->attr->pcidev.device_id, separator,
|
||||
obj->attr->pcidev.class_id, hwloc_pci_class_string(obj->attr->pcidev.class_id), linkspeed);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (res < 0)
|
||||
return -1;
|
||||
ret += res;
|
||||
if (ret > 0)
|
||||
prefix = separator;
|
||||
if (res >= tmplen)
|
||||
res = tmplen>0 ? (int)tmplen - 1 : 0;
|
||||
tmp += res;
|
||||
tmplen -= res;
|
||||
|
||||
/* printf infos */
|
||||
if (verbose) {
|
||||
unsigned i;
|
||||
for(i=0; i<obj->infos_count; i++) {
|
||||
struct hwloc_info_s *info = &obj->infos[i];
|
||||
const char *quote;
|
||||
if (strchr(info->value, ' '))
|
||||
quote = "\"";
|
||||
else
|
||||
quote = "";
|
||||
res = hwloc_snprintf(tmp, tmplen, "%s%s=%s%s%s",
|
||||
prefix,
|
||||
info->name,
|
||||
quote, info->value, quote);
|
||||
if (res < 0)
|
||||
return -1;
|
||||
ret += res;
|
||||
if (res >= tmplen)
|
||||
res = tmplen>0 ? (int)tmplen - 1 : 0;
|
||||
tmp += res;
|
||||
tmplen -= res;
|
||||
if (ret > 0)
|
||||
prefix = separator;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
hwloc_obj_t
|
||||
hwloc_get_obj_with_same_locality(hwloc_topology_t topology, hwloc_obj_t src,
|
||||
hwloc_obj_type_t type, const char *subtype, const char *nameprefix,
|
||||
unsigned long flags)
|
||||
{
|
||||
if (flags) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (hwloc_obj_type_is_normal(src->type) || hwloc_obj_type_is_memory(src->type)) {
|
||||
/* normal/memory type, look for normal/memory type with same sets */
|
||||
hwloc_obj_t obj;
|
||||
|
||||
if (!hwloc_obj_type_is_normal(type) && !hwloc_obj_type_is_memory(type)) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
while ((obj = hwloc_get_next_obj_by_type(topology, type, obj)) != NULL) {
|
||||
if (!hwloc_bitmap_isequal(src->cpuset, obj->cpuset)
|
||||
|| !hwloc_bitmap_isequal(src->nodeset, obj->nodeset))
|
||||
continue;
|
||||
if (subtype && (!obj->subtype || strcasecmp(subtype, obj->subtype)))
|
||||
continue;
|
||||
if (nameprefix && (!obj->name || hwloc_strncasecmp(nameprefix, obj->name, strlen(nameprefix))))
|
||||
continue;
|
||||
return obj;
|
||||
}
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
|
||||
} else if (hwloc_obj_type_is_io(src->type)) {
|
||||
/* I/O device, look for PCI/OS in same PCI */
|
||||
hwloc_obj_t pci;
|
||||
|
||||
if ((src->type != HWLOC_OBJ_OS_DEVICE && src->type != HWLOC_OBJ_PCI_DEVICE)
|
||||
|| (type != HWLOC_OBJ_OS_DEVICE && type != HWLOC_OBJ_PCI_DEVICE)) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* walk up to find the container */
|
||||
pci = src;
|
||||
while (pci->type == HWLOC_OBJ_OS_DEVICE)
|
||||
pci = pci->parent;
|
||||
|
||||
if (type == HWLOC_OBJ_PCI_DEVICE) {
|
||||
if (pci->type != HWLOC_OBJ_PCI_DEVICE) {
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
if (subtype && (!pci->subtype || strcasecmp(subtype, pci->subtype))) {
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
if (nameprefix && (!pci->name || hwloc_strncasecmp(nameprefix, pci->name, strlen(nameprefix)))) {
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
return pci;
|
||||
|
||||
} else {
|
||||
/* find a matching osdev child */
|
||||
assert(type == HWLOC_OBJ_OS_DEVICE);
|
||||
/* FIXME: won't work if we ever store osdevs in osdevs */
|
||||
hwloc_obj_t child;
|
||||
for(child = pci->io_first_child; child; child = child->next_sibling) {
|
||||
if (child->type != HWLOC_OBJ_OS_DEVICE)
|
||||
/* FIXME: should never occur currently */
|
||||
continue;
|
||||
if (subtype && (!child->subtype || strcasecmp(subtype, child->subtype)))
|
||||
continue;
|
||||
if (nameprefix && (!child->name || hwloc_strncasecmp(nameprefix, child->name, strlen(nameprefix))))
|
||||
continue;
|
||||
return child;
|
||||
}
|
||||
}
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
|
||||
} else {
|
||||
/* nothing for Misc */
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
24
src/3rdparty/libethash/CMakeLists.txt
vendored
24
src/3rdparty/libethash/CMakeLists.txt
vendored
@@ -1,24 +0,0 @@
|
||||
cmake_minimum_required (VERSION 2.8.12)
|
||||
project (ethash C)
|
||||
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os")
|
||||
|
||||
set(HEADERS
|
||||
data_sizes.h
|
||||
endian.h
|
||||
ethash.h
|
||||
ethash_internal.h
|
||||
fnv.h
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
ethash_internal.c
|
||||
keccakf800.c
|
||||
)
|
||||
|
||||
include_directories(../..)
|
||||
|
||||
add_library(ethash STATIC
|
||||
${HEADERS}
|
||||
${SOURCES}
|
||||
)
|
||||
811
src/3rdparty/libethash/data_sizes.h
vendored
811
src/3rdparty/libethash/data_sizes.h
vendored
@@ -1,811 +0,0 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software FoundationUUU,either version 3 of the LicenseUUU,or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be usefulU,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If notUUU,see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file data_sizes.h
|
||||
* @author Matthew Wampler-Doty <negacthulhu@gmail.com>
|
||||
* @date 2015
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// 2048 Epochs (~20 years) worth of tabulated DAG sizes
|
||||
|
||||
// Generated with the following Mathematica Code:
|
||||
|
||||
// GetCacheSizes[n_] := Module[{
|
||||
// CacheSizeBytesInit = 2^24,
|
||||
// CacheGrowth = 2^17,
|
||||
// HashBytes = 64,
|
||||
// j = 0},
|
||||
// Reap[
|
||||
// While[j < n,
|
||||
// Module[{i =
|
||||
// Floor[(CacheSizeBytesInit + CacheGrowth * j) / HashBytes]},
|
||||
// While[! PrimeQ[i], i--];
|
||||
// Sow[i*HashBytes]; j++]]]][[2]][[1]]
|
||||
|
||||
|
||||
static const uint64_t dag_sizes[2048] = {
|
||||
1073739904U, 1082130304U, 1090514816U, 1098906752U, 1107293056U,
|
||||
1115684224U, 1124070016U, 1132461952U, 1140849536U, 1149232768U,
|
||||
1157627776U, 1166013824U, 1174404736U, 1182786944U, 1191180416U,
|
||||
1199568512U, 1207958912U, 1216345216U, 1224732032U, 1233124736U,
|
||||
1241513344U, 1249902464U, 1258290304U, 1266673792U, 1275067264U,
|
||||
1283453312U, 1291844992U, 1300234112U, 1308619904U, 1317010048U,
|
||||
1325397376U, 1333787776U, 1342176128U, 1350561664U, 1358954368U,
|
||||
1367339392U, 1375731584U, 1384118144U, 1392507008U, 1400897408U,
|
||||
1409284736U, 1417673344U, 1426062464U, 1434451072U, 1442839168U,
|
||||
1451229056U, 1459615616U, 1468006016U, 1476394112U, 1484782976U,
|
||||
1493171584U, 1501559168U, 1509948032U, 1518337664U, 1526726528U,
|
||||
1535114624U, 1543503488U, 1551892096U, 1560278656U, 1568669056U,
|
||||
1577056384U, 1585446272U, 1593831296U, 1602219392U, 1610610304U,
|
||||
1619000192U, 1627386752U, 1635773824U, 1644164224U, 1652555648U,
|
||||
1660943488U, 1669332608U, 1677721216U, 1686109312U, 1694497664U,
|
||||
1702886272U, 1711274624U, 1719661184U, 1728047744U, 1736434816U,
|
||||
1744829056U, 1753218944U, 1761606272U, 1769995904U, 1778382464U,
|
||||
1786772864U, 1795157888U, 1803550592U, 1811937664U, 1820327552U,
|
||||
1828711552U, 1837102976U, 1845488768U, 1853879936U, 1862269312U,
|
||||
1870656896U, 1879048064U, 1887431552U, 1895825024U, 1904212096U,
|
||||
1912601216U, 1920988544U, 1929379456U, 1937765504U, 1946156672U,
|
||||
1954543232U, 1962932096U, 1971321728U, 1979707264U, 1988093056U,
|
||||
1996487552U, 2004874624U, 2013262208U, 2021653888U, 2030039936U,
|
||||
2038430848U, 2046819968U, 2055208576U, 2063596672U, 2071981952U,
|
||||
2080373632U, 2088762752U, 2097149056U, 2105539712U, 2113928576U,
|
||||
2122315136U, 2130700672U, 2139092608U, 2147483264U, 2155872128U,
|
||||
2164257664U, 2172642176U, 2181035392U, 2189426048U, 2197814912U,
|
||||
2206203008U, 2214587264U, 2222979712U, 2231367808U, 2239758208U,
|
||||
2248145024U, 2256527744U, 2264922752U, 2273312128U, 2281701248U,
|
||||
2290086272U, 2298476672U, 2306867072U, 2315251072U, 2323639168U,
|
||||
2332032128U, 2340420224U, 2348808064U, 2357196416U, 2365580416U,
|
||||
2373966976U, 2382363008U, 2390748544U, 2399139968U, 2407530368U,
|
||||
2415918976U, 2424307328U, 2432695424U, 2441084288U, 2449472384U,
|
||||
2457861248U, 2466247808U, 2474637184U, 2483026816U, 2491414144U,
|
||||
2499803776U, 2508191872U, 2516582272U, 2524970368U, 2533359232U,
|
||||
2541743488U, 2550134144U, 2558525056U, 2566913408U, 2575301504U,
|
||||
2583686528U, 2592073856U, 2600467328U, 2608856192U, 2617240448U,
|
||||
2625631616U, 2634022016U, 2642407552U, 2650796416U, 2659188352U,
|
||||
2667574912U, 2675965312U, 2684352896U, 2692738688U, 2701130624U,
|
||||
2709518464U, 2717907328U, 2726293376U, 2734685056U, 2743073152U,
|
||||
2751462016U, 2759851648U, 2768232832U, 2776625536U, 2785017728U,
|
||||
2793401984U, 2801794432U, 2810182016U, 2818571648U, 2826959488U,
|
||||
2835349376U, 2843734144U, 2852121472U, 2860514432U, 2868900992U,
|
||||
2877286784U, 2885676928U, 2894069632U, 2902451584U, 2910843008U,
|
||||
2919234688U, 2927622784U, 2936011648U, 2944400768U, 2952789376U,
|
||||
2961177728U, 2969565568U, 2977951616U, 2986338944U, 2994731392U,
|
||||
3003120256U, 3011508352U, 3019895936U, 3028287104U, 3036675968U,
|
||||
3045063808U, 3053452928U, 3061837696U, 3070228352U, 3078615424U,
|
||||
3087003776U, 3095394944U, 3103782272U, 3112173184U, 3120562048U,
|
||||
3128944768U, 3137339264U, 3145725056U, 3154109312U, 3162505088U,
|
||||
3170893184U, 3179280256U, 3187669376U, 3196056704U, 3204445568U,
|
||||
3212836736U, 3221224064U, 3229612928U, 3238002304U, 3246391168U,
|
||||
3254778496U, 3263165824U, 3271556224U, 3279944576U, 3288332416U,
|
||||
3296719232U, 3305110912U, 3313500032U, 3321887104U, 3330273152U,
|
||||
3338658944U, 3347053184U, 3355440512U, 3363827072U, 3372220288U,
|
||||
3380608384U, 3388997504U, 3397384576U, 3405774208U, 3414163072U,
|
||||
3422551936U, 3430937984U, 3439328384U, 3447714176U, 3456104576U,
|
||||
3464493952U, 3472883584U, 3481268864U, 3489655168U, 3498048896U,
|
||||
3506434432U, 3514826368U, 3523213952U, 3531603584U, 3539987072U,
|
||||
3548380288U, 3556763264U, 3565157248U, 3573545344U, 3581934464U,
|
||||
3590324096U, 3598712704U, 3607098752U, 3615488384U, 3623877248U,
|
||||
3632265856U, 3640646528U, 3649043584U, 3657430144U, 3665821568U,
|
||||
3674207872U, 3682597504U, 3690984832U, 3699367808U, 3707764352U,
|
||||
3716152448U, 3724541056U, 3732925568U, 3741318016U, 3749706368U,
|
||||
3758091136U, 3766481536U, 3774872704U, 3783260032U, 3791650432U,
|
||||
3800036224U, 3808427648U, 3816815488U, 3825204608U, 3833592704U,
|
||||
3841981568U, 3850370432U, 3858755968U, 3867147904U, 3875536256U,
|
||||
3883920512U, 3892313728U, 3900702592U, 3909087872U, 3917478784U,
|
||||
3925868416U, 3934256512U, 3942645376U, 3951032192U, 3959422336U,
|
||||
3967809152U, 3976200064U, 3984588416U, 3992974976U, 4001363584U,
|
||||
4009751168U, 4018141312U, 4026530432U, 4034911616U, 4043308928U,
|
||||
4051695488U, 4060084352U, 4068472448U, 4076862848U, 4085249408U,
|
||||
4093640576U, 4102028416U, 4110413696U, 4118805632U, 4127194496U,
|
||||
4135583104U, 4143971968U, 4152360832U, 4160746112U, 4169135744U,
|
||||
4177525888U, 4185912704U, 4194303616U, 4202691968U, 4211076736U,
|
||||
4219463552U, 4227855488U, 4236246656U, 4244633728U, 4253022848U,
|
||||
4261412224U, 4269799808U, 4278184832U, 4286578048U, 4294962304U,
|
||||
4303349632U, 4311743104U, 4320130432U, 4328521088U, 4336909184U,
|
||||
4345295488U, 4353687424U, 4362073472U, 4370458496U, 4378852736U,
|
||||
4387238528U, 4395630208U, 4404019072U, 4412407424U, 4420790656U,
|
||||
4429182848U, 4437571456U, 4445962112U, 4454344064U, 4462738048U,
|
||||
4471119232U, 4479516544U, 4487904128U, 4496289664U, 4504682368U,
|
||||
4513068416U, 4521459584U, 4529846144U, 4538232704U, 4546619776U,
|
||||
4555010176U, 4563402112U, 4571790208U, 4580174464U, 4588567936U,
|
||||
4596957056U, 4605344896U, 4613734016U, 4622119808U, 4630511488U,
|
||||
4638898816U, 4647287936U, 4655675264U, 4664065664U, 4672451968U,
|
||||
4680842624U, 4689231488U, 4697620352U, 4706007424U, 4714397056U,
|
||||
4722786176U, 4731173248U, 4739562368U, 4747951744U, 4756340608U,
|
||||
4764727936U, 4773114496U, 4781504384U, 4789894784U, 4798283648U,
|
||||
4806667648U, 4815059584U, 4823449472U, 4831835776U, 4840226176U,
|
||||
4848612224U, 4857003392U, 4865391488U, 4873780096U, 4882169728U,
|
||||
4890557312U, 4898946944U, 4907333248U, 4915722368U, 4924110976U,
|
||||
4932499328U, 4940889728U, 4949276032U, 4957666432U, 4966054784U,
|
||||
4974438016U, 4982831488U, 4991221376U, 4999607168U, 5007998848U,
|
||||
5016386432U, 5024763776U, 5033164672U, 5041544576U, 5049941888U,
|
||||
5058329728U, 5066717056U, 5075107456U, 5083494272U, 5091883904U,
|
||||
5100273536U, 5108662144U, 5117048192U, 5125436032U, 5133827456U,
|
||||
5142215296U, 5150605184U, 5158993024U, 5167382144U, 5175769472U,
|
||||
5184157568U, 5192543872U, 5200936064U, 5209324928U, 5217711232U,
|
||||
5226102656U, 5234490496U, 5242877312U, 5251263872U, 5259654016U,
|
||||
5268040832U, 5276434304U, 5284819328U, 5293209728U, 5301598592U,
|
||||
5309986688U, 5318374784U, 5326764416U, 5335151488U, 5343542144U,
|
||||
5351929472U, 5360319872U, 5368706944U, 5377096576U, 5385484928U,
|
||||
5393871232U, 5402263424U, 5410650496U, 5419040384U, 5427426944U,
|
||||
5435816576U, 5444205952U, 5452594816U, 5460981376U, 5469367936U,
|
||||
5477760896U, 5486148736U, 5494536832U, 5502925952U, 5511315328U,
|
||||
5519703424U, 5528089984U, 5536481152U, 5544869504U, 5553256064U,
|
||||
5561645696U, 5570032768U, 5578423936U, 5586811264U, 5595193216U,
|
||||
5603585408U, 5611972736U, 5620366208U, 5628750464U, 5637143936U,
|
||||
5645528192U, 5653921408U, 5662310272U, 5670694784U, 5679082624U,
|
||||
5687474048U, 5695864448U, 5704251008U, 5712641408U, 5721030272U,
|
||||
5729416832U, 5737806208U, 5746194304U, 5754583936U, 5762969984U,
|
||||
5771358592U, 5779748224U, 5788137856U, 5796527488U, 5804911232U,
|
||||
5813300608U, 5821692544U, 5830082176U, 5838468992U, 5846855552U,
|
||||
5855247488U, 5863636096U, 5872024448U, 5880411008U, 5888799872U,
|
||||
5897186432U, 5905576832U, 5913966976U, 5922352768U, 5930744704U,
|
||||
5939132288U, 5947522432U, 5955911296U, 5964299392U, 5972688256U,
|
||||
5981074304U, 5989465472U, 5997851008U, 6006241408U, 6014627968U,
|
||||
6023015552U, 6031408256U, 6039796096U, 6048185216U, 6056574848U,
|
||||
6064963456U, 6073351808U, 6081736064U, 6090128768U, 6098517632U,
|
||||
6106906496U, 6115289216U, 6123680896U, 6132070016U, 6140459648U,
|
||||
6148849024U, 6157237376U, 6165624704U, 6174009728U, 6182403712U,
|
||||
6190792064U, 6199176064U, 6207569792U, 6215952256U, 6224345216U,
|
||||
6232732544U, 6241124224U, 6249510272U, 6257899136U, 6266287744U,
|
||||
6274676864U, 6283065728U, 6291454336U, 6299843456U, 6308232064U,
|
||||
6316620928U, 6325006208U, 6333395584U, 6341784704U, 6350174848U,
|
||||
6358562176U, 6366951296U, 6375337856U, 6383729536U, 6392119168U,
|
||||
6400504192U, 6408895616U, 6417283456U, 6425673344U, 6434059136U,
|
||||
6442444672U, 6450837376U, 6459223424U, 6467613056U, 6476004224U,
|
||||
6484393088U, 6492781952U, 6501170048U, 6509555072U, 6517947008U,
|
||||
6526336384U, 6534725504U, 6543112832U, 6551500672U, 6559888768U,
|
||||
6568278656U, 6576662912U, 6585055616U, 6593443456U, 6601834112U,
|
||||
6610219648U, 6618610304U, 6626999168U, 6635385472U, 6643777408U,
|
||||
6652164224U, 6660552832U, 6668941952U, 6677330048U, 6685719424U,
|
||||
6694107776U, 6702493568U, 6710882176U, 6719274112U, 6727662976U,
|
||||
6736052096U, 6744437632U, 6752825984U, 6761213824U, 6769604224U,
|
||||
6777993856U, 6786383488U, 6794770816U, 6803158144U, 6811549312U,
|
||||
6819937664U, 6828326528U, 6836706176U, 6845101696U, 6853491328U,
|
||||
6861880448U, 6870269312U, 6878655104U, 6887046272U, 6895433344U,
|
||||
6903822208U, 6912212864U, 6920596864U, 6928988288U, 6937377152U,
|
||||
6945764992U, 6954149248U, 6962544256U, 6970928768U, 6979317376U,
|
||||
6987709312U, 6996093824U, 7004487296U, 7012875392U, 7021258624U,
|
||||
7029652352U, 7038038912U, 7046427776U, 7054818944U, 7063207808U,
|
||||
7071595136U, 7079980928U, 7088372608U, 7096759424U, 7105149824U,
|
||||
7113536896U, 7121928064U, 7130315392U, 7138699648U, 7147092352U,
|
||||
7155479168U, 7163865728U, 7172249984U, 7180648064U, 7189036672U,
|
||||
7197424768U, 7205810816U, 7214196608U, 7222589824U, 7230975104U,
|
||||
7239367552U, 7247755904U, 7256145536U, 7264533376U, 7272921472U,
|
||||
7281308032U, 7289694848U, 7298088832U, 7306471808U, 7314864512U,
|
||||
7323253888U, 7331643008U, 7340029568U, 7348419712U, 7356808832U,
|
||||
7365196672U, 7373585792U, 7381973888U, 7390362752U, 7398750592U,
|
||||
7407138944U, 7415528576U, 7423915648U, 7432302208U, 7440690304U,
|
||||
7449080192U, 7457472128U, 7465860992U, 7474249088U, 7482635648U,
|
||||
7491023744U, 7499412608U, 7507803008U, 7516192384U, 7524579968U,
|
||||
7532967296U, 7541358464U, 7549745792U, 7558134656U, 7566524032U,
|
||||
7574912896U, 7583300992U, 7591690112U, 7600075136U, 7608466816U,
|
||||
7616854912U, 7625244544U, 7633629824U, 7642020992U, 7650410368U,
|
||||
7658794112U, 7667187328U, 7675574912U, 7683961984U, 7692349568U,
|
||||
7700739712U, 7709130368U, 7717519232U, 7725905536U, 7734295424U,
|
||||
7742683264U, 7751069056U, 7759457408U, 7767849088U, 7776238208U,
|
||||
7784626816U, 7793014912U, 7801405312U, 7809792128U, 7818179968U,
|
||||
7826571136U, 7834957184U, 7843347328U, 7851732352U, 7860124544U,
|
||||
7868512384U, 7876902016U, 7885287808U, 7893679744U, 7902067072U,
|
||||
7910455936U, 7918844288U, 7927230848U, 7935622784U, 7944009344U,
|
||||
7952400256U, 7960786048U, 7969176704U, 7977565312U, 7985953408U,
|
||||
7994339968U, 8002730368U, 8011119488U, 8019508096U, 8027896192U,
|
||||
8036285056U, 8044674688U, 8053062272U, 8061448832U, 8069838464U,
|
||||
8078227328U, 8086616704U, 8095006592U, 8103393664U, 8111783552U,
|
||||
8120171392U, 8128560256U, 8136949376U, 8145336704U, 8153726848U,
|
||||
8162114944U, 8170503296U, 8178891904U, 8187280768U, 8195669632U,
|
||||
8204058496U, 8212444544U, 8220834176U, 8229222272U, 8237612672U,
|
||||
8246000768U, 8254389376U, 8262775168U, 8271167104U, 8279553664U,
|
||||
8287944064U, 8296333184U, 8304715136U, 8313108352U, 8321497984U,
|
||||
8329885568U, 8338274432U, 8346663296U, 8355052928U, 8363441536U,
|
||||
8371828352U, 8380217984U, 8388606592U, 8396996224U, 8405384576U,
|
||||
8413772672U, 8422161536U, 8430549376U, 8438939008U, 8447326592U,
|
||||
8455715456U, 8464104832U, 8472492928U, 8480882048U, 8489270656U,
|
||||
8497659776U, 8506045312U, 8514434944U, 8522823808U, 8531208832U,
|
||||
8539602304U, 8547990656U, 8556378752U, 8564768384U, 8573154176U,
|
||||
8581542784U, 8589933952U, 8598322816U, 8606705024U, 8615099264U,
|
||||
8623487872U, 8631876992U, 8640264064U, 8648653952U, 8657040256U,
|
||||
8665430656U, 8673820544U, 8682209152U, 8690592128U, 8698977152U,
|
||||
8707374464U, 8715763328U, 8724151424U, 8732540032U, 8740928384U,
|
||||
8749315712U, 8757704576U, 8766089344U, 8774480768U, 8782871936U,
|
||||
8791260032U, 8799645824U, 8808034432U, 8816426368U, 8824812928U,
|
||||
8833199488U, 8841591424U, 8849976448U, 8858366336U, 8866757248U,
|
||||
8875147136U, 8883532928U, 8891923328U, 8900306816U, 8908700288U,
|
||||
8917088384U, 8925478784U, 8933867392U, 8942250368U, 8950644608U,
|
||||
8959032704U, 8967420544U, 8975809664U, 8984197504U, 8992584064U,
|
||||
9000976256U, 9009362048U, 9017752448U, 9026141312U, 9034530688U,
|
||||
9042917504U, 9051307904U, 9059694208U, 9068084864U, 9076471424U,
|
||||
9084861824U, 9093250688U, 9101638528U, 9110027648U, 9118416512U,
|
||||
9126803584U, 9135188096U, 9143581312U, 9151969664U, 9160356224U,
|
||||
9168747136U, 9177134464U, 9185525632U, 9193910144U, 9202302848U,
|
||||
9210690688U, 9219079552U, 9227465344U, 9235854464U, 9244244864U,
|
||||
9252633472U, 9261021824U, 9269411456U, 9277799296U, 9286188928U,
|
||||
9294574208U, 9302965888U, 9311351936U, 9319740032U, 9328131968U,
|
||||
9336516736U, 9344907392U, 9353296768U, 9361685888U, 9370074752U,
|
||||
9378463616U, 9386849408U, 9395239808U, 9403629184U, 9412016512U,
|
||||
9420405376U, 9428795008U, 9437181568U, 9445570688U, 9453960832U,
|
||||
9462346624U, 9470738048U, 9479121536U, 9487515008U, 9495903616U,
|
||||
9504289664U, 9512678528U, 9521067904U, 9529456256U, 9537843584U,
|
||||
9546233728U, 9554621312U, 9563011456U, 9571398784U, 9579788672U,
|
||||
9588178304U, 9596567168U, 9604954496U, 9613343104U, 9621732992U,
|
||||
9630121856U, 9638508416U, 9646898816U, 9655283584U, 9663675776U,
|
||||
9672061312U, 9680449664U, 9688840064U, 9697230464U, 9705617536U,
|
||||
9714003584U, 9722393984U, 9730772608U, 9739172224U, 9747561088U,
|
||||
9755945344U, 9764338816U, 9772726144U, 9781116544U, 9789503872U,
|
||||
9797892992U, 9806282624U, 9814670464U, 9823056512U, 9831439232U,
|
||||
9839833984U, 9848224384U, 9856613504U, 9865000576U, 9873391232U,
|
||||
9881772416U, 9890162816U, 9898556288U, 9906940544U, 9915333248U,
|
||||
9923721088U, 9932108672U, 9940496512U, 9948888448U, 9957276544U,
|
||||
9965666176U, 9974048384U, 9982441088U, 9990830464U, 9999219584U,
|
||||
10007602816U, 10015996544U, 10024385152U, 10032774016U, 10041163648U,
|
||||
10049548928U, 10057940096U, 10066329472U, 10074717824U, 10083105152U,
|
||||
10091495296U, 10099878784U, 10108272256U, 10116660608U, 10125049216U,
|
||||
10133437312U, 10141825664U, 10150213504U, 10158601088U, 10166991232U,
|
||||
10175378816U, 10183766144U, 10192157312U, 10200545408U, 10208935552U,
|
||||
10217322112U, 10225712768U, 10234099328U, 10242489472U, 10250876032U,
|
||||
10259264896U, 10267656064U, 10276042624U, 10284429184U, 10292820352U,
|
||||
10301209472U, 10309598848U, 10317987712U, 10326375296U, 10334763392U,
|
||||
10343153536U, 10351541632U, 10359930752U, 10368318592U, 10376707456U,
|
||||
10385096576U, 10393484672U, 10401867136U, 10410262144U, 10418647424U,
|
||||
10427039104U, 10435425664U, 10443810176U, 10452203648U, 10460589952U,
|
||||
10468982144U, 10477369472U, 10485759104U, 10494147712U, 10502533504U,
|
||||
10510923392U, 10519313536U, 10527702656U, 10536091264U, 10544478592U,
|
||||
10552867712U, 10561255808U, 10569642368U, 10578032768U, 10586423168U,
|
||||
10594805632U, 10603200128U, 10611588992U, 10619976064U, 10628361344U,
|
||||
10636754048U, 10645143424U, 10653531776U, 10661920384U, 10670307968U,
|
||||
10678696832U, 10687086464U, 10695475072U, 10703863168U, 10712246144U,
|
||||
10720639616U, 10729026688U, 10737414784U, 10745806208U, 10754190976U,
|
||||
10762581376U, 10770971264U, 10779356288U, 10787747456U, 10796135552U,
|
||||
10804525184U, 10812915584U, 10821301888U, 10829692288U, 10838078336U,
|
||||
10846469248U, 10854858368U, 10863247232U, 10871631488U, 10880023424U,
|
||||
10888412032U, 10896799616U, 10905188992U, 10913574016U, 10921964672U,
|
||||
10930352768U, 10938742912U, 10947132544U, 10955518592U, 10963909504U,
|
||||
10972298368U, 10980687488U, 10989074816U, 10997462912U, 11005851776U,
|
||||
11014241152U, 11022627712U, 11031017344U, 11039403904U, 11047793024U,
|
||||
11056184704U, 11064570752U, 11072960896U, 11081343872U, 11089737856U,
|
||||
11098128256U, 11106514816U, 11114904448U, 11123293568U, 11131680128U,
|
||||
11140065152U, 11148458368U, 11156845696U, 11165236864U, 11173624192U,
|
||||
11182013824U, 11190402688U, 11198790784U, 11207179136U, 11215568768U,
|
||||
11223957376U, 11232345728U, 11240734592U, 11249122688U, 11257511296U,
|
||||
11265899648U, 11274285952U, 11282675584U, 11291065472U, 11299452544U,
|
||||
11307842432U, 11316231296U, 11324616832U, 11333009024U, 11341395584U,
|
||||
11349782656U, 11358172288U, 11366560384U, 11374950016U, 11383339648U,
|
||||
11391721856U, 11400117376U, 11408504192U, 11416893568U, 11425283456U,
|
||||
11433671552U, 11442061184U, 11450444672U, 11458837888U, 11467226752U,
|
||||
11475611776U, 11484003968U, 11492392064U, 11500780672U, 11509169024U,
|
||||
11517550976U, 11525944448U, 11534335616U, 11542724224U, 11551111808U,
|
||||
11559500672U, 11567890304U, 11576277376U, 11584667008U, 11593056128U,
|
||||
11601443456U, 11609830016U, 11618221952U, 11626607488U, 11634995072U,
|
||||
11643387776U, 11651775104U, 11660161664U, 11668552576U, 11676940928U,
|
||||
11685330304U, 11693718656U, 11702106496U, 11710496128U, 11718882688U,
|
||||
11727273088U, 11735660416U, 11744050048U, 11752437376U, 11760824704U,
|
||||
11769216128U, 11777604736U, 11785991296U, 11794381952U, 11802770048U,
|
||||
11811157888U, 11819548544U, 11827932544U, 11836324736U, 11844713344U,
|
||||
11853100928U, 11861486464U, 11869879936U, 11878268032U, 11886656896U,
|
||||
11895044992U, 11903433088U, 11911822976U, 11920210816U, 11928600448U,
|
||||
11936987264U, 11945375872U, 11953761152U, 11962151296U, 11970543488U,
|
||||
11978928512U, 11987320448U, 11995708288U, 12004095104U, 12012486272U,
|
||||
12020875136U, 12029255552U, 12037652096U, 12046039168U, 12054429568U,
|
||||
12062813824U, 12071206528U, 12079594624U, 12087983744U, 12096371072U,
|
||||
12104759936U, 12113147264U, 12121534592U, 12129924992U, 12138314624U,
|
||||
12146703232U, 12155091584U, 12163481216U, 12171864704U, 12180255872U,
|
||||
12188643968U, 12197034112U, 12205424512U, 12213811328U, 12222199424U,
|
||||
12230590336U, 12238977664U, 12247365248U, 12255755392U, 12264143488U,
|
||||
12272531584U, 12280920448U, 12289309568U, 12297694592U, 12306086528U,
|
||||
12314475392U, 12322865024U, 12331253632U, 12339640448U, 12348029312U,
|
||||
12356418944U, 12364805248U, 12373196672U, 12381580928U, 12389969024U,
|
||||
12398357632U, 12406750592U, 12415138432U, 12423527552U, 12431916416U,
|
||||
12440304512U, 12448692352U, 12457081216U, 12465467776U, 12473859968U,
|
||||
12482245504U, 12490636672U, 12499025536U, 12507411584U, 12515801728U,
|
||||
12524190592U, 12532577152U, 12540966272U, 12549354368U, 12557743232U,
|
||||
12566129536U, 12574523264U, 12582911872U, 12591299456U, 12599688064U,
|
||||
12608074624U, 12616463488U, 12624845696U, 12633239936U, 12641631616U,
|
||||
12650019968U, 12658407296U, 12666795136U, 12675183232U, 12683574656U,
|
||||
12691960192U, 12700350592U, 12708740224U, 12717128576U, 12725515904U,
|
||||
12733906816U, 12742295168U, 12750680192U, 12759071872U, 12767460736U,
|
||||
12775848832U, 12784236928U, 12792626816U, 12801014656U, 12809404288U,
|
||||
12817789312U, 12826181504U, 12834568832U, 12842954624U, 12851345792U,
|
||||
12859732352U, 12868122496U, 12876512128U, 12884901248U, 12893289088U,
|
||||
12901672832U, 12910067584U, 12918455168U, 12926842496U, 12935232896U,
|
||||
12943620736U, 12952009856U, 12960396928U, 12968786816U, 12977176192U,
|
||||
12985563776U, 12993951104U, 13002341504U, 13010730368U, 13019115392U,
|
||||
13027506304U, 13035895168U, 13044272512U, 13052673152U, 13061062528U,
|
||||
13069446272U, 13077838976U, 13086227072U, 13094613632U, 13103000192U,
|
||||
13111393664U, 13119782528U, 13128157568U, 13136559232U, 13144945024U,
|
||||
13153329536U, 13161724288U, 13170111872U, 13178502784U, 13186884736U,
|
||||
13195279744U, 13203667072U, 13212057472U, 13220445824U, 13228832128U,
|
||||
13237221248U, 13245610624U, 13254000512U, 13262388352U, 13270777472U,
|
||||
13279166336U, 13287553408U, 13295943296U, 13304331904U, 13312719488U,
|
||||
13321108096U, 13329494656U, 13337885824U, 13346274944U, 13354663808U,
|
||||
13363051136U, 13371439232U, 13379825024U, 13388210816U, 13396605056U,
|
||||
13404995456U, 13413380224U, 13421771392U, 13430159744U, 13438546048U,
|
||||
13446937216U, 13455326848U, 13463708288U, 13472103808U, 13480492672U,
|
||||
13488875648U, 13497269888U, 13505657728U, 13514045312U, 13522435712U,
|
||||
13530824576U, 13539210112U, 13547599232U, 13555989376U, 13564379008U,
|
||||
13572766336U, 13581154432U, 13589544832U, 13597932928U, 13606320512U,
|
||||
13614710656U, 13623097472U, 13631477632U, 13639874944U, 13648264064U,
|
||||
13656652928U, 13665041792U, 13673430656U, 13681818496U, 13690207616U,
|
||||
13698595712U, 13706982272U, 13715373184U, 13723762048U, 13732150144U,
|
||||
13740536704U, 13748926592U, 13757316224U, 13765700992U, 13774090112U,
|
||||
13782477952U, 13790869376U, 13799259008U, 13807647872U, 13816036736U,
|
||||
13824425344U, 13832814208U, 13841202304U, 13849591424U, 13857978752U,
|
||||
13866368896U, 13874754688U, 13883145344U, 13891533184U, 13899919232U,
|
||||
13908311168U, 13916692096U, 13925085056U, 13933473152U, 13941866368U,
|
||||
13950253696U, 13958643584U, 13967032192U, 13975417216U, 13983807616U,
|
||||
13992197504U, 14000582272U, 14008973696U, 14017363072U, 14025752192U,
|
||||
14034137984U, 14042528384U, 14050918016U, 14059301504U, 14067691648U,
|
||||
14076083584U, 14084470144U, 14092852352U, 14101249664U, 14109635968U,
|
||||
14118024832U, 14126407552U, 14134804352U, 14143188608U, 14151577984U,
|
||||
14159968384U, 14168357248U, 14176741504U, 14185127296U, 14193521024U,
|
||||
14201911424U, 14210301824U, 14218685056U, 14227067264U, 14235467392U,
|
||||
14243855488U, 14252243072U, 14260630144U, 14269021568U, 14277409408U,
|
||||
14285799296U, 14294187904U, 14302571392U, 14310961792U, 14319353728U,
|
||||
14327738752U, 14336130944U, 14344518784U, 14352906368U, 14361296512U,
|
||||
14369685376U, 14378071424U, 14386462592U, 14394848128U, 14403230848U,
|
||||
14411627392U, 14420013952U, 14428402304U, 14436793472U, 14445181568U,
|
||||
14453569664U, 14461959808U, 14470347904U, 14478737024U, 14487122816U,
|
||||
14495511424U, 14503901824U, 14512291712U, 14520677504U, 14529064832U,
|
||||
14537456768U, 14545845632U, 14554234496U, 14562618496U, 14571011456U,
|
||||
14579398784U, 14587789184U, 14596172672U, 14604564608U, 14612953984U,
|
||||
14621341312U, 14629724288U, 14638120832U, 14646503296U, 14654897536U,
|
||||
14663284864U, 14671675264U, 14680061056U, 14688447616U, 14696835968U,
|
||||
14705228416U, 14713616768U, 14722003328U, 14730392192U, 14738784128U,
|
||||
14747172736U, 14755561088U, 14763947648U, 14772336512U, 14780725376U,
|
||||
14789110144U, 14797499776U, 14805892736U, 14814276992U, 14822670208U,
|
||||
14831056256U, 14839444352U, 14847836032U, 14856222848U, 14864612992U,
|
||||
14872997504U, 14881388672U, 14889775744U, 14898165376U, 14906553472U,
|
||||
14914944896U, 14923329664U, 14931721856U, 14940109696U, 14948497024U,
|
||||
14956887424U, 14965276544U, 14973663616U, 14982053248U, 14990439808U,
|
||||
14998830976U, 15007216768U, 15015605888U, 15023995264U, 15032385152U,
|
||||
15040768384U, 15049154944U, 15057549184U, 15065939072U, 15074328448U,
|
||||
15082715008U, 15091104128U, 15099493504U, 15107879296U, 15116269184U,
|
||||
15124659584U, 15133042304U, 15141431936U, 15149824384U, 15158214272U,
|
||||
15166602368U, 15174991232U, 15183378304U, 15191760512U, 15200154496U,
|
||||
15208542592U, 15216931712U, 15225323392U, 15233708416U, 15242098048U,
|
||||
15250489216U, 15258875264U, 15267265408U, 15275654528U, 15284043136U,
|
||||
15292431488U, 15300819584U, 15309208192U, 15317596544U, 15325986176U,
|
||||
15334374784U, 15342763648U, 15351151744U, 15359540608U, 15367929728U,
|
||||
15376318336U, 15384706432U, 15393092992U, 15401481856U, 15409869952U,
|
||||
15418258816U, 15426649984U, 15435037568U, 15443425664U, 15451815296U,
|
||||
15460203392U, 15468589184U, 15476979328U, 15485369216U, 15493755776U,
|
||||
15502146944U, 15510534272U, 15518924416U, 15527311232U, 15535699072U,
|
||||
15544089472U, 15552478336U, 15560866688U, 15569254528U, 15577642624U,
|
||||
15586031488U, 15594419072U, 15602809472U, 15611199104U, 15619586432U,
|
||||
15627975296U, 15636364928U, 15644753792U, 15653141888U, 15661529216U,
|
||||
15669918848U, 15678305152U, 15686696576U, 15695083136U, 15703474048U,
|
||||
15711861632U, 15720251264U, 15728636288U, 15737027456U, 15745417088U,
|
||||
15753804928U, 15762194048U, 15770582656U, 15778971008U, 15787358336U,
|
||||
15795747712U, 15804132224U, 15812523392U, 15820909696U, 15829300096U,
|
||||
15837691264U, 15846071936U, 15854466944U, 15862855808U, 15871244672U,
|
||||
15879634816U, 15888020608U, 15896409728U, 15904799104U, 15913185152U,
|
||||
15921577088U, 15929966464U, 15938354816U, 15946743424U, 15955129472U,
|
||||
15963519872U, 15971907968U, 15980296064U, 15988684928U, 15997073024U,
|
||||
16005460864U, 16013851264U, 16022241152U, 16030629248U, 16039012736U,
|
||||
16047406976U, 16055794816U, 16064181376U, 16072571264U, 16080957824U,
|
||||
16089346688U, 16097737856U, 16106125184U, 16114514816U, 16122904192U,
|
||||
16131292544U, 16139678848U, 16148066944U, 16156453504U, 16164839552U,
|
||||
16173236096U, 16181623424U, 16190012032U, 16198401152U, 16206790528U,
|
||||
16215177344U, 16223567744U, 16231956352U, 16240344704U, 16248731008U,
|
||||
16257117824U, 16265504384U, 16273898624U, 16282281856U, 16290668672U,
|
||||
16299064192U, 16307449216U, 16315842176U, 16324230016U, 16332613504U,
|
||||
16341006464U, 16349394304U, 16357783168U, 16366172288U, 16374561664U,
|
||||
16382951296U, 16391337856U, 16399726208U, 16408116352U, 16416505472U,
|
||||
16424892032U, 16433282176U, 16441668224U, 16450058624U, 16458448768U,
|
||||
16466836864U, 16475224448U, 16483613056U, 16492001408U, 16500391808U,
|
||||
16508779648U, 16517166976U, 16525555328U, 16533944192U, 16542330752U,
|
||||
16550719616U, 16559110528U, 16567497088U, 16575888512U, 16584274816U,
|
||||
16592665472U, 16601051008U, 16609442944U, 16617832064U, 16626218624U,
|
||||
16634607488U, 16642996096U, 16651385728U, 16659773824U, 16668163712U,
|
||||
16676552576U, 16684938112U, 16693328768U, 16701718144U, 16710095488U,
|
||||
16718492288U, 16726883968U, 16735272832U, 16743661184U, 16752049792U,
|
||||
16760436608U, 16768827008U, 16777214336U, 16785599104U, 16793992832U,
|
||||
16802381696U, 16810768768U, 16819151744U, 16827542656U, 16835934848U,
|
||||
16844323712U, 16852711552U, 16861101952U, 16869489536U, 16877876864U,
|
||||
16886265728U, 16894653056U, 16903044736U, 16911431296U, 16919821696U,
|
||||
16928207488U, 16936592768U, 16944987776U, 16953375616U, 16961763968U,
|
||||
16970152832U, 16978540928U, 16986929536U, 16995319168U, 17003704448U,
|
||||
17012096896U, 17020481152U, 17028870784U, 17037262208U, 17045649536U,
|
||||
17054039936U, 17062426496U, 17070814336U, 17079205504U, 17087592064U,
|
||||
17095978112U, 17104369024U, 17112759424U, 17121147776U, 17129536384U,
|
||||
17137926016U, 17146314368U, 17154700928U, 17163089792U, 17171480192U,
|
||||
17179864192U, 17188256896U, 17196644992U, 17205033856U, 17213423488U,
|
||||
17221811072U, 17230198912U, 17238588032U, 17246976896U, 17255360384U,
|
||||
17263754624U, 17272143232U, 17280530048U, 17288918912U, 17297309312U,
|
||||
17305696384U, 17314085504U, 17322475136U, 17330863744U, 17339252096U,
|
||||
17347640192U, 17356026496U, 17364413824U, 17372796544U, 17381190016U,
|
||||
17389583488U, 17397972608U, 17406360704U, 17414748544U, 17423135872U,
|
||||
17431527296U, 17439915904U, 17448303232U, 17456691584U, 17465081728U,
|
||||
17473468288U, 17481857408U, 17490247552U, 17498635904U, 17507022464U,
|
||||
17515409024U, 17523801728U, 17532189824U, 17540577664U, 17548966016U,
|
||||
17557353344U, 17565741184U, 17574131584U, 17582519168U, 17590907008U,
|
||||
17599296128U, 17607687808U, 17616076672U, 17624455808U, 17632852352U,
|
||||
17641238656U, 17649630848U, 17658018944U, 17666403968U, 17674794112U,
|
||||
17683178368U, 17691573376U, 17699962496U, 17708350592U, 17716739968U,
|
||||
17725126528U, 17733517184U, 17741898112U, 17750293888U, 17758673024U,
|
||||
17767070336U, 17775458432U, 17783848832U, 17792236928U, 17800625536U,
|
||||
17809012352U, 17817402752U, 17825785984U, 17834178944U, 17842563968U,
|
||||
17850955648U, 17859344512U, 17867732864U, 17876119424U, 17884511872U,
|
||||
17892900224U, 17901287296U, 17909677696U, 17918058112U, 17926451072U,
|
||||
17934843776U, 17943230848U, 17951609216U, 17960008576U, 17968397696U,
|
||||
17976784256U, 17985175424U, 17993564032U, 18001952128U, 18010339712U,
|
||||
18018728576U, 18027116672U, 18035503232U, 18043894144U, 18052283264U,
|
||||
18060672128U, 18069056384U, 18077449856U, 18085837184U, 18094225792U,
|
||||
18102613376U, 18111004544U, 18119388544U, 18127781248U, 18136170368U,
|
||||
18144558976U, 18152947328U, 18161336192U, 18169724288U, 18178108544U,
|
||||
18186498944U, 18194886784U, 18203275648U, 18211666048U, 18220048768U,
|
||||
18228444544U, 18236833408U, 18245220736U
|
||||
};
|
||||
|
||||
|
||||
// Generated with the following Mathematica Code:
|
||||
|
||||
// GetCacheSizes[n_] := Module[{
|
||||
// DataSetSizeBytesInit = 2^30,
|
||||
// MixBytes = 128,
|
||||
// DataSetGrowth = 2^23,
|
||||
// HashBytes = 64,
|
||||
// CacheMultiplier = 1024,
|
||||
// j = 0},
|
||||
// Reap[
|
||||
// While[j < n,
|
||||
// Module[{i = Floor[(DataSetSizeBytesInit + DataSetGrowth * j) / (CacheMultiplier * HashBytes)]},
|
||||
// While[! PrimeQ[i], i--];
|
||||
// Sow[i*HashBytes]; j++]]]][[2]][[1]]
|
||||
|
||||
const uint64_t cache_sizes[2048] = {
|
||||
16776896U, 16907456U, 17039296U, 17170112U, 17301056U, 17432512U, 17563072U,
|
||||
17693888U, 17824192U, 17955904U, 18087488U, 18218176U, 18349504U, 18481088U,
|
||||
18611392U, 18742336U, 18874304U, 19004224U, 19135936U, 19267264U, 19398208U,
|
||||
19529408U, 19660096U, 19791424U, 19922752U, 20053952U, 20184896U, 20315968U,
|
||||
20446912U, 20576576U, 20709184U, 20840384U, 20971072U, 21102272U, 21233216U,
|
||||
21364544U, 21494848U, 21626816U, 21757376U, 21887552U, 22019392U, 22151104U,
|
||||
22281536U, 22412224U, 22543936U, 22675264U, 22806464U, 22935872U, 23068096U,
|
||||
23198272U, 23330752U, 23459008U, 23592512U, 23723968U, 23854912U, 23986112U,
|
||||
24116672U, 24247616U, 24378688U, 24509504U, 24640832U, 24772544U, 24903488U,
|
||||
25034432U, 25165376U, 25296704U, 25427392U, 25558592U, 25690048U, 25820096U,
|
||||
25951936U, 26081728U, 26214208U, 26345024U, 26476096U, 26606656U, 26737472U,
|
||||
26869184U, 26998208U, 27131584U, 27262528U, 27393728U, 27523904U, 27655744U,
|
||||
27786688U, 27917888U, 28049344U, 28179904U, 28311488U, 28441792U, 28573504U,
|
||||
28700864U, 28835648U, 28966208U, 29096768U, 29228608U, 29359808U, 29490752U,
|
||||
29621824U, 29752256U, 29882816U, 30014912U, 30144448U, 30273728U, 30406976U,
|
||||
30538432U, 30670784U, 30799936U, 30932672U, 31063744U, 31195072U, 31325248U,
|
||||
31456192U, 31588288U, 31719232U, 31850432U, 31981504U, 32110784U, 32243392U,
|
||||
32372672U, 32505664U, 32636608U, 32767808U, 32897344U, 33029824U, 33160768U,
|
||||
33289664U, 33423296U, 33554368U, 33683648U, 33816512U, 33947456U, 34076992U,
|
||||
34208704U, 34340032U, 34471744U, 34600256U, 34734016U, 34864576U, 34993984U,
|
||||
35127104U, 35258176U, 35386688U, 35518528U, 35650624U, 35782336U, 35910976U,
|
||||
36044608U, 36175808U, 36305728U, 36436672U, 36568384U, 36699968U, 36830656U,
|
||||
36961984U, 37093312U, 37223488U, 37355072U, 37486528U, 37617472U, 37747904U,
|
||||
37879232U, 38009792U, 38141888U, 38272448U, 38403392U, 38535104U, 38660672U,
|
||||
38795584U, 38925632U, 39059264U, 39190336U, 39320768U, 39452096U, 39581632U,
|
||||
39713984U, 39844928U, 39974848U, 40107968U, 40238144U, 40367168U, 40500032U,
|
||||
40631744U, 40762816U, 40894144U, 41023552U, 41155904U, 41286208U, 41418304U,
|
||||
41547712U, 41680448U, 41811904U, 41942848U, 42073792U, 42204992U, 42334912U,
|
||||
42467008U, 42597824U, 42729152U, 42860096U, 42991552U, 43122368U, 43253696U,
|
||||
43382848U, 43515712U, 43646912U, 43777088U, 43907648U, 44039104U, 44170432U,
|
||||
44302144U, 44433344U, 44564288U, 44694976U, 44825152U, 44956864U, 45088448U,
|
||||
45219008U, 45350464U, 45481024U, 45612608U, 45744064U, 45874496U, 46006208U,
|
||||
46136768U, 46267712U, 46399424U, 46529344U, 46660672U, 46791488U, 46923328U,
|
||||
47053504U, 47185856U, 47316928U, 47447872U, 47579072U, 47710144U, 47839936U,
|
||||
47971648U, 48103232U, 48234176U, 48365248U, 48496192U, 48627136U, 48757312U,
|
||||
48889664U, 49020736U, 49149248U, 49283008U, 49413824U, 49545152U, 49675712U,
|
||||
49807168U, 49938368U, 50069056U, 50200256U, 50331584U, 50462656U, 50593472U,
|
||||
50724032U, 50853952U, 50986048U, 51117632U, 51248576U, 51379904U, 51510848U,
|
||||
51641792U, 51773248U, 51903296U, 52035136U, 52164032U, 52297664U, 52427968U,
|
||||
52557376U, 52690112U, 52821952U, 52952896U, 53081536U, 53213504U, 53344576U,
|
||||
53475776U, 53608384U, 53738816U, 53870528U, 54000832U, 54131776U, 54263744U,
|
||||
54394688U, 54525248U, 54655936U, 54787904U, 54918592U, 55049152U, 55181248U,
|
||||
55312064U, 55442752U, 55574336U, 55705024U, 55836224U, 55967168U, 56097856U,
|
||||
56228672U, 56358592U, 56490176U, 56621888U, 56753728U, 56884928U, 57015488U,
|
||||
57146816U, 57278272U, 57409216U, 57540416U, 57671104U, 57802432U, 57933632U,
|
||||
58064576U, 58195264U, 58326976U, 58457408U, 58588864U, 58720192U, 58849984U,
|
||||
58981696U, 59113024U, 59243456U, 59375552U, 59506624U, 59637568U, 59768512U,
|
||||
59897792U, 60030016U, 60161984U, 60293056U, 60423872U, 60554432U, 60683968U,
|
||||
60817216U, 60948032U, 61079488U, 61209664U, 61341376U, 61471936U, 61602752U,
|
||||
61733696U, 61865792U, 61996736U, 62127808U, 62259136U, 62389568U, 62520512U,
|
||||
62651584U, 62781632U, 62910784U, 63045056U, 63176128U, 63307072U, 63438656U,
|
||||
63569216U, 63700928U, 63831616U, 63960896U, 64093888U, 64225088U, 64355392U,
|
||||
64486976U, 64617664U, 64748608U, 64879424U, 65009216U, 65142464U, 65273792U,
|
||||
65402816U, 65535424U, 65666752U, 65797696U, 65927744U, 66060224U, 66191296U,
|
||||
66321344U, 66453056U, 66584384U, 66715328U, 66846656U, 66977728U, 67108672U,
|
||||
67239104U, 67370432U, 67501888U, 67631296U, 67763776U, 67895104U, 68026304U,
|
||||
68157248U, 68287936U, 68419264U, 68548288U, 68681408U, 68811968U, 68942912U,
|
||||
69074624U, 69205568U, 69337024U, 69467584U, 69599168U, 69729472U, 69861184U,
|
||||
69989824U, 70122944U, 70253888U, 70385344U, 70515904U, 70647232U, 70778816U,
|
||||
70907968U, 71040832U, 71171648U, 71303104U, 71432512U, 71564992U, 71695168U,
|
||||
71826368U, 71958464U, 72089536U, 72219712U, 72350144U, 72482624U, 72613568U,
|
||||
72744512U, 72875584U, 73006144U, 73138112U, 73268672U, 73400128U, 73530944U,
|
||||
73662272U, 73793344U, 73924544U, 74055104U, 74185792U, 74316992U, 74448832U,
|
||||
74579392U, 74710976U, 74841664U, 74972864U, 75102784U, 75233344U, 75364544U,
|
||||
75497024U, 75627584U, 75759296U, 75890624U, 76021696U, 76152256U, 76283072U,
|
||||
76414144U, 76545856U, 76676672U, 76806976U, 76937792U, 77070016U, 77200832U,
|
||||
77331392U, 77462464U, 77593664U, 77725376U, 77856448U, 77987776U, 78118336U,
|
||||
78249664U, 78380992U, 78511424U, 78642496U, 78773056U, 78905152U, 79033664U,
|
||||
79166656U, 79297472U, 79429568U, 79560512U, 79690816U, 79822784U, 79953472U,
|
||||
80084672U, 80214208U, 80346944U, 80477632U, 80608576U, 80740288U, 80870848U,
|
||||
81002048U, 81133504U, 81264448U, 81395648U, 81525952U, 81657536U, 81786304U,
|
||||
81919808U, 82050112U, 82181312U, 82311616U, 82443968U, 82573376U, 82705984U,
|
||||
82835776U, 82967744U, 83096768U, 83230528U, 83359552U, 83491264U, 83622464U,
|
||||
83753536U, 83886016U, 84015296U, 84147776U, 84277184U, 84409792U, 84540608U,
|
||||
84672064U, 84803008U, 84934336U, 85065152U, 85193792U, 85326784U, 85458496U,
|
||||
85589312U, 85721024U, 85851968U, 85982656U, 86112448U, 86244416U, 86370112U,
|
||||
86506688U, 86637632U, 86769344U, 86900672U, 87031744U, 87162304U, 87293632U,
|
||||
87424576U, 87555392U, 87687104U, 87816896U, 87947968U, 88079168U, 88211264U,
|
||||
88341824U, 88473152U, 88603712U, 88735424U, 88862912U, 88996672U, 89128384U,
|
||||
89259712U, 89390272U, 89521984U, 89652544U, 89783872U, 89914816U, 90045376U,
|
||||
90177088U, 90307904U, 90438848U, 90569152U, 90700096U, 90832832U, 90963776U,
|
||||
91093696U, 91223744U, 91356992U, 91486784U, 91618496U, 91749824U, 91880384U,
|
||||
92012224U, 92143552U, 92273344U, 92405696U, 92536768U, 92666432U, 92798912U,
|
||||
92926016U, 93060544U, 93192128U, 93322816U, 93453632U, 93583936U, 93715136U,
|
||||
93845056U, 93977792U, 94109504U, 94240448U, 94371776U, 94501184U, 94632896U,
|
||||
94764224U, 94895552U, 95023424U, 95158208U, 95287744U, 95420224U, 95550016U,
|
||||
95681216U, 95811904U, 95943872U, 96075328U, 96203584U, 96337856U, 96468544U,
|
||||
96599744U, 96731072U, 96860992U, 96992576U, 97124288U, 97254848U, 97385536U,
|
||||
97517248U, 97647808U, 97779392U, 97910464U, 98041408U, 98172608U, 98303168U,
|
||||
98434496U, 98565568U, 98696768U, 98827328U, 98958784U, 99089728U, 99220928U,
|
||||
99352384U, 99482816U, 99614272U, 99745472U, 99876416U, 100007104U,
|
||||
100138048U, 100267072U, 100401088U, 100529984U, 100662592U, 100791872U,
|
||||
100925248U, 101056064U, 101187392U, 101317952U, 101449408U, 101580608U,
|
||||
101711296U, 101841728U, 101973824U, 102104896U, 102235712U, 102366016U,
|
||||
102498112U, 102628672U, 102760384U, 102890432U, 103021888U, 103153472U,
|
||||
103284032U, 103415744U, 103545152U, 103677248U, 103808576U, 103939648U,
|
||||
104070976U, 104201792U, 104332736U, 104462528U, 104594752U, 104725952U,
|
||||
104854592U, 104988608U, 105118912U, 105247808U, 105381184U, 105511232U,
|
||||
105643072U, 105774784U, 105903296U, 106037056U, 106167872U, 106298944U,
|
||||
106429504U, 106561472U, 106691392U, 106822592U, 106954304U, 107085376U,
|
||||
107216576U, 107346368U, 107478464U, 107609792U, 107739712U, 107872192U,
|
||||
108003136U, 108131392U, 108265408U, 108396224U, 108527168U, 108657344U,
|
||||
108789568U, 108920384U, 109049792U, 109182272U, 109312576U, 109444928U,
|
||||
109572928U, 109706944U, 109837888U, 109969088U, 110099648U, 110230976U,
|
||||
110362432U, 110492992U, 110624704U, 110755264U, 110886208U, 111017408U,
|
||||
111148864U, 111279296U, 111410752U, 111541952U, 111673024U, 111803456U,
|
||||
111933632U, 112066496U, 112196416U, 112328512U, 112457792U, 112590784U,
|
||||
112715968U, 112852672U, 112983616U, 113114944U, 113244224U, 113376448U,
|
||||
113505472U, 113639104U, 113770304U, 113901376U, 114031552U, 114163264U,
|
||||
114294592U, 114425536U, 114556864U, 114687424U, 114818624U, 114948544U,
|
||||
115080512U, 115212224U, 115343296U, 115473472U, 115605184U, 115736128U,
|
||||
115867072U, 115997248U, 116128576U, 116260288U, 116391488U, 116522944U,
|
||||
116652992U, 116784704U, 116915648U, 117046208U, 117178304U, 117308608U,
|
||||
117440192U, 117569728U, 117701824U, 117833024U, 117964096U, 118094656U,
|
||||
118225984U, 118357312U, 118489024U, 118617536U, 118749632U, 118882112U,
|
||||
119012416U, 119144384U, 119275328U, 119406016U, 119537344U, 119668672U,
|
||||
119798464U, 119928896U, 120061376U, 120192832U, 120321728U, 120454336U,
|
||||
120584512U, 120716608U, 120848192U, 120979136U, 121109056U, 121241408U,
|
||||
121372352U, 121502912U, 121634752U, 121764416U, 121895744U, 122027072U,
|
||||
122157632U, 122289088U, 122421184U, 122550592U, 122682944U, 122813888U,
|
||||
122945344U, 123075776U, 123207488U, 123338048U, 123468736U, 123600704U,
|
||||
123731264U, 123861952U, 123993664U, 124124608U, 124256192U, 124386368U,
|
||||
124518208U, 124649024U, 124778048U, 124911296U, 125041088U, 125173696U,
|
||||
125303744U, 125432896U, 125566912U, 125696576U, 125829056U, 125958592U,
|
||||
126090304U, 126221248U, 126352832U, 126483776U, 126615232U, 126746432U,
|
||||
126876608U, 127008704U, 127139392U, 127270336U, 127401152U, 127532224U,
|
||||
127663552U, 127794752U, 127925696U, 128055232U, 128188096U, 128319424U,
|
||||
128449856U, 128581312U, 128712256U, 128843584U, 128973632U, 129103808U,
|
||||
129236288U, 129365696U, 129498944U, 129629888U, 129760832U, 129892288U,
|
||||
130023104U, 130154048U, 130283968U, 130416448U, 130547008U, 130678336U,
|
||||
130807616U, 130939456U, 131071552U, 131202112U, 131331776U, 131464384U,
|
||||
131594048U, 131727296U, 131858368U, 131987392U, 132120256U, 132250816U,
|
||||
132382528U, 132513728U, 132644672U, 132774976U, 132905792U, 133038016U,
|
||||
133168832U, 133299392U, 133429312U, 133562048U, 133692992U, 133823296U,
|
||||
133954624U, 134086336U, 134217152U, 134348608U, 134479808U, 134607296U,
|
||||
134741056U, 134872384U, 135002944U, 135134144U, 135265472U, 135396544U,
|
||||
135527872U, 135659072U, 135787712U, 135921472U, 136052416U, 136182848U,
|
||||
136313792U, 136444864U, 136576448U, 136707904U, 136837952U, 136970048U,
|
||||
137099584U, 137232064U, 137363392U, 137494208U, 137625536U, 137755712U,
|
||||
137887424U, 138018368U, 138149824U, 138280256U, 138411584U, 138539584U,
|
||||
138672832U, 138804928U, 138936128U, 139066688U, 139196864U, 139328704U,
|
||||
139460032U, 139590208U, 139721024U, 139852864U, 139984576U, 140115776U,
|
||||
140245696U, 140376512U, 140508352U, 140640064U, 140769856U, 140902336U,
|
||||
141032768U, 141162688U, 141294016U, 141426496U, 141556544U, 141687488U,
|
||||
141819584U, 141949888U, 142080448U, 142212544U, 142342336U, 142474432U,
|
||||
142606144U, 142736192U, 142868288U, 142997824U, 143129408U, 143258944U,
|
||||
143392448U, 143523136U, 143653696U, 143785024U, 143916992U, 144045632U,
|
||||
144177856U, 144309184U, 144440768U, 144570688U, 144701888U, 144832448U,
|
||||
144965056U, 145096384U, 145227584U, 145358656U, 145489856U, 145620928U,
|
||||
145751488U, 145883072U, 146011456U, 146144704U, 146275264U, 146407232U,
|
||||
146538176U, 146668736U, 146800448U, 146931392U, 147062336U, 147193664U,
|
||||
147324224U, 147455936U, 147586624U, 147717056U, 147848768U, 147979456U,
|
||||
148110784U, 148242368U, 148373312U, 148503232U, 148635584U, 148766144U,
|
||||
148897088U, 149028416U, 149159488U, 149290688U, 149420224U, 149551552U,
|
||||
149683136U, 149814976U, 149943616U, 150076352U, 150208064U, 150338624U,
|
||||
150470464U, 150600256U, 150732224U, 150862784U, 150993088U, 151125952U,
|
||||
151254976U, 151388096U, 151519168U, 151649728U, 151778752U, 151911104U,
|
||||
152042944U, 152174144U, 152304704U, 152435648U, 152567488U, 152698816U,
|
||||
152828992U, 152960576U, 153091648U, 153222976U, 153353792U, 153484096U,
|
||||
153616192U, 153747008U, 153878336U, 154008256U, 154139968U, 154270912U,
|
||||
154402624U, 154533824U, 154663616U, 154795712U, 154926272U, 155057984U,
|
||||
155188928U, 155319872U, 155450816U, 155580608U, 155712064U, 155843392U,
|
||||
155971136U, 156106688U, 156237376U, 156367424U, 156499264U, 156630976U,
|
||||
156761536U, 156892352U, 157024064U, 157155008U, 157284416U, 157415872U,
|
||||
157545536U, 157677248U, 157810496U, 157938112U, 158071744U, 158203328U,
|
||||
158334656U, 158464832U, 158596288U, 158727616U, 158858048U, 158988992U,
|
||||
159121216U, 159252416U, 159381568U, 159513152U, 159645632U, 159776192U,
|
||||
159906496U, 160038464U, 160169536U, 160300352U, 160430656U, 160563008U,
|
||||
160693952U, 160822208U, 160956352U, 161086784U, 161217344U, 161349184U,
|
||||
161480512U, 161611456U, 161742272U, 161873216U, 162002752U, 162135872U,
|
||||
162266432U, 162397888U, 162529216U, 162660032U, 162790976U, 162922048U,
|
||||
163052096U, 163184576U, 163314752U, 163446592U, 163577408U, 163707968U,
|
||||
163839296U, 163969984U, 164100928U, 164233024U, 164364224U, 164494912U,
|
||||
164625856U, 164756672U, 164887616U, 165019072U, 165150016U, 165280064U,
|
||||
165412672U, 165543104U, 165674944U, 165805888U, 165936832U, 166067648U,
|
||||
166198336U, 166330048U, 166461248U, 166591552U, 166722496U, 166854208U,
|
||||
166985408U, 167116736U, 167246656U, 167378368U, 167508416U, 167641024U,
|
||||
167771584U, 167903168U, 168034112U, 168164032U, 168295744U, 168427456U,
|
||||
168557632U, 168688448U, 168819136U, 168951616U, 169082176U, 169213504U,
|
||||
169344832U, 169475648U, 169605952U, 169738048U, 169866304U, 169999552U,
|
||||
170131264U, 170262464U, 170393536U, 170524352U, 170655424U, 170782016U,
|
||||
170917696U, 171048896U, 171179072U, 171310784U, 171439936U, 171573184U,
|
||||
171702976U, 171835072U, 171966272U, 172097216U, 172228288U, 172359232U,
|
||||
172489664U, 172621376U, 172747712U, 172883264U, 173014208U, 173144512U,
|
||||
173275072U, 173407424U, 173539136U, 173669696U, 173800768U, 173931712U,
|
||||
174063424U, 174193472U, 174325696U, 174455744U, 174586816U, 174718912U,
|
||||
174849728U, 174977728U, 175109696U, 175242688U, 175374272U, 175504832U,
|
||||
175636288U, 175765696U, 175898432U, 176028992U, 176159936U, 176291264U,
|
||||
176422592U, 176552512U, 176684864U, 176815424U, 176946496U, 177076544U,
|
||||
177209152U, 177340096U, 177470528U, 177600704U, 177731648U, 177864256U,
|
||||
177994816U, 178126528U, 178257472U, 178387648U, 178518464U, 178650176U,
|
||||
178781888U, 178912064U, 179044288U, 179174848U, 179305024U, 179436736U,
|
||||
179568448U, 179698496U, 179830208U, 179960512U, 180092608U, 180223808U,
|
||||
180354752U, 180485696U, 180617152U, 180748096U, 180877504U, 181009984U,
|
||||
181139264U, 181272512U, 181402688U, 181532608U, 181663168U, 181795136U,
|
||||
181926592U, 182057536U, 182190016U, 182320192U, 182451904U, 182582336U,
|
||||
182713792U, 182843072U, 182976064U, 183107264U, 183237056U, 183368384U,
|
||||
183494848U, 183631424U, 183762752U, 183893824U, 184024768U, 184154816U,
|
||||
184286656U, 184417984U, 184548928U, 184680128U, 184810816U, 184941248U,
|
||||
185072704U, 185203904U, 185335616U, 185465408U, 185596352U, 185727296U,
|
||||
185859904U, 185989696U, 186121664U, 186252992U, 186383552U, 186514112U,
|
||||
186645952U, 186777152U, 186907328U, 187037504U, 187170112U, 187301824U,
|
||||
187429184U, 187562048U, 187693504U, 187825472U, 187957184U, 188087104U,
|
||||
188218304U, 188349376U, 188481344U, 188609728U, 188743616U, 188874304U,
|
||||
189005248U, 189136448U, 189265088U, 189396544U, 189528128U, 189660992U,
|
||||
189791936U, 189923264U, 190054208U, 190182848U, 190315072U, 190447424U,
|
||||
190577984U, 190709312U, 190840768U, 190971328U, 191102656U, 191233472U,
|
||||
191364032U, 191495872U, 191626816U, 191758016U, 191888192U, 192020288U,
|
||||
192148928U, 192282176U, 192413504U, 192542528U, 192674752U, 192805952U,
|
||||
192937792U, 193068608U, 193198912U, 193330496U, 193462208U, 193592384U,
|
||||
193723456U, 193854272U, 193985984U, 194116672U, 194247232U, 194379712U,
|
||||
194508352U, 194641856U, 194772544U, 194900672U, 195035072U, 195166016U,
|
||||
195296704U, 195428032U, 195558592U, 195690304U, 195818176U, 195952576U,
|
||||
196083392U, 196214336U, 196345792U, 196476736U, 196607552U, 196739008U,
|
||||
196869952U, 197000768U, 197130688U, 197262784U, 197394368U, 197523904U,
|
||||
197656384U, 197787584U, 197916608U, 198049472U, 198180544U, 198310208U,
|
||||
198442432U, 198573632U, 198705088U, 198834368U, 198967232U, 199097792U,
|
||||
199228352U, 199360192U, 199491392U, 199621696U, 199751744U, 199883968U,
|
||||
200014016U, 200146624U, 200276672U, 200408128U, 200540096U, 200671168U,
|
||||
200801984U, 200933312U, 201062464U, 201194944U, 201326144U, 201457472U,
|
||||
201588544U, 201719744U, 201850816U, 201981632U, 202111552U, 202244032U,
|
||||
202374464U, 202505152U, 202636352U, 202767808U, 202898368U, 203030336U,
|
||||
203159872U, 203292608U, 203423296U, 203553472U, 203685824U, 203816896U,
|
||||
203947712U, 204078272U, 204208192U, 204341056U, 204472256U, 204603328U,
|
||||
204733888U, 204864448U, 204996544U, 205125568U, 205258304U, 205388864U,
|
||||
205517632U, 205650112U, 205782208U, 205913536U, 206044736U, 206176192U,
|
||||
206307008U, 206434496U, 206569024U, 206700224U, 206831168U, 206961856U,
|
||||
207093056U, 207223616U, 207355328U, 207486784U, 207616832U, 207749056U,
|
||||
207879104U, 208010048U, 208141888U, 208273216U, 208404032U, 208534336U,
|
||||
208666048U, 208796864U, 208927424U, 209059264U, 209189824U, 209321792U,
|
||||
209451584U, 209582656U, 209715136U, 209845568U, 209976896U, 210106432U,
|
||||
210239296U, 210370112U, 210501568U, 210630976U, 210763712U, 210894272U,
|
||||
211024832U, 211156672U, 211287616U, 211418176U, 211549376U, 211679296U,
|
||||
211812032U, 211942592U, 212074432U, 212204864U, 212334016U, 212467648U,
|
||||
212597824U, 212727616U, 212860352U, 212991424U, 213120832U, 213253952U,
|
||||
213385024U, 213515584U, 213645632U, 213777728U, 213909184U, 214040128U,
|
||||
214170688U, 214302656U, 214433728U, 214564544U, 214695232U, 214826048U,
|
||||
214956992U, 215089088U, 215219776U, 215350592U, 215482304U, 215613248U,
|
||||
215743552U, 215874752U, 216005312U, 216137024U, 216267328U, 216399296U,
|
||||
216530752U, 216661696U, 216790592U, 216923968U, 217054528U, 217183168U,
|
||||
217316672U, 217448128U, 217579072U, 217709504U, 217838912U, 217972672U,
|
||||
218102848U, 218233024U, 218364736U, 218496832U, 218627776U, 218759104U,
|
||||
218888896U, 219021248U, 219151936U, 219281728U, 219413056U, 219545024U,
|
||||
219675968U, 219807296U, 219938624U, 220069312U, 220200128U, 220331456U,
|
||||
220461632U, 220592704U, 220725184U, 220855744U, 220987072U, 221117888U,
|
||||
221249216U, 221378368U, 221510336U, 221642048U, 221772736U, 221904832U,
|
||||
222031808U, 222166976U, 222297536U, 222428992U, 222559936U, 222690368U,
|
||||
222820672U, 222953152U, 223083968U, 223213376U, 223345984U, 223476928U,
|
||||
223608512U, 223738688U, 223869376U, 224001472U, 224132672U, 224262848U,
|
||||
224394944U, 224524864U, 224657344U, 224788288U, 224919488U, 225050432U,
|
||||
225181504U, 225312704U, 225443776U, 225574592U, 225704768U, 225834176U,
|
||||
225966784U, 226097216U, 226229824U, 226360384U, 226491712U, 226623424U,
|
||||
226754368U, 226885312U, 227015104U, 227147456U, 227278528U, 227409472U,
|
||||
227539904U, 227669696U, 227802944U, 227932352U, 228065216U, 228196288U,
|
||||
228326464U, 228457792U, 228588736U, 228720064U, 228850112U, 228981056U,
|
||||
229113152U, 229243328U, 229375936U, 229505344U, 229636928U, 229769152U,
|
||||
229894976U, 230030272U, 230162368U, 230292416U, 230424512U, 230553152U,
|
||||
230684864U, 230816704U, 230948416U, 231079616U, 231210944U, 231342016U,
|
||||
231472448U, 231603776U, 231733952U, 231866176U, 231996736U, 232127296U,
|
||||
232259392U, 232388672U, 232521664U, 232652608U, 232782272U, 232914496U,
|
||||
233043904U, 233175616U, 233306816U, 233438528U, 233569984U, 233699776U,
|
||||
233830592U, 233962688U, 234092224U, 234221888U, 234353984U, 234485312U,
|
||||
234618304U, 234749888U, 234880832U, 235011776U, 235142464U, 235274048U,
|
||||
235403456U, 235535936U, 235667392U, 235797568U, 235928768U, 236057152U,
|
||||
236190272U, 236322752U, 236453312U, 236583616U, 236715712U, 236846528U,
|
||||
236976448U, 237108544U, 237239104U, 237371072U, 237501632U, 237630784U,
|
||||
237764416U, 237895232U, 238026688U, 238157632U, 238286912U, 238419392U,
|
||||
238548032U, 238681024U, 238812608U, 238941632U, 239075008U, 239206336U,
|
||||
239335232U, 239466944U, 239599168U, 239730496U, 239861312U, 239992384U,
|
||||
240122816U, 240254656U, 240385856U, 240516928U, 240647872U, 240779072U,
|
||||
240909632U, 241040704U, 241171904U, 241302848U, 241433408U, 241565248U,
|
||||
241696192U, 241825984U, 241958848U, 242088256U, 242220224U, 242352064U,
|
||||
242481856U, 242611648U, 242744896U, 242876224U, 243005632U, 243138496U,
|
||||
243268672U, 243400384U, 243531712U, 243662656U, 243793856U, 243924544U,
|
||||
244054592U, 244187072U, 244316608U, 244448704U, 244580032U, 244710976U,
|
||||
244841536U, 244972864U, 245104448U, 245233984U, 245365312U, 245497792U,
|
||||
245628736U, 245759936U, 245889856U, 246021056U, 246152512U, 246284224U,
|
||||
246415168U, 246545344U, 246675904U, 246808384U, 246939584U, 247070144U,
|
||||
247199552U, 247331648U, 247463872U, 247593536U, 247726016U, 247857088U,
|
||||
247987648U, 248116928U, 248249536U, 248380736U, 248512064U, 248643008U,
|
||||
248773312U, 248901056U, 249036608U, 249167552U, 249298624U, 249429184U,
|
||||
249560512U, 249692096U, 249822784U, 249954112U, 250085312U, 250215488U,
|
||||
250345792U, 250478528U, 250608704U, 250739264U, 250870976U, 251002816U,
|
||||
251133632U, 251263552U, 251395136U, 251523904U, 251657792U, 251789248U,
|
||||
251919424U, 252051392U, 252182464U, 252313408U, 252444224U, 252575552U,
|
||||
252706624U, 252836032U, 252968512U, 253099712U, 253227584U, 253361728U,
|
||||
253493056U, 253623488U, 253754432U, 253885504U, 254017216U, 254148032U,
|
||||
254279488U, 254410432U, 254541376U, 254672576U, 254803264U, 254933824U,
|
||||
255065792U, 255196736U, 255326528U, 255458752U, 255589952U, 255721408U,
|
||||
255851072U, 255983296U, 256114624U, 256244416U, 256374208U, 256507712U,
|
||||
256636096U, 256768832U, 256900544U, 257031616U, 257162176U, 257294272U,
|
||||
257424448U, 257555776U, 257686976U, 257818432U, 257949632U, 258079552U,
|
||||
258211136U, 258342464U, 258473408U, 258603712U, 258734656U, 258867008U,
|
||||
258996544U, 259127744U, 259260224U, 259391296U, 259522112U, 259651904U,
|
||||
259784384U, 259915328U, 260045888U, 260175424U, 260308544U, 260438336U,
|
||||
260570944U, 260700992U, 260832448U, 260963776U, 261092672U, 261226304U,
|
||||
261356864U, 261487936U, 261619648U, 261750592U, 261879872U, 262011968U,
|
||||
262143424U, 262274752U, 262404416U, 262537024U, 262667968U, 262799296U,
|
||||
262928704U, 263061184U, 263191744U, 263322944U, 263454656U, 263585216U,
|
||||
263716672U, 263847872U, 263978944U, 264108608U, 264241088U, 264371648U,
|
||||
264501184U, 264632768U, 264764096U, 264895936U, 265024576U, 265158464U,
|
||||
265287488U, 265418432U, 265550528U, 265681216U, 265813312U, 265943488U,
|
||||
266075968U, 266206144U, 266337728U, 266468032U, 266600384U, 266731072U,
|
||||
266862272U, 266993344U, 267124288U, 267255616U, 267386432U, 267516992U,
|
||||
267648704U, 267777728U, 267910592U, 268040512U, 268172096U, 268302784U,
|
||||
268435264U, 268566208U, 268696256U, 268828096U, 268959296U, 269090368U,
|
||||
269221312U, 269352256U, 269482688U, 269614784U, 269745856U, 269876416U,
|
||||
270007616U, 270139328U, 270270272U, 270401216U, 270531904U, 270663616U,
|
||||
270791744U, 270924736U, 271056832U, 271186112U, 271317184U, 271449536U,
|
||||
271580992U, 271711936U, 271843136U, 271973056U, 272105408U, 272236352U,
|
||||
272367296U, 272498368U, 272629568U, 272759488U, 272891456U, 273022784U,
|
||||
273153856U, 273284672U, 273415616U, 273547072U, 273677632U, 273808448U,
|
||||
273937088U, 274071488U, 274200896U, 274332992U, 274463296U, 274595392U,
|
||||
274726208U, 274857536U, 274988992U, 275118656U, 275250496U, 275382208U,
|
||||
275513024U, 275643968U, 275775296U, 275906368U, 276037184U, 276167872U,
|
||||
276297664U, 276429376U, 276560576U, 276692672U, 276822976U, 276955072U,
|
||||
277085632U, 277216832U, 277347008U, 277478848U, 277609664U, 277740992U,
|
||||
277868608U, 278002624U, 278134336U, 278265536U, 278395328U, 278526784U,
|
||||
278657728U, 278789824U, 278921152U, 279052096U, 279182912U, 279313088U,
|
||||
279443776U, 279576256U, 279706048U, 279838528U, 279969728U, 280099648U,
|
||||
280230976U, 280361408U, 280493632U, 280622528U, 280755392U, 280887104U,
|
||||
281018176U, 281147968U, 281278912U, 281411392U, 281542592U, 281673152U,
|
||||
281803712U, 281935552U, 282066496U, 282197312U, 282329024U, 282458816U,
|
||||
282590272U, 282720832U, 282853184U, 282983744U, 283115072U, 283246144U,
|
||||
283377344U, 283508416U, 283639744U, 283770304U, 283901504U, 284032576U,
|
||||
284163136U, 284294848U, 284426176U, 284556992U, 284687296U, 284819264U,
|
||||
284950208U, 285081536U
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
77
src/3rdparty/libethash/endian.h
vendored
77
src/3rdparty/libethash/endian.h
vendored
@@ -1,77 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(__MINGW32__) || defined(_WIN32)
|
||||
# define LITTLE_ENDIAN 1234
|
||||
# define BYTE_ORDER LITTLE_ENDIAN
|
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
|
||||
# include <sys/endian.h>
|
||||
#elif defined(__OpenBSD__) || defined(__SVR4)
|
||||
# include <sys/types.h>
|
||||
#elif defined(__APPLE__)
|
||||
# include <machine/endian.h>
|
||||
#elif defined( BSD ) && (BSD >= 199103)
|
||||
# include <machine/endian.h>
|
||||
#elif defined( __QNXNTO__ ) && defined( __LITTLEENDIAN__ )
|
||||
# define LITTLE_ENDIAN 1234
|
||||
# define BYTE_ORDER LITTLE_ENDIAN
|
||||
#elif defined( __QNXNTO__ ) && defined( __BIGENDIAN__ )
|
||||
# define BIG_ENDIAN 1234
|
||||
# define BYTE_ORDER BIG_ENDIAN
|
||||
#else
|
||||
# include <endian.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <stdlib.h>
|
||||
#define ethash_swap_u32(input_) _byteswap_ulong(input_)
|
||||
#define ethash_swap_u64(input_) _byteswap_uint64(input_)
|
||||
#elif defined(__APPLE__)
|
||||
#include <libkern/OSByteOrder.h>
|
||||
#define ethash_swap_u32(input_) OSSwapInt32(input_)
|
||||
#define ethash_swap_u64(input_) OSSwapInt64(input_)
|
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
|
||||
#define ethash_swap_u32(input_) bswap32(input_)
|
||||
#define ethash_swap_u64(input_) bswap64(input_)
|
||||
#elif defined(__OpenBSD__)
|
||||
#include <endian.h>
|
||||
#define ethash_swap_u32(input_) swap32(input_)
|
||||
#define ethash_swap_u64(input_) swap64(input_)
|
||||
#else // posix
|
||||
#include <byteswap.h>
|
||||
#define ethash_swap_u32(input_) bswap_32(input_)
|
||||
#define ethash_swap_u64(input_) bswap_64(input_)
|
||||
#endif
|
||||
|
||||
|
||||
#if LITTLE_ENDIAN == BYTE_ORDER
|
||||
|
||||
#define fix_endian32(dst_ ,src_) dst_ = src_
|
||||
#define fix_endian32_same(val_)
|
||||
#define fix_endian64(dst_, src_) dst_ = src_
|
||||
#define fix_endian64_same(val_)
|
||||
#define fix_endian_arr32(arr_, size_)
|
||||
#define fix_endian_arr64(arr_, size_)
|
||||
|
||||
#elif BIG_ENDIAN == BYTE_ORDER
|
||||
|
||||
#define fix_endian32(dst_, src_) dst_ = ethash_swap_u32(src_)
|
||||
#define fix_endian32_same(val_) val_ = ethash_swap_u32(val_)
|
||||
#define fix_endian64(dst_, src_) dst_ = ethash_swap_u64(src_)
|
||||
#define fix_endian64_same(val_) val_ = ethash_swap_u64(val_)
|
||||
#define fix_endian_arr32(arr_, size_) \
|
||||
do { \
|
||||
for (unsigned i_ = 0; i_ < (size_); ++i_) { \
|
||||
arr_[i_] = ethash_swap_u32(arr_[i_]); \
|
||||
} \
|
||||
} while (0)
|
||||
#define fix_endian_arr64(arr_, size_) \
|
||||
do { \
|
||||
for (unsigned i_ = 0; i_ < (size_); ++i_) { \
|
||||
arr_[i_] = ethash_swap_u64(arr_[i_]); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
# error "endian not supported"
|
||||
#endif // BYTE_ORDER
|
||||
158
src/3rdparty/libethash/ethash.h
vendored
158
src/3rdparty/libethash/ethash.h
vendored
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
This file is part of ethash.
|
||||
|
||||
ethash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ethash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ethash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file ethash.h
|
||||
* @date 2015
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define ETHASH_REVISION 23
|
||||
#define ETHASH_DATASET_BYTES_INIT 1073741824U // 2**30
|
||||
#define ETHASH_DATASET_BYTES_GROWTH 8388608U // 2**23
|
||||
#define ETHASH_CACHE_BYTES_INIT 1073741824U // 2**24
|
||||
#define ETHASH_CACHE_BYTES_GROWTH 131072U // 2**17
|
||||
#define ETHASH_EPOCH_LENGTH 30000U
|
||||
#define ETHASH_MIX_BYTES 128
|
||||
#define ETHASH_HASH_BYTES 64
|
||||
#define ETHASH_DATASET_PARENTS 256
|
||||
#define ETHASH_CACHE_ROUNDS 3
|
||||
#define ETHASH_ACCESSES 64
|
||||
#define ETHASH_DAG_MAGIC_NUM_SIZE 8
|
||||
#define ETHASH_DAG_MAGIC_NUM 0xFEE1DEADBADDCAFE
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Type of a seedhash/blockhash e.t.c.
|
||||
typedef struct ethash_h256 { uint8_t b[32]; } ethash_h256_t;
|
||||
|
||||
// convenience macro to statically initialize an h256_t
|
||||
// usage:
|
||||
// ethash_h256_t a = ethash_h256_static_init(1, 2, 3, ... )
|
||||
// have to provide all 32 values. If you don't provide all the rest
|
||||
// will simply be unitialized (not guranteed to be 0)
|
||||
#define ethash_h256_static_init(...) \
|
||||
{ {__VA_ARGS__} }
|
||||
|
||||
struct ethash_light;
|
||||
typedef struct ethash_light* ethash_light_t;
|
||||
struct ethash_full;
|
||||
typedef struct ethash_full* ethash_full_t;
|
||||
typedef int(*ethash_callback_t)(unsigned);
|
||||
|
||||
typedef struct ethash_return_value {
|
||||
ethash_h256_t result;
|
||||
ethash_h256_t mix_hash;
|
||||
bool success;
|
||||
} ethash_return_value_t;
|
||||
|
||||
/**
|
||||
* Allocate and initialize a new ethash_light handler
|
||||
*
|
||||
* @param block_number The block number for which to create the handler
|
||||
* @return Newly allocated ethash_light handler or NULL in case of
|
||||
* ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes()
|
||||
*/
|
||||
ethash_light_t ethash_light_new(uint64_t block_number);
|
||||
/**
|
||||
*/
|
||||
bool ethash_compute_cache_nodes(
|
||||
void* nodes,
|
||||
uint64_t cache_size,
|
||||
ethash_h256_t const* seed
|
||||
);
|
||||
/**
|
||||
* Frees a previously allocated ethash_light handler
|
||||
* @param light The light handler to free
|
||||
*/
|
||||
void ethash_light_delete(ethash_light_t light);
|
||||
/**
|
||||
* Calculate the light client data
|
||||
*
|
||||
* @param light The light client handler
|
||||
* @param header_hash The header hash to pack into the mix
|
||||
* @param nonce The nonce to pack into the mix
|
||||
* @return an object of ethash_return_value_t holding the return values
|
||||
*/
|
||||
ethash_return_value_t ethash_light_compute(
|
||||
ethash_light_t light,
|
||||
ethash_h256_t const header_hash,
|
||||
uint64_t nonce
|
||||
);
|
||||
|
||||
/**
|
||||
* Allocate and initialize a new ethash_full handler
|
||||
*
|
||||
* @param light The light handler containing the cache.
|
||||
* @param callback A callback function with signature of @ref ethash_callback_t
|
||||
* It accepts an unsigned with which a progress of DAG calculation
|
||||
* can be displayed. If all goes well the callback should return 0.
|
||||
* If a non-zero value is returned then DAG generation will stop.
|
||||
* Be advised. A progress value of 100 means that DAG creation is
|
||||
* almost complete and that this function will soon return succesfully.
|
||||
* It does not mean that the function has already had a succesfull return.
|
||||
* @return Newly allocated ethash_full handler or NULL in case of
|
||||
* ERRNOMEM or invalid parameters used for @ref ethash_compute_full_data()
|
||||
*/
|
||||
ethash_full_t ethash_full_new(ethash_light_t light, ethash_callback_t callback);
|
||||
|
||||
/**
|
||||
* Frees a previously allocated ethash_full handler
|
||||
* @param full The light handler to free
|
||||
*/
|
||||
void ethash_full_delete(ethash_full_t full);
|
||||
/**
|
||||
* Calculate the full client data
|
||||
*
|
||||
* @param full The full client handler
|
||||
* @param header_hash The header hash to pack into the mix
|
||||
* @param nonce The nonce to pack into the mix
|
||||
* @return An object of ethash_return_value to hold the return value
|
||||
*/
|
||||
ethash_return_value_t ethash_full_compute(
|
||||
ethash_full_t full,
|
||||
ethash_h256_t const header_hash,
|
||||
uint64_t nonce
|
||||
);
|
||||
/**
|
||||
* Get a pointer to the full DAG data
|
||||
*/
|
||||
void const* ethash_full_dag(ethash_full_t full);
|
||||
/**
|
||||
* Get the size of the DAG data
|
||||
*/
|
||||
uint64_t ethash_full_dag_size(ethash_full_t full);
|
||||
|
||||
/**
|
||||
* Calculate the seedhash for a given epoch
|
||||
*/
|
||||
ethash_h256_t ethash_get_seedhash(uint64_t epoch);
|
||||
|
||||
/**
|
||||
* KeccakF800 for ProgPoW
|
||||
*/
|
||||
void ethash_keccakf800(uint32_t state[25]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
463
src/3rdparty/libethash/ethash_internal.c
vendored
463
src/3rdparty/libethash/ethash_internal.c
vendored
@@ -1,463 +0,0 @@
|
||||
/*
|
||||
This file is part of ethash.
|
||||
|
||||
ethash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ethash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file internal.c
|
||||
* @author Tim Hughes <tim@twistedfury.com>
|
||||
* @author Matthew Wampler-Doty
|
||||
* @date 2015
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "ethash.h"
|
||||
#include "fnv.h"
|
||||
#include "endian.h"
|
||||
#include "ethash_internal.h"
|
||||
#include "data_sizes.h"
|
||||
#include "base/crypto/sha3.h"
|
||||
|
||||
#if defined(_M_X64) || defined(__x86_64__) || defined(__SSE2__)
|
||||
#ifdef __GNUC__
|
||||
#include <x86intrin.h>
|
||||
#else
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#define kp_prefetch(x) _mm_prefetch((x), _MM_HINT_T0);
|
||||
#else
|
||||
#define kp_prefetch(x)
|
||||
#endif
|
||||
|
||||
#define SHA3_256(a, b, c) sha3_HashBuffer(256, SHA3_FLAGS_KECCAK, b, c, a, 32)
|
||||
#define SHA3_512(a, b, c) sha3_HashBuffer(512, SHA3_FLAGS_KECCAK, b, c, a, 64)
|
||||
|
||||
uint64_t ethash_get_datasize(uint64_t const block_number)
|
||||
{
|
||||
assert(block_number / ETHASH_EPOCH_LENGTH < 2048);
|
||||
return dag_sizes[block_number / ETHASH_EPOCH_LENGTH];
|
||||
}
|
||||
|
||||
uint64_t ethash_get_cachesize(uint64_t const block_number)
|
||||
{
|
||||
assert(block_number / ETHASH_EPOCH_LENGTH < 2048);
|
||||
return cache_sizes[block_number / ETHASH_EPOCH_LENGTH];
|
||||
}
|
||||
|
||||
// Follows Sergio's "STRICT MEMORY HARD HASHING FUNCTIONS" (2014)
|
||||
// https://bitslog.files.wordpress.com/2013/12/memohash-v0-3.pdf
|
||||
// SeqMemoHash(s, R, N)
|
||||
bool ethash_compute_cache_nodes(
|
||||
void* nodes_ptr,
|
||||
uint64_t cache_size,
|
||||
ethash_h256_t const* seed
|
||||
)
|
||||
{
|
||||
if (cache_size % sizeof(node) != 0) {
|
||||
return false;
|
||||
}
|
||||
uint32_t const num_nodes = (uint32_t) (cache_size / sizeof(node));
|
||||
|
||||
node* nodes = (node*)nodes_ptr;
|
||||
SHA3_512(nodes[0].bytes, (uint8_t*)seed, 32);
|
||||
|
||||
for (uint32_t i = 1; i != num_nodes; ++i) {
|
||||
SHA3_512(nodes[i].bytes, nodes[i - 1].bytes, 64);
|
||||
}
|
||||
|
||||
for (uint32_t j = 0; j != ETHASH_CACHE_ROUNDS; j++) {
|
||||
for (uint32_t i = 0; i != num_nodes; i++) {
|
||||
uint32_t const idx = nodes[i].words[0] % num_nodes;
|
||||
node data;
|
||||
data = nodes[(num_nodes - 1 + i) % num_nodes];
|
||||
for (uint32_t w = 0; w != NODE_WORDS; ++w) {
|
||||
data.words[w] ^= nodes[idx].words[w];
|
||||
}
|
||||
SHA3_512(nodes[i].bytes, data.bytes, sizeof(data));
|
||||
}
|
||||
}
|
||||
|
||||
// now perform endian conversion
|
||||
fix_endian_arr32(nodes->words, num_nodes * NODE_WORDS);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ethash_calculate_dag_item(
|
||||
node* const ret,
|
||||
uint32_t node_index,
|
||||
uint32_t num_parents,
|
||||
ethash_light_t const light
|
||||
)
|
||||
{
|
||||
uint32_t num_parent_nodes = (uint32_t) (light->cache_size / sizeof(node));
|
||||
node const* cache_nodes = (node const *) light->cache;
|
||||
node const* init = &cache_nodes[node_index % num_parent_nodes];
|
||||
memcpy(ret, init, sizeof(node));
|
||||
ret->words[0] ^= node_index;
|
||||
SHA3_512(ret->bytes, ret->bytes, sizeof(node));
|
||||
#if defined(_M_X64) && ENABLE_SSE
|
||||
__m128i const fnv_prime = _mm_set1_epi32(FNV_PRIME);
|
||||
__m128i xmm0 = ret->xmm[0];
|
||||
__m128i xmm1 = ret->xmm[1];
|
||||
__m128i xmm2 = ret->xmm[2];
|
||||
__m128i xmm3 = ret->xmm[3];
|
||||
#endif
|
||||
|
||||
for (uint32_t i = 0; i != num_parents; ++i) {
|
||||
uint32_t parent_index = fnv_hash(node_index ^ i, ret->words[i % NODE_WORDS]) % num_parent_nodes;
|
||||
node const *parent = &cache_nodes[parent_index];
|
||||
|
||||
#if defined(_M_X64) && ENABLE_SSE
|
||||
{
|
||||
xmm0 = _mm_mullo_epi32(xmm0, fnv_prime);
|
||||
xmm1 = _mm_mullo_epi32(xmm1, fnv_prime);
|
||||
xmm2 = _mm_mullo_epi32(xmm2, fnv_prime);
|
||||
xmm3 = _mm_mullo_epi32(xmm3, fnv_prime);
|
||||
xmm0 = _mm_xor_si128(xmm0, parent->xmm[0]);
|
||||
xmm1 = _mm_xor_si128(xmm1, parent->xmm[1]);
|
||||
xmm2 = _mm_xor_si128(xmm2, parent->xmm[2]);
|
||||
xmm3 = _mm_xor_si128(xmm3, parent->xmm[3]);
|
||||
|
||||
// have to write to ret as values are used to compute index
|
||||
ret->xmm[0] = xmm0;
|
||||
ret->xmm[1] = xmm1;
|
||||
ret->xmm[2] = xmm2;
|
||||
ret->xmm[3] = xmm3;
|
||||
}
|
||||
#else
|
||||
{
|
||||
for (unsigned w = 0; w != NODE_WORDS; ++w) {
|
||||
ret->words[w] = fnv_hash(ret->words[w], parent->words[w]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
SHA3_512(ret->bytes, ret->bytes, sizeof(node));
|
||||
}
|
||||
|
||||
static inline uint32_t fast_mod(uint64_t a, uint64_t d, uint64_t r, uint64_t i, uint64_t s)
|
||||
{
|
||||
const uint32_t q = ((a + i) * r) >> s;
|
||||
return a - q * d;
|
||||
}
|
||||
|
||||
void ethash_calculate_dag_item_opt(
|
||||
node* const ret,
|
||||
uint32_t node_index,
|
||||
uint32_t num_parents,
|
||||
ethash_light_t const light
|
||||
)
|
||||
{
|
||||
node const* cache_nodes = (node const*)light->cache;
|
||||
node const* init = &cache_nodes[fast_mod(node_index, light->num_parent_nodes, light->reciprocal, light->increment, light->shift)];
|
||||
memcpy(ret, init, sizeof(node));
|
||||
ret->words[0] ^= node_index;
|
||||
SHA3_512(ret->bytes, ret->bytes, sizeof(node));
|
||||
|
||||
for (uint32_t i = 0; i != num_parents; ++i) {
|
||||
uint32_t parent_index = fast_mod(fnv_hash(node_index ^ i, ret->words[i % NODE_WORDS]), light->num_parent_nodes, light->reciprocal, light->increment, light->shift);
|
||||
node const* parent = &cache_nodes[parent_index];
|
||||
for (unsigned w = 0; w != NODE_WORDS; ++w) {
|
||||
ret->words[w] = fnv_hash(ret->words[w], parent->words[w]);
|
||||
}
|
||||
}
|
||||
SHA3_512(ret->bytes, ret->bytes, sizeof(node));
|
||||
}
|
||||
|
||||
void ethash_calculate_dag_item4_opt(
|
||||
node* ret,
|
||||
uint32_t node_index,
|
||||
uint32_t num_parents,
|
||||
ethash_light_t const light
|
||||
)
|
||||
{
|
||||
node const* cache_nodes = (node const*)light->cache;
|
||||
|
||||
for (size_t i = 0; i < 4; ++i) {
|
||||
node const* init = &cache_nodes[fast_mod(node_index + i, light->num_parent_nodes, light->reciprocal, light->increment, light->shift)];
|
||||
memcpy(ret + i, init, sizeof(node));
|
||||
ret[i].words[0] ^= node_index + i;
|
||||
SHA3_512(ret[i].bytes, ret[i].bytes, sizeof(node));
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i != num_parents; ++i) {
|
||||
node const* parent[4];
|
||||
|
||||
for (uint32_t j = 0; j < 4; ++j) {
|
||||
const uint32_t parent_index = fast_mod(fnv_hash((node_index + j) ^ i, ret[j].words[i % NODE_WORDS]), light->num_parent_nodes, light->reciprocal, light->increment, light->shift);
|
||||
parent[j] = &cache_nodes[parent_index];
|
||||
kp_prefetch(parent[j]);
|
||||
}
|
||||
|
||||
for (unsigned w = 0; w != NODE_WORDS; ++w) ret[0].words[w] = fnv_hash(ret[0].words[w], parent[0]->words[w]);
|
||||
for (unsigned w = 0; w != NODE_WORDS; ++w) ret[1].words[w] = fnv_hash(ret[1].words[w], parent[1]->words[w]);
|
||||
for (unsigned w = 0; w != NODE_WORDS; ++w) ret[2].words[w] = fnv_hash(ret[2].words[w], parent[2]->words[w]);
|
||||
for (unsigned w = 0; w != NODE_WORDS; ++w) ret[3].words[w] = fnv_hash(ret[3].words[w], parent[3]->words[w]);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 4; ++i) {
|
||||
SHA3_512(ret[i].bytes, ret[i].bytes, sizeof(node));
|
||||
}
|
||||
}
|
||||
|
||||
bool ethash_compute_full_data(
|
||||
void* mem,
|
||||
uint64_t full_size,
|
||||
ethash_light_t const light,
|
||||
ethash_callback_t callback
|
||||
)
|
||||
{
|
||||
if (full_size % (sizeof(uint32_t) * MIX_WORDS) != 0 ||
|
||||
(full_size % sizeof(node)) != 0) {
|
||||
return false;
|
||||
}
|
||||
uint32_t const max_n = (uint32_t)(full_size / sizeof(node));
|
||||
node* full_nodes = (node*) mem;
|
||||
double const progress_change = 1.0f / max_n;
|
||||
double progress = 0.0f;
|
||||
// now compute full nodes
|
||||
for (uint32_t n = 0; n != max_n; ++n) {
|
||||
if (callback &&
|
||||
n % (max_n / 100) == 0 &&
|
||||
callback((unsigned int)(ceil(progress * 100.0f))) != 0) {
|
||||
|
||||
return false;
|
||||
}
|
||||
progress += progress_change;
|
||||
ethash_calculate_dag_item(&(full_nodes[n]), n, ETHASH_DATASET_PARENTS, light);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ethash_hash(
|
||||
ethash_return_value_t* ret,
|
||||
node const* full_nodes,
|
||||
ethash_light_t const light,
|
||||
uint64_t full_size,
|
||||
ethash_h256_t const header_hash,
|
||||
uint64_t const nonce
|
||||
)
|
||||
{
|
||||
if (full_size % MIX_WORDS != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// pack hash and nonce together into first 40 bytes of s_mix
|
||||
assert(sizeof(node) * 8 == 512);
|
||||
node s_mix[MIX_NODES + 1];
|
||||
memcpy(s_mix[0].bytes, &header_hash, 32);
|
||||
fix_endian64(s_mix[0].double_words[4], nonce);
|
||||
|
||||
// compute sha3-512 hash and replicate across mix
|
||||
SHA3_512(s_mix->bytes, s_mix->bytes, 40);
|
||||
fix_endian_arr32(s_mix[0].words, 16);
|
||||
|
||||
node* const mix = s_mix + 1;
|
||||
for (uint32_t w = 0; w != MIX_WORDS; ++w) {
|
||||
mix->words[w] = s_mix[0].words[w % NODE_WORDS];
|
||||
}
|
||||
|
||||
unsigned const page_size = sizeof(uint32_t) * MIX_WORDS;
|
||||
unsigned const num_full_pages = (unsigned) (full_size / page_size);
|
||||
|
||||
for (unsigned i = 0; i != ETHASH_ACCESSES; ++i) {
|
||||
uint32_t const index = fnv_hash(s_mix->words[0] ^ i, mix->words[i % MIX_WORDS]) % num_full_pages;
|
||||
|
||||
for (unsigned n = 0; n != MIX_NODES; ++n) {
|
||||
node const* dag_node;
|
||||
node tmp_node;
|
||||
if (full_nodes) {
|
||||
dag_node = &full_nodes[MIX_NODES * index + n];
|
||||
} else {
|
||||
ethash_calculate_dag_item(&tmp_node, index * MIX_NODES + n, ETHASH_DATASET_PARENTS, light);
|
||||
dag_node = &tmp_node;
|
||||
}
|
||||
|
||||
#if defined(_M_X64) && ENABLE_SSE
|
||||
{
|
||||
__m128i fnv_prime = _mm_set1_epi32(FNV_PRIME);
|
||||
__m128i xmm0 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[0]);
|
||||
__m128i xmm1 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[1]);
|
||||
__m128i xmm2 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[2]);
|
||||
__m128i xmm3 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[3]);
|
||||
mix[n].xmm[0] = _mm_xor_si128(xmm0, dag_node->xmm[0]);
|
||||
mix[n].xmm[1] = _mm_xor_si128(xmm1, dag_node->xmm[1]);
|
||||
mix[n].xmm[2] = _mm_xor_si128(xmm2, dag_node->xmm[2]);
|
||||
mix[n].xmm[3] = _mm_xor_si128(xmm3, dag_node->xmm[3]);
|
||||
}
|
||||
#else
|
||||
{
|
||||
for (unsigned w = 0; w != NODE_WORDS; ++w) {
|
||||
mix[n].words[w] = fnv_hash(mix[n].words[w], dag_node->words[w]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// compress mix
|
||||
for (uint32_t w = 0; w != MIX_WORDS; w += 4) {
|
||||
uint32_t reduction = mix->words[w + 0];
|
||||
reduction = reduction * FNV_PRIME ^ mix->words[w + 1];
|
||||
reduction = reduction * FNV_PRIME ^ mix->words[w + 2];
|
||||
reduction = reduction * FNV_PRIME ^ mix->words[w + 3];
|
||||
mix->words[w / 4] = reduction;
|
||||
}
|
||||
|
||||
fix_endian_arr32(mix->words, MIX_WORDS / 4);
|
||||
memcpy(&ret->mix_hash, mix->bytes, 32);
|
||||
// final Keccak hash
|
||||
SHA3_256(&ret->result, s_mix->bytes, 64 + 32); // Keccak-256(s + compressed_mix)
|
||||
return true;
|
||||
}
|
||||
|
||||
void ethash_quick_hash(
|
||||
ethash_h256_t* return_hash,
|
||||
ethash_h256_t const* header_hash,
|
||||
uint64_t nonce,
|
||||
ethash_h256_t const* mix_hash
|
||||
)
|
||||
{
|
||||
uint8_t buf[64 + 32];
|
||||
memcpy(buf, header_hash, 32);
|
||||
fix_endian64_same(nonce);
|
||||
memcpy(&(buf[32]), &nonce, 8);
|
||||
SHA3_512(buf, buf, 40);
|
||||
memcpy(&(buf[64]), mix_hash, 32);
|
||||
SHA3_256(return_hash, buf, 64 + 32);
|
||||
}
|
||||
|
||||
ethash_h256_t ethash_get_seedhash(uint64_t epoch)
|
||||
{
|
||||
ethash_h256_t ret;
|
||||
ethash_h256_reset(&ret);
|
||||
for (uint32_t i = 0; i < epoch; ++i)
|
||||
SHA3_256(&ret, (uint8_t*)&ret, 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ethash_quick_check_difficulty(
|
||||
ethash_h256_t const* header_hash,
|
||||
uint64_t const nonce,
|
||||
ethash_h256_t const* mix_hash,
|
||||
ethash_h256_t const* boundary
|
||||
)
|
||||
{
|
||||
ethash_h256_t return_hash;
|
||||
ethash_quick_hash(&return_hash, header_hash, nonce, mix_hash);
|
||||
return ethash_check_difficulty(&return_hash, boundary);
|
||||
}
|
||||
|
||||
ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t const* seed)
|
||||
{
|
||||
struct ethash_light *ret;
|
||||
ret = (struct ethash_light*)calloc(sizeof(*ret), 1);
|
||||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
ret->cache = malloc((size_t)cache_size);
|
||||
if (!ret->cache) {
|
||||
goto fail_free_light;
|
||||
}
|
||||
node* nodes = (node*)ret->cache;
|
||||
if (!ethash_compute_cache_nodes(nodes, cache_size, seed)) {
|
||||
goto fail_free_cache_mem;
|
||||
}
|
||||
ret->cache_size = cache_size;
|
||||
return ret;
|
||||
|
||||
fail_free_cache_mem:
|
||||
free(ret->cache);
|
||||
fail_free_light:
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ethash_light_t ethash_light_new(uint64_t block_number)
|
||||
{
|
||||
ethash_h256_t seedhash = ethash_get_seedhash(block_number / ETHASH_EPOCH_LENGTH);
|
||||
ethash_light_t ret;
|
||||
ret = ethash_light_new_internal(ethash_get_cachesize(block_number), &seedhash);
|
||||
ret->block_number = block_number;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ethash_light_delete(ethash_light_t light)
|
||||
{
|
||||
if (light->cache) {
|
||||
free(light->cache);
|
||||
}
|
||||
free(light);
|
||||
}
|
||||
|
||||
ethash_return_value_t ethash_light_compute_internal(
|
||||
ethash_light_t light,
|
||||
uint64_t full_size,
|
||||
ethash_h256_t const header_hash,
|
||||
uint64_t nonce
|
||||
)
|
||||
{
|
||||
ethash_return_value_t ret;
|
||||
ret.success = true;
|
||||
if (!ethash_hash(&ret, NULL, light, full_size, header_hash, nonce)) {
|
||||
ret.success = false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ethash_return_value_t ethash_light_compute(
|
||||
ethash_light_t light,
|
||||
ethash_h256_t const header_hash,
|
||||
uint64_t nonce
|
||||
)
|
||||
{
|
||||
uint64_t full_size = ethash_get_datasize(light->block_number);
|
||||
return ethash_light_compute_internal(light, full_size, header_hash, nonce);
|
||||
}
|
||||
|
||||
ethash_return_value_t ethash_full_compute(
|
||||
ethash_full_t full,
|
||||
ethash_h256_t const header_hash,
|
||||
uint64_t nonce
|
||||
)
|
||||
{
|
||||
ethash_return_value_t ret;
|
||||
ret.success = true;
|
||||
if (!ethash_hash(
|
||||
&ret,
|
||||
(node const*)full->data,
|
||||
NULL,
|
||||
full->file_size,
|
||||
header_hash,
|
||||
nonce)) {
|
||||
ret.success = false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void const* ethash_full_dag(ethash_full_t full)
|
||||
{
|
||||
return full->data;
|
||||
}
|
||||
|
||||
uint64_t ethash_full_dag_size(ethash_full_t full)
|
||||
{
|
||||
return full->file_size;
|
||||
}
|
||||
199
src/3rdparty/libethash/ethash_internal.h
vendored
199
src/3rdparty/libethash/ethash_internal.h
vendored
@@ -1,199 +0,0 @@
|
||||
#pragma once
|
||||
#include "endian.h"
|
||||
#include "ethash.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define ENABLE_SSE 0
|
||||
|
||||
#if defined(_M_X64) && ENABLE_SSE
|
||||
#include <smmintrin.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// compile time settings
|
||||
#define NODE_WORDS (64/4)
|
||||
#define MIX_WORDS (ETHASH_MIX_BYTES/4)
|
||||
#define MIX_NODES (MIX_WORDS / NODE_WORDS)
|
||||
#include <stdint.h>
|
||||
|
||||
typedef union node {
|
||||
uint8_t bytes[NODE_WORDS * 4];
|
||||
uint32_t words[NODE_WORDS];
|
||||
uint64_t double_words[NODE_WORDS / 2];
|
||||
|
||||
#if defined(_M_X64) && ENABLE_SSE
|
||||
__m128i xmm[NODE_WORDS/4];
|
||||
#endif
|
||||
|
||||
} node;
|
||||
|
||||
static inline uint8_t ethash_h256_get(ethash_h256_t const* hash, unsigned int i)
|
||||
{
|
||||
return hash->b[i];
|
||||
}
|
||||
|
||||
static inline void ethash_h256_set(ethash_h256_t* hash, unsigned int i, uint8_t v)
|
||||
{
|
||||
hash->b[i] = v;
|
||||
}
|
||||
|
||||
static inline void ethash_h256_reset(ethash_h256_t* hash)
|
||||
{
|
||||
memset(hash, 0, 32);
|
||||
}
|
||||
|
||||
// Returns if hash is less than or equal to boundary (2^256/difficulty)
|
||||
static inline bool ethash_check_difficulty(
|
||||
ethash_h256_t const* hash,
|
||||
ethash_h256_t const* boundary
|
||||
)
|
||||
{
|
||||
// Boundary is big endian
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if (ethash_h256_get(hash, i) == ethash_h256_get(boundary, i)) {
|
||||
continue;
|
||||
}
|
||||
return ethash_h256_get(hash, i) < ethash_h256_get(boundary, i);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Difficulty quick check for POW preverification
|
||||
*
|
||||
* @param header_hash The hash of the header
|
||||
* @param nonce The block's nonce
|
||||
* @param mix_hash The mix digest hash
|
||||
* @param boundary The boundary is defined as (2^256 / difficulty)
|
||||
* @return true for succesful pre-verification and false otherwise
|
||||
*/
|
||||
bool ethash_quick_check_difficulty(
|
||||
ethash_h256_t const* header_hash,
|
||||
uint64_t const nonce,
|
||||
ethash_h256_t const* mix_hash,
|
||||
ethash_h256_t const* boundary
|
||||
);
|
||||
|
||||
struct ethash_light {
|
||||
void* cache;
|
||||
uint64_t cache_size;
|
||||
uint64_t block_number;
|
||||
|
||||
// Used for fast division
|
||||
uint32_t num_parent_nodes;
|
||||
uint32_t reciprocal;
|
||||
uint32_t increment;
|
||||
uint32_t shift;
|
||||
};
|
||||
|
||||
/**
|
||||
* Allocate and initialize a new ethash_light handler. Internal version
|
||||
*
|
||||
* @param cache_size The size of the cache in bytes
|
||||
* @param seed Block seedhash to be used during the computation of the
|
||||
* cache nodes
|
||||
* @return Newly allocated ethash_light handler or NULL in case of
|
||||
* ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes()
|
||||
*/
|
||||
ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t const* seed);
|
||||
|
||||
/**
|
||||
* Calculate the light client data. Internal version.
|
||||
*
|
||||
* @param light The light client handler
|
||||
* @param full_size The size of the full data in bytes.
|
||||
* @param header_hash The header hash to pack into the mix
|
||||
* @param nonce The nonce to pack into the mix
|
||||
* @return The resulting hash.
|
||||
*/
|
||||
ethash_return_value_t ethash_light_compute_internal(
|
||||
ethash_light_t light,
|
||||
uint64_t full_size,
|
||||
ethash_h256_t const header_hash,
|
||||
uint64_t nonce
|
||||
);
|
||||
|
||||
struct ethash_full {
|
||||
FILE* file;
|
||||
uint64_t file_size;
|
||||
node* data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Allocate and initialize a new ethash_full handler. Internal version.
|
||||
*
|
||||
* @param dirname The directory in which to put the DAG file.
|
||||
* @param seedhash The seed hash of the block. Used in the DAG file naming.
|
||||
* @param full_size The size of the full data in bytes.
|
||||
* @param cache A cache object to use that was allocated with @ref ethash_cache_new().
|
||||
* Iff this function succeeds the ethash_full_t will take memory
|
||||
* memory ownership of the cache and free it at deletion. If
|
||||
* not then the user still has to handle freeing of the cache himself.
|
||||
* @param callback A callback function with signature of @ref ethash_callback_t
|
||||
* It accepts an unsigned with which a progress of DAG calculation
|
||||
* can be displayed. If all goes well the callback should return 0.
|
||||
* If a non-zero value is returned then DAG generation will stop.
|
||||
* @return Newly allocated ethash_full handler or NULL in case of
|
||||
* ERRNOMEM or invalid parameters used for @ref ethash_compute_full_data()
|
||||
*/
|
||||
ethash_full_t ethash_full_new_internal(
|
||||
char const* dirname,
|
||||
ethash_h256_t const seed_hash,
|
||||
uint64_t full_size,
|
||||
ethash_light_t const light,
|
||||
ethash_callback_t callback
|
||||
);
|
||||
|
||||
void ethash_calculate_dag_item(
|
||||
node* const ret,
|
||||
uint32_t node_index,
|
||||
uint32_t num_parents,
|
||||
ethash_light_t const cache
|
||||
);
|
||||
|
||||
void ethash_calculate_dag_item_opt(
|
||||
node* const ret,
|
||||
uint32_t node_index,
|
||||
uint32_t num_parents,
|
||||
ethash_light_t const cache
|
||||
);
|
||||
|
||||
void ethash_calculate_dag_item4_opt(
|
||||
node* ret,
|
||||
uint32_t node_index,
|
||||
uint32_t num_parents,
|
||||
ethash_light_t const cache
|
||||
);
|
||||
|
||||
void ethash_quick_hash(
|
||||
ethash_h256_t* return_hash,
|
||||
ethash_h256_t const* header_hash,
|
||||
const uint64_t nonce,
|
||||
ethash_h256_t const* mix_hash
|
||||
);
|
||||
|
||||
uint64_t ethash_get_datasize(uint64_t const block_number);
|
||||
uint64_t ethash_get_cachesize(uint64_t const block_number);
|
||||
|
||||
/**
|
||||
* Compute the memory data for a full node's memory
|
||||
*
|
||||
* @param mem A pointer to an ethash full's memory
|
||||
* @param full_size The size of the full data in bytes
|
||||
* @param cache A cache object to use in the calculation
|
||||
* @param callback The callback function. Check @ref ethash_full_new() for details.
|
||||
* @return true if all went fine and false for invalid parameters
|
||||
*/
|
||||
bool ethash_compute_full_data(
|
||||
void* mem,
|
||||
uint64_t full_size,
|
||||
ethash_light_t const light,
|
||||
ethash_callback_t callback
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
42
src/3rdparty/libethash/fnv.h
vendored
42
src/3rdparty/libethash/fnv.h
vendored
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file fnv.h
|
||||
* @author Matthew Wampler-Doty <negacthulhu@gmail.com>
|
||||
* @date 2015
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define FNV_PRIME 0x01000193
|
||||
|
||||
/* The FNV-1 spec multiplies the prime with the input one byte (octet) in turn.
|
||||
We instead multiply it with the full 32-bit input.
|
||||
This gives a different result compared to a canonical FNV-1 implementation.
|
||||
*/
|
||||
static inline uint32_t fnv_hash(uint32_t const x, uint32_t const y)
|
||||
{
|
||||
return x * FNV_PRIME ^ y;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
253
src/3rdparty/libethash/keccakf800.c
vendored
253
src/3rdparty/libethash/keccakf800.c
vendored
@@ -1,253 +0,0 @@
|
||||
/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
|
||||
* Copyright 2018-2019 Pawel Bylica.
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static uint32_t rol(uint32_t x, unsigned s)
|
||||
{
|
||||
return (x << s) | (x >> (32 - s));
|
||||
}
|
||||
|
||||
static const uint32_t round_constants[22] = {
|
||||
0x00000001,
|
||||
0x00008082,
|
||||
0x0000808A,
|
||||
0x80008000,
|
||||
0x0000808B,
|
||||
0x80000001,
|
||||
0x80008081,
|
||||
0x00008009,
|
||||
0x0000008A,
|
||||
0x00000088,
|
||||
0x80008009,
|
||||
0x8000000A,
|
||||
0x8000808B,
|
||||
0x0000008B,
|
||||
0x00008089,
|
||||
0x00008003,
|
||||
0x00008002,
|
||||
0x00000080,
|
||||
0x0000800A,
|
||||
0x8000000A,
|
||||
0x80008081,
|
||||
0x00008080,
|
||||
};
|
||||
|
||||
void ethash_keccakf800(uint32_t state[25])
|
||||
{
|
||||
/* The implementation directly translated from ethash_keccakf1600. */
|
||||
|
||||
int round;
|
||||
|
||||
uint32_t Aba, Abe, Abi, Abo, Abu;
|
||||
uint32_t Aga, Age, Agi, Ago, Agu;
|
||||
uint32_t Aka, Ake, Aki, Ako, Aku;
|
||||
uint32_t Ama, Ame, Ami, Amo, Amu;
|
||||
uint32_t Asa, Ase, Asi, Aso, Asu;
|
||||
|
||||
uint32_t Eba, Ebe, Ebi, Ebo, Ebu;
|
||||
uint32_t Ega, Ege, Egi, Ego, Egu;
|
||||
uint32_t Eka, Eke, Eki, Eko, Eku;
|
||||
uint32_t Ema, Eme, Emi, Emo, Emu;
|
||||
uint32_t Esa, Ese, Esi, Eso, Esu;
|
||||
|
||||
uint32_t Ba, Be, Bi, Bo, Bu;
|
||||
|
||||
uint32_t Da, De, Di, Do, Du;
|
||||
|
||||
Aba = state[0];
|
||||
Abe = state[1];
|
||||
Abi = state[2];
|
||||
Abo = state[3];
|
||||
Abu = state[4];
|
||||
Aga = state[5];
|
||||
Age = state[6];
|
||||
Agi = state[7];
|
||||
Ago = state[8];
|
||||
Agu = state[9];
|
||||
Aka = state[10];
|
||||
Ake = state[11];
|
||||
Aki = state[12];
|
||||
Ako = state[13];
|
||||
Aku = state[14];
|
||||
Ama = state[15];
|
||||
Ame = state[16];
|
||||
Ami = state[17];
|
||||
Amo = state[18];
|
||||
Amu = state[19];
|
||||
Asa = state[20];
|
||||
Ase = state[21];
|
||||
Asi = state[22];
|
||||
Aso = state[23];
|
||||
Asu = state[24];
|
||||
|
||||
for (round = 0; round < 22; round += 2)
|
||||
{
|
||||
/* Round (round + 0): Axx -> Exx */
|
||||
|
||||
Ba = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
|
||||
Be = Abe ^ Age ^ Ake ^ Ame ^ Ase;
|
||||
Bi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
|
||||
Bo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
|
||||
Bu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
|
||||
|
||||
Da = Bu ^ rol(Be, 1);
|
||||
De = Ba ^ rol(Bi, 1);
|
||||
Di = Be ^ rol(Bo, 1);
|
||||
Do = Bi ^ rol(Bu, 1);
|
||||
Du = Bo ^ rol(Ba, 1);
|
||||
|
||||
Ba = Aba ^ Da;
|
||||
Be = rol(Age ^ De, 12);
|
||||
Bi = rol(Aki ^ Di, 11);
|
||||
Bo = rol(Amo ^ Do, 21);
|
||||
Bu = rol(Asu ^ Du, 14);
|
||||
Eba = Ba ^ (~Be & Bi) ^ round_constants[round];
|
||||
Ebe = Be ^ (~Bi & Bo);
|
||||
Ebi = Bi ^ (~Bo & Bu);
|
||||
Ebo = Bo ^ (~Bu & Ba);
|
||||
Ebu = Bu ^ (~Ba & Be);
|
||||
|
||||
Ba = rol(Abo ^ Do, 28);
|
||||
Be = rol(Agu ^ Du, 20);
|
||||
Bi = rol(Aka ^ Da, 3);
|
||||
Bo = rol(Ame ^ De, 13);
|
||||
Bu = rol(Asi ^ Di, 29);
|
||||
Ega = Ba ^ (~Be & Bi);
|
||||
Ege = Be ^ (~Bi & Bo);
|
||||
Egi = Bi ^ (~Bo & Bu);
|
||||
Ego = Bo ^ (~Bu & Ba);
|
||||
Egu = Bu ^ (~Ba & Be);
|
||||
|
||||
Ba = rol(Abe ^ De, 1);
|
||||
Be = rol(Agi ^ Di, 6);
|
||||
Bi = rol(Ako ^ Do, 25);
|
||||
Bo = rol(Amu ^ Du, 8);
|
||||
Bu = rol(Asa ^ Da, 18);
|
||||
Eka = Ba ^ (~Be & Bi);
|
||||
Eke = Be ^ (~Bi & Bo);
|
||||
Eki = Bi ^ (~Bo & Bu);
|
||||
Eko = Bo ^ (~Bu & Ba);
|
||||
Eku = Bu ^ (~Ba & Be);
|
||||
|
||||
Ba = rol(Abu ^ Du, 27);
|
||||
Be = rol(Aga ^ Da, 4);
|
||||
Bi = rol(Ake ^ De, 10);
|
||||
Bo = rol(Ami ^ Di, 15);
|
||||
Bu = rol(Aso ^ Do, 24);
|
||||
Ema = Ba ^ (~Be & Bi);
|
||||
Eme = Be ^ (~Bi & Bo);
|
||||
Emi = Bi ^ (~Bo & Bu);
|
||||
Emo = Bo ^ (~Bu & Ba);
|
||||
Emu = Bu ^ (~Ba & Be);
|
||||
|
||||
Ba = rol(Abi ^ Di, 30);
|
||||
Be = rol(Ago ^ Do, 23);
|
||||
Bi = rol(Aku ^ Du, 7);
|
||||
Bo = rol(Ama ^ Da, 9);
|
||||
Bu = rol(Ase ^ De, 2);
|
||||
Esa = Ba ^ (~Be & Bi);
|
||||
Ese = Be ^ (~Bi & Bo);
|
||||
Esi = Bi ^ (~Bo & Bu);
|
||||
Eso = Bo ^ (~Bu & Ba);
|
||||
Esu = Bu ^ (~Ba & Be);
|
||||
|
||||
|
||||
/* Round (round + 1): Exx -> Axx */
|
||||
|
||||
Ba = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
|
||||
Be = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
|
||||
Bi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
|
||||
Bo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
|
||||
Bu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
|
||||
|
||||
Da = Bu ^ rol(Be, 1);
|
||||
De = Ba ^ rol(Bi, 1);
|
||||
Di = Be ^ rol(Bo, 1);
|
||||
Do = Bi ^ rol(Bu, 1);
|
||||
Du = Bo ^ rol(Ba, 1);
|
||||
|
||||
Ba = Eba ^ Da;
|
||||
Be = rol(Ege ^ De, 12);
|
||||
Bi = rol(Eki ^ Di, 11);
|
||||
Bo = rol(Emo ^ Do, 21);
|
||||
Bu = rol(Esu ^ Du, 14);
|
||||
Aba = Ba ^ (~Be & Bi) ^ round_constants[round + 1];
|
||||
Abe = Be ^ (~Bi & Bo);
|
||||
Abi = Bi ^ (~Bo & Bu);
|
||||
Abo = Bo ^ (~Bu & Ba);
|
||||
Abu = Bu ^ (~Ba & Be);
|
||||
|
||||
Ba = rol(Ebo ^ Do, 28);
|
||||
Be = rol(Egu ^ Du, 20);
|
||||
Bi = rol(Eka ^ Da, 3);
|
||||
Bo = rol(Eme ^ De, 13);
|
||||
Bu = rol(Esi ^ Di, 29);
|
||||
Aga = Ba ^ (~Be & Bi);
|
||||
Age = Be ^ (~Bi & Bo);
|
||||
Agi = Bi ^ (~Bo & Bu);
|
||||
Ago = Bo ^ (~Bu & Ba);
|
||||
Agu = Bu ^ (~Ba & Be);
|
||||
|
||||
Ba = rol(Ebe ^ De, 1);
|
||||
Be = rol(Egi ^ Di, 6);
|
||||
Bi = rol(Eko ^ Do, 25);
|
||||
Bo = rol(Emu ^ Du, 8);
|
||||
Bu = rol(Esa ^ Da, 18);
|
||||
Aka = Ba ^ (~Be & Bi);
|
||||
Ake = Be ^ (~Bi & Bo);
|
||||
Aki = Bi ^ (~Bo & Bu);
|
||||
Ako = Bo ^ (~Bu & Ba);
|
||||
Aku = Bu ^ (~Ba & Be);
|
||||
|
||||
Ba = rol(Ebu ^ Du, 27);
|
||||
Be = rol(Ega ^ Da, 4);
|
||||
Bi = rol(Eke ^ De, 10);
|
||||
Bo = rol(Emi ^ Di, 15);
|
||||
Bu = rol(Eso ^ Do, 24);
|
||||
Ama = Ba ^ (~Be & Bi);
|
||||
Ame = Be ^ (~Bi & Bo);
|
||||
Ami = Bi ^ (~Bo & Bu);
|
||||
Amo = Bo ^ (~Bu & Ba);
|
||||
Amu = Bu ^ (~Ba & Be);
|
||||
|
||||
Ba = rol(Ebi ^ Di, 30);
|
||||
Be = rol(Ego ^ Do, 23);
|
||||
Bi = rol(Eku ^ Du, 7);
|
||||
Bo = rol(Ema ^ Da, 9);
|
||||
Bu = rol(Ese ^ De, 2);
|
||||
Asa = Ba ^ (~Be & Bi);
|
||||
Ase = Be ^ (~Bi & Bo);
|
||||
Asi = Bi ^ (~Bo & Bu);
|
||||
Aso = Bo ^ (~Bu & Ba);
|
||||
Asu = Bu ^ (~Ba & Be);
|
||||
}
|
||||
|
||||
state[0] = Aba;
|
||||
state[1] = Abe;
|
||||
state[2] = Abi;
|
||||
state[3] = Abo;
|
||||
state[4] = Abu;
|
||||
state[5] = Aga;
|
||||
state[6] = Age;
|
||||
state[7] = Agi;
|
||||
state[8] = Ago;
|
||||
state[9] = Agu;
|
||||
state[10] = Aka;
|
||||
state[11] = Ake;
|
||||
state[12] = Aki;
|
||||
state[13] = Ako;
|
||||
state[14] = Aku;
|
||||
state[15] = Ama;
|
||||
state[16] = Ame;
|
||||
state[17] = Ami;
|
||||
state[18] = Amo;
|
||||
state[19] = Amu;
|
||||
state[20] = Asa;
|
||||
state[21] = Ase;
|
||||
state[22] = Asi;
|
||||
state[23] = Aso;
|
||||
state[24] = Asu;
|
||||
}
|
||||
22
src/3rdparty/llhttp/LICENSE-MIT
vendored
22
src/3rdparty/llhttp/LICENSE-MIT
vendored
@@ -1,22 +0,0 @@
|
||||
This software is licensed under the MIT License.
|
||||
|
||||
Copyright Fedor Indutny, 2018.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
135
src/3rdparty/llhttp/README.md
vendored
135
src/3rdparty/llhttp/README.md
vendored
@@ -1,135 +0,0 @@
|
||||
# llhttp
|
||||
[](https://github.com/nodejs/llhttp/actions?query=workflow%3ACI)
|
||||
|
||||
Port of [http_parser][0] to [llparse][1].
|
||||
|
||||
## Why?
|
||||
|
||||
Let's face it, [http_parser][0] is practically unmaintainable. Even
|
||||
introduction of a single new method results in a significant code churn.
|
||||
|
||||
This project aims to:
|
||||
|
||||
* Make it maintainable
|
||||
* Verifiable
|
||||
* Improving benchmarks where possible
|
||||
|
||||
More details in [Fedor Indutny's talk at JSConf EU 2019](https://youtu.be/x3k_5Mi66sY)
|
||||
|
||||
## How?
|
||||
|
||||
Over time, different approaches for improving [http_parser][0]'s code base
|
||||
were tried. However, all of them failed due to resulting significant performance
|
||||
degradation.
|
||||
|
||||
This project is a port of [http_parser][0] to TypeScript. [llparse][1] is used
|
||||
to generate the output C source file, which could be compiled and
|
||||
linked with the embedder's program (like [Node.js][7]).
|
||||
|
||||
## Performance
|
||||
|
||||
So far llhttp outperforms http_parser:
|
||||
|
||||
| | input size | bandwidth | reqs/sec | time |
|
||||
|:----------------|-----------:|-------------:|-----------:|--------:|
|
||||
| **llhttp** | 8192.00 mb | 1777.24 mb/s | 3583799.39 req/sec | 4.61 s |
|
||||
| **http_parser** | 8192.00 mb | 694.66 mb/s | 1406180.33 req/sec | 11.79 s |
|
||||
|
||||
llhttp is faster by approximately **156%**.
|
||||
|
||||
## Maintenance
|
||||
|
||||
llhttp project has about 1400 lines of TypeScript code describing the parser
|
||||
itself and around 450 lines of C code and headers providing the helper methods.
|
||||
The whole [http_parser][0] is implemented in approximately 2500 lines of C, and
|
||||
436 lines of headers.
|
||||
|
||||
All optimizations and multi-character matching in llhttp are generated
|
||||
automatically, and thus doesn't add any extra maintenance cost. On the contrary,
|
||||
most of http_parser's code is hand-optimized and unrolled. Instead describing
|
||||
"how" it should parse the HTTP requests/responses, a maintainer should
|
||||
implement the new features in [http_parser][0] cautiously, considering
|
||||
possible performance degradation and manually optimizing the new code.
|
||||
|
||||
## Verification
|
||||
|
||||
The state machine graph is encoded explicitly in llhttp. The [llparse][1]
|
||||
automatically checks the graph for absence of loops and correct reporting of the
|
||||
input ranges (spans) like header names and values. In the future, additional
|
||||
checks could be performed to get even stricter verification of the llhttp.
|
||||
|
||||
## Usage
|
||||
|
||||
```C
|
||||
#include "llhttp.h"
|
||||
|
||||
llhttp_t parser;
|
||||
llhttp_settings_t settings;
|
||||
|
||||
/* Initialize user callbacks and settings */
|
||||
llhttp_settings_init(&settings);
|
||||
|
||||
/* Set user callback */
|
||||
settings.on_message_complete = handle_on_message_complete;
|
||||
|
||||
/* Initialize the parser in HTTP_BOTH mode, meaning that it will select between
|
||||
* HTTP_REQUEST and HTTP_RESPONSE parsing automatically while reading the first
|
||||
* input.
|
||||
*/
|
||||
llhttp_init(&parser, HTTP_BOTH, &settings);
|
||||
|
||||
/* Parse request! */
|
||||
const char* request = "GET / HTTP/1.1\r\n\r\n";
|
||||
int request_len = strlen(request);
|
||||
|
||||
enum llhttp_errno err = llhttp_execute(&parser, request, request_len);
|
||||
if (err == HPE_OK) {
|
||||
/* Successfully parsed! */
|
||||
} else {
|
||||
fprintf(stderr, "Parse error: %s %s\n", llhttp_errno_name(err),
|
||||
parser.reason);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Bindings to other languages
|
||||
|
||||
* Python: [pallas/pyllhttp][8]
|
||||
* Ruby: [metabahn/llhttp][9]
|
||||
|
||||
#### LICENSE
|
||||
|
||||
This software is licensed under the MIT License.
|
||||
|
||||
Copyright Fedor Indutny, 2018.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
[0]: https://github.com/nodejs/http-parser
|
||||
[1]: https://github.com/nodejs/llparse
|
||||
[2]: https://en.wikipedia.org/wiki/Register_allocation#Spilling
|
||||
[3]: https://en.wikipedia.org/wiki/Tail_call
|
||||
[4]: https://llvm.org/docs/LangRef.html
|
||||
[5]: https://llvm.org/docs/LangRef.html#call-instruction
|
||||
[6]: https://clang.llvm.org/
|
||||
[7]: https://github.com/nodejs/node
|
||||
[8]: https://github.com/pallas/pyllhttp
|
||||
[9]: https://github.com/metabahn/llhttp
|
||||
348
src/3rdparty/llhttp/api.c
vendored
348
src/3rdparty/llhttp/api.c
vendored
@@ -1,348 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "llhttp.h"
|
||||
|
||||
#define CALLBACK_MAYBE(PARSER, NAME, ...) \
|
||||
do { \
|
||||
const llhttp_settings_t* settings; \
|
||||
settings = (const llhttp_settings_t*) (PARSER)->settings; \
|
||||
if (settings == NULL || settings->NAME == NULL) { \
|
||||
err = 0; \
|
||||
break; \
|
||||
} \
|
||||
err = settings->NAME(__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
void llhttp_init(llhttp_t* parser, llhttp_type_t type,
|
||||
const llhttp_settings_t* settings) {
|
||||
llhttp__internal_init(parser);
|
||||
|
||||
parser->type = type;
|
||||
parser->settings = (void*) settings;
|
||||
}
|
||||
|
||||
|
||||
#if defined(__wasm__)
|
||||
|
||||
extern int wasm_on_message_begin(llhttp_t * p);
|
||||
extern int wasm_on_url(llhttp_t* p, const char* at, size_t length);
|
||||
extern int wasm_on_status(llhttp_t* p, const char* at, size_t length);
|
||||
extern int wasm_on_header_field(llhttp_t* p, const char* at, size_t length);
|
||||
extern int wasm_on_header_value(llhttp_t* p, const char* at, size_t length);
|
||||
extern int wasm_on_headers_complete(llhttp_t * p);
|
||||
extern int wasm_on_body(llhttp_t* p, const char* at, size_t length);
|
||||
extern int wasm_on_message_complete(llhttp_t * p);
|
||||
|
||||
const llhttp_settings_t wasm_settings = {
|
||||
wasm_on_message_begin,
|
||||
wasm_on_url,
|
||||
wasm_on_status,
|
||||
wasm_on_header_field,
|
||||
wasm_on_header_value,
|
||||
wasm_on_headers_complete,
|
||||
wasm_on_body,
|
||||
wasm_on_message_complete,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
llhttp_t* llhttp_alloc(llhttp_type_t type) {
|
||||
llhttp_t* parser = malloc(sizeof(llhttp_t));
|
||||
llhttp_init(parser, type, &wasm_settings);
|
||||
return parser;
|
||||
}
|
||||
|
||||
void llhttp_free(llhttp_t* parser) {
|
||||
free(parser);
|
||||
}
|
||||
|
||||
/* Some getters required to get stuff from the parser */
|
||||
|
||||
uint8_t llhttp_get_type(llhttp_t* parser) {
|
||||
return parser->type;
|
||||
}
|
||||
|
||||
uint8_t llhttp_get_http_major(llhttp_t* parser) {
|
||||
return parser->http_major;
|
||||
}
|
||||
|
||||
uint8_t llhttp_get_http_minor(llhttp_t* parser) {
|
||||
return parser->http_minor;
|
||||
}
|
||||
|
||||
uint8_t llhttp_get_method(llhttp_t* parser) {
|
||||
return parser->method;
|
||||
}
|
||||
|
||||
int llhttp_get_status_code(llhttp_t* parser) {
|
||||
return parser->status_code;
|
||||
}
|
||||
|
||||
uint8_t llhttp_get_upgrade(llhttp_t* parser) {
|
||||
return parser->upgrade;
|
||||
}
|
||||
|
||||
#endif // defined(__wasm__)
|
||||
|
||||
|
||||
void llhttp_reset(llhttp_t* parser) {
|
||||
llhttp_type_t type = parser->type;
|
||||
const llhttp_settings_t* settings = parser->settings;
|
||||
void* data = parser->data;
|
||||
uint8_t lenient_flags = parser->lenient_flags;
|
||||
|
||||
llhttp__internal_init(parser);
|
||||
|
||||
parser->type = type;
|
||||
parser->settings = (void*) settings;
|
||||
parser->data = data;
|
||||
parser->lenient_flags = lenient_flags;
|
||||
}
|
||||
|
||||
|
||||
llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len) {
|
||||
return llhttp__internal_execute(parser, data, data + len);
|
||||
}
|
||||
|
||||
|
||||
void llhttp_settings_init(llhttp_settings_t* settings) {
|
||||
memset(settings, 0, sizeof(*settings));
|
||||
}
|
||||
|
||||
|
||||
llhttp_errno_t llhttp_finish(llhttp_t* parser) {
|
||||
int err;
|
||||
|
||||
/* We're in an error state. Don't bother doing anything. */
|
||||
if (parser->error != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (parser->finish) {
|
||||
case HTTP_FINISH_SAFE_WITH_CB:
|
||||
CALLBACK_MAYBE(parser, on_message_complete, parser);
|
||||
if (err != HPE_OK) return err;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
case HTTP_FINISH_SAFE:
|
||||
return HPE_OK;
|
||||
case HTTP_FINISH_UNSAFE:
|
||||
parser->reason = "Invalid EOF state";
|
||||
return HPE_INVALID_EOF_STATE;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void llhttp_pause(llhttp_t* parser) {
|
||||
if (parser->error != HPE_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
parser->error = HPE_PAUSED;
|
||||
parser->reason = "Paused";
|
||||
}
|
||||
|
||||
|
||||
void llhttp_resume(llhttp_t* parser) {
|
||||
if (parser->error != HPE_PAUSED) {
|
||||
return;
|
||||
}
|
||||
|
||||
parser->error = 0;
|
||||
}
|
||||
|
||||
|
||||
void llhttp_resume_after_upgrade(llhttp_t* parser) {
|
||||
if (parser->error != HPE_PAUSED_UPGRADE) {
|
||||
return;
|
||||
}
|
||||
|
||||
parser->error = 0;
|
||||
}
|
||||
|
||||
|
||||
llhttp_errno_t llhttp_get_errno(const llhttp_t* parser) {
|
||||
return parser->error;
|
||||
}
|
||||
|
||||
|
||||
const char* llhttp_get_error_reason(const llhttp_t* parser) {
|
||||
return parser->reason;
|
||||
}
|
||||
|
||||
|
||||
void llhttp_set_error_reason(llhttp_t* parser, const char* reason) {
|
||||
parser->reason = reason;
|
||||
}
|
||||
|
||||
|
||||
const char* llhttp_get_error_pos(const llhttp_t* parser) {
|
||||
return parser->error_pos;
|
||||
}
|
||||
|
||||
|
||||
const char* llhttp_errno_name(llhttp_errno_t err) {
|
||||
#define HTTP_ERRNO_GEN(CODE, NAME, _) case HPE_##NAME: return "HPE_" #NAME;
|
||||
switch (err) {
|
||||
HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
|
||||
default: abort();
|
||||
}
|
||||
#undef HTTP_ERRNO_GEN
|
||||
}
|
||||
|
||||
|
||||
const char* llhttp_method_name(llhttp_method_t method) {
|
||||
#define HTTP_METHOD_GEN(NUM, NAME, STRING) case HTTP_##NAME: return #STRING;
|
||||
switch (method) {
|
||||
HTTP_METHOD_MAP(HTTP_METHOD_GEN)
|
||||
default: abort();
|
||||
}
|
||||
#undef HTTP_METHOD_GEN
|
||||
}
|
||||
|
||||
|
||||
void llhttp_set_lenient_headers(llhttp_t* parser, int enabled) {
|
||||
if (enabled) {
|
||||
parser->lenient_flags |= LENIENT_HEADERS;
|
||||
} else {
|
||||
parser->lenient_flags &= ~LENIENT_HEADERS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled) {
|
||||
if (enabled) {
|
||||
parser->lenient_flags |= LENIENT_CHUNKED_LENGTH;
|
||||
} else {
|
||||
parser->lenient_flags &= ~LENIENT_CHUNKED_LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled) {
|
||||
if (enabled) {
|
||||
parser->lenient_flags |= LENIENT_KEEP_ALIVE;
|
||||
} else {
|
||||
parser->lenient_flags &= ~LENIENT_KEEP_ALIVE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Callbacks */
|
||||
|
||||
|
||||
int llhttp__on_message_begin(llhttp_t* s, const char* p, const char* endp) {
|
||||
int err;
|
||||
CALLBACK_MAYBE(s, on_message_begin, s);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int llhttp__on_url(llhttp_t* s, const char* p, const char* endp) {
|
||||
int err;
|
||||
CALLBACK_MAYBE(s, on_url, s, p, endp - p);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int llhttp__on_url_complete(llhttp_t* s, const char* p, const char* endp) {
|
||||
int err;
|
||||
CALLBACK_MAYBE(s, on_url_complete, s);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int llhttp__on_status(llhttp_t* s, const char* p, const char* endp) {
|
||||
int err;
|
||||
CALLBACK_MAYBE(s, on_status, s, p, endp - p);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int llhttp__on_status_complete(llhttp_t* s, const char* p, const char* endp) {
|
||||
int err;
|
||||
CALLBACK_MAYBE(s, on_status_complete, s);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int llhttp__on_header_field(llhttp_t* s, const char* p, const char* endp) {
|
||||
int err;
|
||||
CALLBACK_MAYBE(s, on_header_field, s, p, endp - p);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int llhttp__on_header_field_complete(llhttp_t* s, const char* p, const char* endp) {
|
||||
int err;
|
||||
CALLBACK_MAYBE(s, on_header_field_complete, s);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int llhttp__on_header_value(llhttp_t* s, const char* p, const char* endp) {
|
||||
int err;
|
||||
CALLBACK_MAYBE(s, on_header_value, s, p, endp - p);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int llhttp__on_header_value_complete(llhttp_t* s, const char* p, const char* endp) {
|
||||
int err;
|
||||
CALLBACK_MAYBE(s, on_header_value_complete, s);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int llhttp__on_headers_complete(llhttp_t* s, const char* p, const char* endp) {
|
||||
int err;
|
||||
CALLBACK_MAYBE(s, on_headers_complete, s);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int llhttp__on_message_complete(llhttp_t* s, const char* p, const char* endp) {
|
||||
int err;
|
||||
CALLBACK_MAYBE(s, on_message_complete, s);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int llhttp__on_body(llhttp_t* s, const char* p, const char* endp) {
|
||||
int err;
|
||||
CALLBACK_MAYBE(s, on_body, s, p, endp - p);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int llhttp__on_chunk_header(llhttp_t* s, const char* p, const char* endp) {
|
||||
int err;
|
||||
CALLBACK_MAYBE(s, on_chunk_header, s);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int llhttp__on_chunk_complete(llhttp_t* s, const char* p, const char* endp) {
|
||||
int err;
|
||||
CALLBACK_MAYBE(s, on_chunk_complete, s);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Private */
|
||||
|
||||
|
||||
void llhttp__debug(llhttp_t* s, const char* p, const char* endp,
|
||||
const char* msg) {
|
||||
if (p == endp) {
|
||||
fprintf(stderr, "p=%p type=%d flags=%02x next=null debug=%s\n", s, s->type,
|
||||
s->flags, msg);
|
||||
} else {
|
||||
fprintf(stderr, "p=%p type=%d flags=%02x next=%02x debug=%s\n", s,
|
||||
s->type, s->flags, *p, msg);
|
||||
}
|
||||
}
|
||||
253
src/3rdparty/llhttp/api.h
vendored
253
src/3rdparty/llhttp/api.h
vendored
@@ -1,253 +0,0 @@
|
||||
#ifndef INCLUDE_LLHTTP_API_H_
|
||||
#define INCLUDE_LLHTTP_API_H_
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(__wasm__)
|
||||
#define LLHTTP_EXPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
#define LLHTTP_EXPORT
|
||||
#endif
|
||||
|
||||
typedef llhttp__internal_t llhttp_t;
|
||||
typedef struct llhttp_settings_s llhttp_settings_t;
|
||||
|
||||
typedef int (*llhttp_data_cb)(llhttp_t*, const char *at, size_t length);
|
||||
typedef int (*llhttp_cb)(llhttp_t*);
|
||||
|
||||
struct llhttp_settings_s {
|
||||
/* Possible return values 0, -1, `HPE_PAUSED` */
|
||||
llhttp_cb on_message_begin;
|
||||
|
||||
llhttp_data_cb on_url;
|
||||
llhttp_data_cb on_status;
|
||||
llhttp_data_cb on_header_field;
|
||||
llhttp_data_cb on_header_value;
|
||||
|
||||
/* Possible return values:
|
||||
* 0 - Proceed normally
|
||||
* 1 - Assume that request/response has no body, and proceed to parsing the
|
||||
* next message
|
||||
* 2 - Assume absence of body (as above) and make `llhttp_execute()` return
|
||||
* `HPE_PAUSED_UPGRADE`
|
||||
* -1 - Error
|
||||
* `HPE_PAUSED`
|
||||
*/
|
||||
llhttp_cb on_headers_complete;
|
||||
|
||||
llhttp_data_cb on_body;
|
||||
|
||||
/* Possible return values 0, -1, `HPE_PAUSED` */
|
||||
llhttp_cb on_message_complete;
|
||||
|
||||
/* When on_chunk_header is called, the current chunk length is stored
|
||||
* in parser->content_length.
|
||||
* Possible return values 0, -1, `HPE_PAUSED`
|
||||
*/
|
||||
llhttp_cb on_chunk_header;
|
||||
llhttp_cb on_chunk_complete;
|
||||
|
||||
llhttp_cb on_url_complete;
|
||||
llhttp_cb on_status_complete;
|
||||
llhttp_cb on_header_field_complete;
|
||||
llhttp_cb on_header_value_complete;
|
||||
};
|
||||
|
||||
/* Initialize the parser with specific type and user settings.
|
||||
*
|
||||
* NOTE: lifetime of `settings` has to be at least the same as the lifetime of
|
||||
* the `parser` here. In practice, `settings` has to be either a static
|
||||
* variable or be allocated with `malloc`, `new`, etc.
|
||||
*/
|
||||
LLHTTP_EXPORT
|
||||
void llhttp_init(llhttp_t* parser, llhttp_type_t type,
|
||||
const llhttp_settings_t* settings);
|
||||
|
||||
#if defined(__wasm__)
|
||||
|
||||
LLHTTP_EXPORT
|
||||
llhttp_t* llhttp_alloc(llhttp_type_t type);
|
||||
|
||||
LLHTTP_EXPORT
|
||||
void llhttp_free(llhttp_t* parser);
|
||||
|
||||
LLHTTP_EXPORT
|
||||
uint8_t llhttp_get_type(llhttp_t* parser);
|
||||
|
||||
LLHTTP_EXPORT
|
||||
uint8_t llhttp_get_http_major(llhttp_t* parser);
|
||||
|
||||
LLHTTP_EXPORT
|
||||
uint8_t llhttp_get_http_minor(llhttp_t* parser);
|
||||
|
||||
LLHTTP_EXPORT
|
||||
uint8_t llhttp_get_method(llhttp_t* parser);
|
||||
|
||||
LLHTTP_EXPORT
|
||||
int llhttp_get_status_code(llhttp_t* parser);
|
||||
|
||||
LLHTTP_EXPORT
|
||||
uint8_t llhttp_get_upgrade(llhttp_t* parser);
|
||||
|
||||
#endif // defined(__wasm__)
|
||||
|
||||
/* Reset an already initialized parser back to the start state, preserving the
|
||||
* existing parser type, callback settings, user data, and lenient flags.
|
||||
*/
|
||||
LLHTTP_EXPORT
|
||||
void llhttp_reset(llhttp_t* parser);
|
||||
|
||||
/* Initialize the settings object */
|
||||
LLHTTP_EXPORT
|
||||
void llhttp_settings_init(llhttp_settings_t* settings);
|
||||
|
||||
/* Parse full or partial request/response, invoking user callbacks along the
|
||||
* way.
|
||||
*
|
||||
* If any of `llhttp_data_cb` returns errno not equal to `HPE_OK` - the parsing
|
||||
* interrupts, and such errno is returned from `llhttp_execute()`. If
|
||||
* `HPE_PAUSED` was used as a errno, the execution can be resumed with
|
||||
* `llhttp_resume()` call.
|
||||
*
|
||||
* In a special case of CONNECT/Upgrade request/response `HPE_PAUSED_UPGRADE`
|
||||
* is returned after fully parsing the request/response. If the user wishes to
|
||||
* continue parsing, they need to invoke `llhttp_resume_after_upgrade()`.
|
||||
*
|
||||
* NOTE: if this function ever returns a non-pause type error, it will continue
|
||||
* to return the same error upon each successive call up until `llhttp_init()`
|
||||
* is called.
|
||||
*/
|
||||
LLHTTP_EXPORT
|
||||
llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len);
|
||||
|
||||
/* This method should be called when the other side has no further bytes to
|
||||
* send (e.g. shutdown of readable side of the TCP connection.)
|
||||
*
|
||||
* Requests without `Content-Length` and other messages might require treating
|
||||
* all incoming bytes as the part of the body, up to the last byte of the
|
||||
* connection. This method will invoke `on_message_complete()` callback if the
|
||||
* request was terminated safely. Otherwise a error code would be returned.
|
||||
*/
|
||||
LLHTTP_EXPORT
|
||||
llhttp_errno_t llhttp_finish(llhttp_t* parser);
|
||||
|
||||
/* Returns `1` if the incoming message is parsed until the last byte, and has
|
||||
* to be completed by calling `llhttp_finish()` on EOF
|
||||
*/
|
||||
LLHTTP_EXPORT
|
||||
int llhttp_message_needs_eof(const llhttp_t* parser);
|
||||
|
||||
/* Returns `1` if there might be any other messages following the last that was
|
||||
* successfully parsed.
|
||||
*/
|
||||
LLHTTP_EXPORT
|
||||
int llhttp_should_keep_alive(const llhttp_t* parser);
|
||||
|
||||
/* Make further calls of `llhttp_execute()` return `HPE_PAUSED` and set
|
||||
* appropriate error reason.
|
||||
*
|
||||
* Important: do not call this from user callbacks! User callbacks must return
|
||||
* `HPE_PAUSED` if pausing is required.
|
||||
*/
|
||||
LLHTTP_EXPORT
|
||||
void llhttp_pause(llhttp_t* parser);
|
||||
|
||||
/* Might be called to resume the execution after the pause in user's callback.
|
||||
* See `llhttp_execute()` above for details.
|
||||
*
|
||||
* Call this only if `llhttp_execute()` returns `HPE_PAUSED`.
|
||||
*/
|
||||
LLHTTP_EXPORT
|
||||
void llhttp_resume(llhttp_t* parser);
|
||||
|
||||
/* Might be called to resume the execution after the pause in user's callback.
|
||||
* See `llhttp_execute()` above for details.
|
||||
*
|
||||
* Call this only if `llhttp_execute()` returns `HPE_PAUSED_UPGRADE`
|
||||
*/
|
||||
LLHTTP_EXPORT
|
||||
void llhttp_resume_after_upgrade(llhttp_t* parser);
|
||||
|
||||
/* Returns the latest return error */
|
||||
LLHTTP_EXPORT
|
||||
llhttp_errno_t llhttp_get_errno(const llhttp_t* parser);
|
||||
|
||||
/* Returns the verbal explanation of the latest returned error.
|
||||
*
|
||||
* Note: User callback should set error reason when returning the error. See
|
||||
* `llhttp_set_error_reason()` for details.
|
||||
*/
|
||||
LLHTTP_EXPORT
|
||||
const char* llhttp_get_error_reason(const llhttp_t* parser);
|
||||
|
||||
/* Assign verbal description to the returned error. Must be called in user
|
||||
* callbacks right before returning the errno.
|
||||
*
|
||||
* Note: `HPE_USER` error code might be useful in user callbacks.
|
||||
*/
|
||||
LLHTTP_EXPORT
|
||||
void llhttp_set_error_reason(llhttp_t* parser, const char* reason);
|
||||
|
||||
/* Returns the pointer to the last parsed byte before the returned error. The
|
||||
* pointer is relative to the `data` argument of `llhttp_execute()`.
|
||||
*
|
||||
* Note: this method might be useful for counting the number of parsed bytes.
|
||||
*/
|
||||
LLHTTP_EXPORT
|
||||
const char* llhttp_get_error_pos(const llhttp_t* parser);
|
||||
|
||||
/* Returns textual name of error code */
|
||||
LLHTTP_EXPORT
|
||||
const char* llhttp_errno_name(llhttp_errno_t err);
|
||||
|
||||
/* Returns textual name of HTTP method */
|
||||
LLHTTP_EXPORT
|
||||
const char* llhttp_method_name(llhttp_method_t method);
|
||||
|
||||
|
||||
/* Enables/disables lenient header value parsing (disabled by default).
|
||||
*
|
||||
* Lenient parsing disables header value token checks, extending llhttp's
|
||||
* protocol support to highly non-compliant clients/server. No
|
||||
* `HPE_INVALID_HEADER_TOKEN` will be raised for incorrect header values when
|
||||
* lenient parsing is "on".
|
||||
*
|
||||
* **(USE AT YOUR OWN RISK)**
|
||||
*/
|
||||
LLHTTP_EXPORT
|
||||
void llhttp_set_lenient_headers(llhttp_t* parser, int enabled);
|
||||
|
||||
|
||||
/* Enables/disables lenient handling of conflicting `Transfer-Encoding` and
|
||||
* `Content-Length` headers (disabled by default).
|
||||
*
|
||||
* Normally `llhttp` would error when `Transfer-Encoding` is present in
|
||||
* conjunction with `Content-Length`. This error is important to prevent HTTP
|
||||
* request smuggling, but may be less desirable for small number of cases
|
||||
* involving legacy servers.
|
||||
*
|
||||
* **(USE AT YOUR OWN RISK)**
|
||||
*/
|
||||
LLHTTP_EXPORT
|
||||
void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled);
|
||||
|
||||
|
||||
/* Enables/disables lenient handling of `Connection: close` and HTTP/1.0
|
||||
* requests responses.
|
||||
*
|
||||
* Normally `llhttp` would error on (in strict mode) or discard (in loose mode)
|
||||
* the HTTP request/response after the request/response with `Connection: close`
|
||||
* and `Content-Length`. This is important to prevent cache poisoning attacks,
|
||||
* but might interact badly with outdated and insecure clients. With this flag
|
||||
* the extra request/response will be parsed normally.
|
||||
*
|
||||
* **(USE AT YOUR OWN RISK)**
|
||||
*/
|
||||
void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
#endif /* INCLUDE_LLHTTP_API_H_ */
|
||||
149
src/3rdparty/llhttp/http.c
vendored
149
src/3rdparty/llhttp/http.c
vendored
@@ -1,149 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#ifndef LLHTTP__TEST
|
||||
# include "llhttp.h"
|
||||
#else
|
||||
# define llhttp_t llparse_t
|
||||
#endif /* */
|
||||
|
||||
int llhttp_message_needs_eof(const llhttp_t* parser);
|
||||
int llhttp_should_keep_alive(const llhttp_t* parser);
|
||||
|
||||
int llhttp__before_headers_complete(llhttp_t* parser, const char* p,
|
||||
const char* endp) {
|
||||
/* Set this here so that on_headers_complete() callbacks can see it */
|
||||
if ((parser->flags & F_UPGRADE) &&
|
||||
(parser->flags & F_CONNECTION_UPGRADE)) {
|
||||
/* For responses, "Upgrade: foo" and "Connection: upgrade" are
|
||||
* mandatory only when it is a 101 Switching Protocols response,
|
||||
* otherwise it is purely informational, to announce support.
|
||||
*/
|
||||
parser->upgrade =
|
||||
(parser->type == HTTP_REQUEST || parser->status_code == 101);
|
||||
} else {
|
||||
parser->upgrade = (parser->method == HTTP_CONNECT);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Return values:
|
||||
* 0 - No body, `restart`, message_complete
|
||||
* 1 - CONNECT request, `restart`, message_complete, and pause
|
||||
* 2 - chunk_size_start
|
||||
* 3 - body_identity
|
||||
* 4 - body_identity_eof
|
||||
* 5 - invalid transfer-encoding for request
|
||||
*/
|
||||
int llhttp__after_headers_complete(llhttp_t* parser, const char* p,
|
||||
const char* endp) {
|
||||
int hasBody;
|
||||
|
||||
hasBody = parser->flags & F_CHUNKED || parser->content_length > 0;
|
||||
if (parser->upgrade && (parser->method == HTTP_CONNECT ||
|
||||
(parser->flags & F_SKIPBODY) || !hasBody)) {
|
||||
/* Exit, the rest of the message is in a different protocol. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (parser->flags & F_SKIPBODY) {
|
||||
return 0;
|
||||
} else if (parser->flags & F_CHUNKED) {
|
||||
/* chunked encoding - ignore Content-Length header, prepare for a chunk */
|
||||
return 2;
|
||||
} else if (parser->flags & F_TRANSFER_ENCODING) {
|
||||
if (parser->type == HTTP_REQUEST &&
|
||||
(parser->lenient_flags & LENIENT_CHUNKED_LENGTH) == 0) {
|
||||
/* RFC 7230 3.3.3 */
|
||||
|
||||
/* If a Transfer-Encoding header field
|
||||
* is present in a request and the chunked transfer coding is not
|
||||
* the final encoding, the message body length cannot be determined
|
||||
* reliably; the server MUST respond with the 400 (Bad Request)
|
||||
* status code and then close the connection.
|
||||
*/
|
||||
return 5;
|
||||
} else {
|
||||
/* RFC 7230 3.3.3 */
|
||||
|
||||
/* If a Transfer-Encoding header field is present in a response and
|
||||
* the chunked transfer coding is not the final encoding, the
|
||||
* message body length is determined by reading the connection until
|
||||
* it is closed by the server.
|
||||
*/
|
||||
return 4;
|
||||
}
|
||||
} else {
|
||||
if (!(parser->flags & F_CONTENT_LENGTH)) {
|
||||
if (!llhttp_message_needs_eof(parser)) {
|
||||
/* Assume content-length 0 - read the next */
|
||||
return 0;
|
||||
} else {
|
||||
/* Read body until EOF */
|
||||
return 4;
|
||||
}
|
||||
} else if (parser->content_length == 0) {
|
||||
/* Content-Length header given but zero: Content-Length: 0\r\n */
|
||||
return 0;
|
||||
} else {
|
||||
/* Content-Length header given and non-zero */
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int llhttp__after_message_complete(llhttp_t* parser, const char* p,
|
||||
const char* endp) {
|
||||
int should_keep_alive;
|
||||
|
||||
should_keep_alive = llhttp_should_keep_alive(parser);
|
||||
parser->finish = HTTP_FINISH_SAFE;
|
||||
parser->flags = 0;
|
||||
|
||||
/* NOTE: this is ignored in loose parsing mode */
|
||||
return should_keep_alive;
|
||||
}
|
||||
|
||||
|
||||
int llhttp_message_needs_eof(const llhttp_t* parser) {
|
||||
if (parser->type == HTTP_REQUEST) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* See RFC 2616 section 4.4 */
|
||||
if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */
|
||||
parser->status_code == 204 || /* No Content */
|
||||
parser->status_code == 304 || /* Not Modified */
|
||||
(parser->flags & F_SKIPBODY)) { /* response to a HEAD request */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* RFC 7230 3.3.3, see `llhttp__after_headers_complete` */
|
||||
if ((parser->flags & F_TRANSFER_ENCODING) &&
|
||||
(parser->flags & F_CHUNKED) == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (parser->flags & (F_CHUNKED | F_CONTENT_LENGTH)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int llhttp_should_keep_alive(const llhttp_t* parser) {
|
||||
if (parser->http_major > 0 && parser->http_minor > 0) {
|
||||
/* HTTP/1.1 */
|
||||
if (parser->flags & F_CONNECTION_CLOSE) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* HTTP/1.0 or earlier */
|
||||
if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return !llhttp_message_needs_eof(parser);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user