mirror of
https://github.com/xmrig/xmrig.git
synced 2025-12-06 23:52:38 -05:00
Compare commits
465 Commits
v6.10.0
...
4948a8c354
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4948a8c354 | ||
|
|
637c023d06 | ||
|
|
f006ec0b68 | ||
|
|
04e5ff0349 | ||
|
|
9ad1c02430 | ||
|
|
61c263af6e | ||
|
|
fe0ed9eaae | ||
|
|
d8f39ebef3 | ||
|
|
07d53fb77e | ||
|
|
4c57b60e59 | ||
|
|
e6c81d7166 | ||
|
|
94840c70d8 | ||
|
|
e1478bfa94 | ||
|
|
6df6e15267 | ||
|
|
834ea44507 | ||
|
|
73dc0ffb7e | ||
|
|
e57641d6b1 | ||
|
|
b324e34444 | ||
|
|
fdfbb60840 | ||
|
|
3ded8e6734 | ||
|
|
ee51dec499 | ||
|
|
575742078c | ||
|
|
6bab67bced | ||
|
|
db9069897d | ||
|
|
30641b1bdf | ||
|
|
45061f40d8 | ||
|
|
9f70752090 | ||
|
|
22d6a7525e | ||
|
|
774f630e14 | ||
|
|
09a7219651 | ||
|
|
97869f3347 | ||
|
|
1bbbff7d17 | ||
|
|
97683e5719 | ||
|
|
059d5d8421 | ||
|
|
285719cde4 | ||
|
|
d6a1c98314 | ||
|
|
75283445fd | ||
|
|
45084cb718 | ||
|
|
bc150fec04 | ||
|
|
c877ba8145 | ||
|
|
6793981066 | ||
|
|
9a0cd68ea5 | ||
|
|
603eb261c5 | ||
|
|
1ae9a4e428 | ||
|
|
0e57053c5a | ||
|
|
de97f3492e | ||
|
|
8a167cb2a7 | ||
|
|
d0953a507c | ||
|
|
fe8e198106 | ||
|
|
232d2d6dc5 | ||
|
|
a3cb74f29b | ||
|
|
dfc3b4632a | ||
|
|
6106bf30de | ||
|
|
56753d7c4a | ||
|
|
f7b9e3ca67 | ||
|
|
56c95703a5 | ||
|
|
eadf272425 | ||
|
|
cb227a0a79 | ||
|
|
4c171bea1e | ||
|
|
e55a854314 | ||
|
|
5bdfafd719 | ||
|
|
15a2091837 | ||
|
|
48bd09f730 | ||
|
|
21fb970949 | ||
|
|
23c12fc351 | ||
|
|
71d193676a | ||
|
|
baef34ba8c | ||
|
|
95a739d821 | ||
|
|
7b9135aadc | ||
|
|
e6f694ca9e | ||
|
|
afd79e7537 | ||
|
|
a2728af4f7 | ||
|
|
65dbded9c4 | ||
|
|
f25e65b5ac | ||
|
|
bbb19ea2f9 | ||
|
|
1c5b332add | ||
|
|
87fd0ea94a | ||
|
|
4a42dca2cb | ||
|
|
b674fafa0f | ||
|
|
b5da73389f | ||
|
|
bf5e38545c | ||
|
|
f7543ada60 | ||
|
|
95e1705fc8 | ||
|
|
2d0b07afbc | ||
|
|
b33ccf0e0b | ||
|
|
4f5f9bdffb | ||
|
|
4d3e3daa6a | ||
|
|
802029e5f5 | ||
|
|
14117e9658 | ||
|
|
7ccb1d65f0 | ||
|
|
15de3cc16c | ||
|
|
124daa4afd | ||
|
|
5de1609b7d | ||
|
|
644f4cc017 | ||
|
|
41a3f97060 | ||
|
|
452080cfbd | ||
|
|
4f103b6b45 | ||
|
|
39609c9183 | ||
|
|
2adb7b2b74 | ||
|
|
3673137df6 | ||
|
|
faa7095865 | ||
|
|
e0701f9dad | ||
|
|
14aacf8636 | ||
|
|
c764441337 | ||
|
|
05fae12a63 | ||
|
|
8059ce67f9 | ||
|
|
10111fd7f9 | ||
|
|
2d25bec2df | ||
|
|
cab244d468 | ||
|
|
4001488888 | ||
|
|
9bec1521b8 | ||
|
|
7bde3ed5f7 | ||
|
|
2e738509bb | ||
|
|
f5447088cb | ||
|
|
7f2f50a8d9 | ||
|
|
5747ccfafc | ||
|
|
93081eb1f6 | ||
|
|
4bf65c8669 | ||
|
|
1a6fc3a665 | ||
|
|
8dede14ac8 | ||
|
|
20687a397e | ||
|
|
454f97fa0f | ||
|
|
8149fc7dcb | ||
|
|
a39ab89236 | ||
|
|
5b8501fb57 | ||
|
|
039be2ab75 | ||
|
|
718c7e0fc1 | ||
|
|
ef7951b91d | ||
|
|
214b1f021b | ||
|
|
81b18c0741 | ||
|
|
8e83f72456 | ||
|
|
c2ae625032 | ||
|
|
60566dc84c | ||
|
|
4ea8fe694d | ||
|
|
669d1ab008 | ||
|
|
e87d5111a2 | ||
|
|
56158779de | ||
|
|
efb322df66 | ||
|
|
e673d541c1 | ||
|
|
a98db529fb | ||
|
|
1a9eaaad8f | ||
|
|
be5fbca9b6 | ||
|
|
2feb264375 | ||
|
|
00990f2649 | ||
|
|
d78713be48 | ||
|
|
77367abe13 | ||
|
|
cd046f6fd0 | ||
|
|
63b7ec2887 | ||
|
|
a1e8f1c3e5 | ||
|
|
6db480a1ab | ||
|
|
a7acd9de6d | ||
|
|
a64f4d1870 | ||
|
|
9bfe59b630 | ||
|
|
1a4bf16521 | ||
|
|
a4d5d0a75a | ||
|
|
c40f1f9f66 | ||
|
|
15e5052dd0 | ||
|
|
f9f7963453 | ||
|
|
02240eff8c | ||
|
|
d64c963e5e | ||
|
|
c6292ce9ee | ||
|
|
cd652e2644 | ||
|
|
6f5ef0fe0f | ||
|
|
01fa968763 | ||
|
|
8e6f3ad99e | ||
|
|
b1f2479ec1 | ||
|
|
ecceba8ecd | ||
|
|
cb5f4a9c17 | ||
|
|
3a8ebfdcb6 | ||
|
|
0dcafeb571 | ||
|
|
a1d7ee4c6b | ||
|
|
03e70ba2ed | ||
|
|
19ef8c5d65 | ||
|
|
63baa9e263 | ||
|
|
1248bd5859 | ||
|
|
5c951ddb8a | ||
|
|
4ab0ad928d | ||
|
|
e67eb47796 | ||
|
|
a6656a8c49 | ||
|
|
a903d0a5bd | ||
|
|
ceaebfd877 | ||
|
|
5156ff11a8 | ||
|
|
e0143a92a8 | ||
|
|
f682d9a2e9 | ||
|
|
3bece0ff40 | ||
|
|
e6c456a970 | ||
|
|
923d1d712f | ||
|
|
ae8459bd35 | ||
|
|
3a7be07c62 | ||
|
|
e1cc0000c6 | ||
|
|
1210e8e95c | ||
|
|
a45fbd9cae | ||
|
|
f6d45f7990 | ||
|
|
b9464f993b | ||
|
|
f8f73b0cd7 | ||
|
|
df6ab2edd8 | ||
|
|
8bf7600154 | ||
|
|
a30501956f | ||
|
|
c287a40a20 | ||
|
|
04f50c24e2 | ||
|
|
7627b23212 | ||
|
|
e90e7febfb | ||
|
|
733b85a132 | ||
|
|
35ba786e63 | ||
|
|
446810a837 | ||
|
|
c6a68c3e51 | ||
|
|
ca8bef3ade | ||
|
|
d735caa334 | ||
|
|
eb54cc0e0f | ||
|
|
84c67c37cd | ||
|
|
b44f38a362 | ||
|
|
8ed4088d0a | ||
|
|
cdcea2a4f9 | ||
|
|
f0d80326ec | ||
|
|
cb8fc26cbe | ||
|
|
5ec5b5ed00 | ||
|
|
67e29c1af1 | ||
|
|
4bd94a79a4 | ||
|
|
80e597d951 | ||
|
|
2e269f5b8c | ||
|
|
57b8e35903 | ||
|
|
53be5765e6 | ||
|
|
68741c925b | ||
|
|
9ce207e667 | ||
|
|
07e0966517 | ||
|
|
a9d4c2a923 | ||
|
|
dc02e1feaa | ||
|
|
7daff331dc | ||
|
|
058a2fb0f4 | ||
|
|
4fff3b946e | ||
|
|
f7aa5e781b | ||
|
|
298c5cccfa | ||
|
|
2985571620 | ||
|
|
279d29cd7f | ||
|
|
387320ad6d | ||
|
|
76cd83edb2 | ||
|
|
7f4d667351 | ||
|
|
8027716264 | ||
|
|
a459dd7741 | ||
|
|
ef6011ac12 | ||
|
|
6d66051d92 | ||
|
|
b2cc2ef0d7 | ||
|
|
9805320517 | ||
|
|
582d17bb84 | ||
|
|
9e5f5b35a6 | ||
|
|
9a9c69ff50 | ||
|
|
5c1f3f395c | ||
|
|
23cefffe43 | ||
|
|
d048d5a639 | ||
|
|
9a6f773dea | ||
|
|
cd7c7902a9 | ||
|
|
fd3dad920d | ||
|
|
3dc192f63e | ||
|
|
123c7ab140 | ||
|
|
838996a0fc | ||
|
|
6e4fea34a4 | ||
|
|
b52c289931 | ||
|
|
4dbb5b89da | ||
|
|
84d0212e79 | ||
|
|
35acb3f00b | ||
|
|
7f2771b466 | ||
|
|
5fdf5516ff | ||
|
|
234de96784 | ||
|
|
df4532d9a1 | ||
|
|
c27f535768 | ||
|
|
c7ac314110 | ||
|
|
3215403815 | ||
|
|
bea2a6cf5b | ||
|
|
a28f411339 | ||
|
|
460d9c75c5 | ||
|
|
d1033abbe5 | ||
|
|
9eac9dd30a | ||
|
|
8d7b6adf98 | ||
|
|
230ff87634 | ||
|
|
19adf2630a | ||
|
|
3de4b16117 | ||
|
|
602e3a7587 | ||
|
|
4f6ffb67c1 | ||
|
|
a0194ddd18 | ||
|
|
30f7e876a2 | ||
|
|
5958490c23 | ||
|
|
f92ad4423d | ||
|
|
e0749a82c2 | ||
|
|
440aa003af | ||
|
|
9580f5395f | ||
|
|
e9ae4deb91 | ||
|
|
aee0762424 | ||
|
|
e6332eff2b | ||
|
|
d0a632f557 | ||
|
|
f4cdc527b0 | ||
|
|
661dc515ab | ||
|
|
6d9bafe068 | ||
|
|
202c8aaee8 | ||
|
|
410084384e | ||
|
|
43e98c509a | ||
|
|
08d79ddcdc | ||
|
|
0fdf063760 | ||
|
|
929205536c | ||
|
|
d24581c963 | ||
|
|
2eb2e90631 | ||
|
|
0842e6b9d2 | ||
|
|
93805cd167 | ||
|
|
755fe28bc3 | ||
|
|
59d780169f | ||
|
|
a30ede04f3 | ||
|
|
3f2dfa4279 | ||
|
|
7177b42903 | ||
|
|
21638c2f58 | ||
|
|
02b2b87bb6 | ||
|
|
c8a9dba8fd | ||
|
|
9a77d39a3f | ||
|
|
28a1d0fe1e | ||
|
|
0243789c04 | ||
|
|
45dd58f808 | ||
|
|
1b4abe1e98 | ||
|
|
9f778742a6 | ||
|
|
015f8aeed4 | ||
|
|
9e6311a7e0 | ||
|
|
0af9d2e75b | ||
|
|
6e2a84a46c | ||
|
|
6bb8913066 | ||
|
|
cf104ebdc5 | ||
|
|
ecba750442 | ||
|
|
3967badc55 | ||
|
|
3f3f9b0661 | ||
|
|
e3fc78a66c | ||
|
|
e6d833c227 | ||
|
|
ebe299902c | ||
|
|
bc63b63a2a | ||
|
|
e739e7d704 | ||
|
|
1bae083587 | ||
|
|
88959bd703 | ||
|
|
93e689d601 | ||
|
|
a136790bee | ||
|
|
29f2dd4b9e | ||
|
|
3003c067d3 | ||
|
|
89bc6418b1 | ||
|
|
8458b4ee39 | ||
|
|
7bfb801ce2 | ||
|
|
4567499905 | ||
|
|
9b63955b09 | ||
|
|
0414511de0 | ||
|
|
b61dad128c | ||
|
|
80ae339343 | ||
|
|
4d87555398 | ||
|
|
bef82c5de6 | ||
|
|
b069ad5dd1 | ||
|
|
f6a0646271 | ||
|
|
b5f1a1feae | ||
|
|
1ce059da1c | ||
|
|
2929451ee1 | ||
|
|
94fecb5e92 | ||
|
|
3bfa5ea038 | ||
|
|
ff82ca57f2 | ||
|
|
7f7b1fb073 | ||
|
|
d443dd86f1 | ||
|
|
3ac8f6b23a | ||
|
|
9b1f020a8b | ||
|
|
8bf88a4e74 | ||
|
|
08a2c143f5 | ||
|
|
4eb9a1aad5 | ||
|
|
c8c40586a1 | ||
|
|
29cb416107 | ||
|
|
465169ff12 | ||
|
|
df2bcd8192 | ||
|
|
d89bb56964 | ||
|
|
87a0864e3b | ||
|
|
ecf5579f36 | ||
|
|
d5523d819f | ||
|
|
dbda2e9ccd | ||
|
|
8babd7bc0a | ||
|
|
27ced139a6 | ||
|
|
b46849e813 | ||
|
|
a96a6108ff | ||
|
|
c50c78b700 | ||
|
|
cd7ab2c79f | ||
|
|
695fbc013b | ||
|
|
a403c53543 | ||
|
|
e26fbc96e9 | ||
|
|
259c165e60 | ||
|
|
7897bf02dc | ||
|
|
05f62c5ccc | ||
|
|
d82e100e30 | ||
|
|
5f869a414c | ||
|
|
7fd6be7d83 | ||
|
|
ae6c536e98 | ||
|
|
c66c593123 | ||
|
|
b3788b2ba3 | ||
|
|
b7adb34c37 | ||
|
|
ace8409a56 | ||
|
|
e2c757d9dd | ||
|
|
da35de993f | ||
|
|
854b7618ef | ||
|
|
3477f9fbc1 | ||
|
|
5799744f2f | ||
|
|
61d165a314 | ||
|
|
69186f2470 | ||
|
|
730d4a6cee | ||
|
|
54bc91d5e3 | ||
|
|
2012ffb231 | ||
|
|
5f9e0ebc6c | ||
|
|
f314c69a70 | ||
|
|
16fe462cad | ||
|
|
e6e2987ddf | ||
|
|
ed456b02cf | ||
|
|
da7f5826cb | ||
|
|
6cb398bb42 | ||
|
|
748be760e8 | ||
|
|
4a4118bb8e | ||
|
|
77f1bf0861 | ||
|
|
6bb29b3e7b | ||
|
|
f720772338 | ||
|
|
e53e48b88c | ||
|
|
ecf36ee891 | ||
|
|
23ef949dd3 | ||
|
|
92e708c6e7 | ||
|
|
30cfcc27db | ||
|
|
3c6077fb02 | ||
|
|
63883b4fa7 | ||
|
|
0f83b5e06c | ||
|
|
637a333197 | ||
|
|
3171b06048 | ||
|
|
2a66a0fa2f | ||
|
|
c080d5b962 | ||
|
|
0133107f14 | ||
|
|
253e349ef9 | ||
|
|
5126cc1414 | ||
|
|
ea1245026d | ||
|
|
2158adb711 | ||
|
|
8554bb4d9c | ||
|
|
1741354498 | ||
|
|
866e97efcf | ||
|
|
277352d072 | ||
|
|
8cae605e1f | ||
|
|
59c85eaf6a | ||
|
|
864233c110 | ||
|
|
e9b32b3009 | ||
|
|
ec608bbd05 | ||
|
|
ec2793bcc9 | ||
|
|
eb40f07552 | ||
|
|
28f268aeba | ||
|
|
bad5458d40 | ||
|
|
b72e21fc3c | ||
|
|
d578a3828f | ||
|
|
6c417eb9af | ||
|
|
dc70893e6b | ||
|
|
c5c958743e | ||
|
|
89f2fa6818 | ||
|
|
bcfd9edaa5 | ||
|
|
e0f774d6dd | ||
|
|
955cc366d1 | ||
|
|
bc4f6249be | ||
|
|
0d45600b0e | ||
|
|
2c8f7f692c | ||
|
|
3e41bdc552 | ||
|
|
5b189696d7 | ||
|
|
c6bcea3811 | ||
|
|
900dd13c45 | ||
|
|
2876f17f65 | ||
|
|
b2563ca8a6 | ||
|
|
7c0d60ac68 | ||
|
|
813a1885cb | ||
|
|
54bcf05b1d | ||
|
|
bbea8810a7 | ||
|
|
b6514957f1 |
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
|
||||
140
CHANGELOG.md
140
CHANGELOG.md
@@ -1,3 +1,143 @@
|
||||
# v6.18.0
|
||||
- [#3067](https://github.com/xmrig/xmrig/pull/3067) Monero v15 network upgrade support and more house keeping.
|
||||
- Removed deprecated AstroBWTv1 and v2.
|
||||
- Fixed debug GhostRider build.
|
||||
- Monero v15 network upgrade support.
|
||||
- Fixed ZMQ debug log.
|
||||
- Improved daemon ZMQ mining stability.
|
||||
- [#3054](https://github.com/xmrig/xmrig/pull/3054) Fixes for 32-bit ARM.
|
||||
- [#3042](https://github.com/xmrig/xmrig/pull/3042) Fixed being unable to resume from `pause-on-battery`.
|
||||
- [#3031](https://github.com/xmrig/xmrig/pull/3031) Fixed `--cpu-priority` not working sometimes.
|
||||
- [#3020](https://github.com/xmrig/xmrig/pull/3020) Removed old AstroBWT algorithm.
|
||||
|
||||
# v6.17.0
|
||||
- [#2954](https://github.com/xmrig/xmrig/pull/2954) **Dero HE fork support (`astrobwt/v2` algorithm).**
|
||||
- [#2961](https://github.com/xmrig/xmrig/pull/2961) Dero HE (`astrobwt/v2`) CUDA config generator.
|
||||
- [#2969](https://github.com/xmrig/xmrig/pull/2969) Dero HE (`astrobwt/v2`) OpenCL support.
|
||||
- Fixed displayed DMI memory information for empty slots.
|
||||
- [#2932](https://github.com/xmrig/xmrig/pull/2932) Fixed GhostRider with hwloc disabled.
|
||||
|
||||
# v6.16.4
|
||||
- [#2904](https://github.com/xmrig/xmrig/pull/2904) Fixed unaligned memory accesses.
|
||||
- [#2908](https://github.com/xmrig/xmrig/pull/2908) Added MSVC/2022 to `version.h`.
|
||||
- [#2910](https://github.com/xmrig/xmrig/issues/2910) Fixed donation for GhostRider/RTM.
|
||||
|
||||
# v6.16.3
|
||||
- [#2778](https://github.com/xmrig/xmrig/pull/2778) Fixed `READY threads X/X` display after algorithm switching.
|
||||
- [#2782](https://github.com/xmrig/xmrig/pull/2782) Updated GhostRider documentation.
|
||||
- [#2815](https://github.com/xmrig/xmrig/pull/2815) Fixed `cn-heavy` in 32-bit builds.
|
||||
- [#2827](https://github.com/xmrig/xmrig/pull/2827) GhostRider: set correct priority for helper threads.
|
||||
- [#2837](https://github.com/xmrig/xmrig/pull/2837) RandomX: don't restart mining threads when the seed changes.
|
||||
- [#2848](https://github.com/xmrig/xmrig/pull/2848) GhostRider: added support for `client.reconnect` method.
|
||||
- [#2856](https://github.com/xmrig/xmrig/pull/2856) Fix for short responses from some Raptoreum pools.
|
||||
- [#2873](https://github.com/xmrig/xmrig/pull/2873) Fixed GhostRider benchmark on single-core systems.
|
||||
- [#2882](https://github.com/xmrig/xmrig/pull/2882) Fixed ARMv7 compilation.
|
||||
- [#2893](https://github.com/xmrig/xmrig/pull/2893) KawPow OpenCL: use separate UV loop for building programs.
|
||||
|
||||
# v6.16.2
|
||||
- [#2751](https://github.com/xmrig/xmrig/pull/2751) Fixed crash on CPUs supporting VAES and running GCC-compiled xmrig.
|
||||
- [#2761](https://github.com/xmrig/xmrig/pull/2761) Fixed broken auto-tuning in GCC Windows build.
|
||||
- [#2771](https://github.com/xmrig/xmrig/issues/2771) Fixed environment variables support for GhostRider and KawPow.
|
||||
- [#2769](https://github.com/xmrig/xmrig/pull/2769) Performance fixes:
|
||||
- Fixed several performance bottlenecks introduced in v6.16.1.
|
||||
- Fixed overall GCC-compiled build performance, it's the same speed as MSVC build now.
|
||||
- **Linux builds are up to 10% faster now compared to v6.16.0 GCC build.**
|
||||
- **Windows builds are up to 5% faster now compared to v6.16.0 MSVC build.**
|
||||
|
||||
# v6.16.1
|
||||
- [#2729](https://github.com/xmrig/xmrig/pull/2729) GhostRider fixes:
|
||||
- Added average hashrate display.
|
||||
- Fixed the number of threads shown at startup.
|
||||
- Fixed `--threads` or `-t` command line option (but `--cpu-max-threads-hint` is recommended to use).
|
||||
- [#2738](https://github.com/xmrig/xmrig/pull/2738) GhostRider fixes:
|
||||
- Fixed "difficulty is not a number" error when diff is high on some pools.
|
||||
- Fixed GhostRider compilation when `WITH_KAWPOW=OFF`.
|
||||
- [#2740](https://github.com/xmrig/xmrig/pull/2740) Added VAES support for Cryptonight variants **+4% speedup on Zen3**.
|
||||
- VAES instructions are available on Intel Ice Lake/AMD Zen3 and newer CPUs.
|
||||
- +4% speedup on Ryzen 5 5600X.
|
||||
|
||||
# v6.16.0
|
||||
- [#2712](https://github.com/xmrig/xmrig/pull/2712) **GhostRider algorithm (Raptoreum) support**: read the [RELEASE NOTES](src/crypto/ghostrider/README.md) for quick start guide and performance comparisons.
|
||||
- [#2682](https://github.com/xmrig/xmrig/pull/2682) Fixed: use cn-heavy optimization only for Vermeer CPUs.
|
||||
- [#2684](https://github.com/xmrig/xmrig/pull/2684) MSR mod: fix for error 183.
|
||||
|
||||
# v6.15.3
|
||||
- [#2614](https://github.com/xmrig/xmrig/pull/2614) OpenCL fixes for non-AMD platforms.
|
||||
- [#2623](https://github.com/xmrig/xmrig/pull/2623) Fixed compiling without kawpow.
|
||||
- [#2636](https://github.com/xmrig/xmrig/pull/2636) [#2639](https://github.com/xmrig/xmrig/pull/2639) AstroBWT speedup (up to +35%).
|
||||
- [#2646](https://github.com/xmrig/xmrig/pull/2646) Fixed MSVC compilation error.
|
||||
|
||||
# v6.15.2
|
||||
- [#2606](https://github.com/xmrig/xmrig/pull/2606) Fixed: AstroBWT auto-config ignored `max-threads-hint`.
|
||||
- Fixed possible crash on Windows (regression in v6.15.1).
|
||||
|
||||
# v6.15.1
|
||||
- [#2586](https://github.com/xmrig/xmrig/pull/2586) Fixed Windows 7 compatibility.
|
||||
- [#2594](https://github.com/xmrig/xmrig/pull/2594) Added Windows taskbar icon colors.
|
||||
|
||||
# v6.15.0
|
||||
- [#2548](https://github.com/xmrig/xmrig/pull/2548) Added automatic coin detection for daemon mining.
|
||||
- [#2563](https://github.com/xmrig/xmrig/pull/2563) Added new algorithm RandomX Graft (`rx/graft`).
|
||||
- [#2565](https://github.com/xmrig/xmrig/pull/2565) AstroBWT: added AVX2 Salsa20 implementation.
|
||||
- Added support for new CUDA plugin API (previous API still supported).
|
||||
|
||||
# v6.14.1
|
||||
- [#2532](https://github.com/xmrig/xmrig/pull/2532) Refactoring: stable (persistent) algorithms IDs.
|
||||
- [#2537](https://github.com/xmrig/xmrig/pull/2537) Fixed Termux build.
|
||||
|
||||
# v6.14.0
|
||||
- [#2484](https://github.com/xmrig/xmrig/pull/2484) Added ZeroMQ support for solo mining.
|
||||
- [#2476](https://github.com/xmrig/xmrig/issues/2476) Fixed crash in DMI memory reader.
|
||||
- [#2492](https://github.com/xmrig/xmrig/issues/2492) Added missing `--huge-pages-jit` command line option.
|
||||
- [#2512](https://github.com/xmrig/xmrig/pull/2512) Added show the number of transactions in pool job.
|
||||
|
||||
# v6.13.1
|
||||
- [#2468](https://github.com/xmrig/xmrig/pull/2468) Fixed regression in previous version: don't send miner signature during regular mining.
|
||||
|
||||
# v6.13.0
|
||||
- [#2445](https://github.com/xmrig/xmrig/pull/2445) Added support for solo mining with miner signatures for the upcoming Wownero fork.
|
||||
|
||||
# v6.12.2
|
||||
- [#2280](https://github.com/xmrig/xmrig/issues/2280) GPU backends are now disabled in benchmark mode.
|
||||
- [#2322](https://github.com/xmrig/xmrig/pull/2322) Improved MSR compatibility with recent Linux kernels and updated `randomx_boost.sh`.
|
||||
- [#2340](https://github.com/xmrig/xmrig/pull/2340) Fixed AES detection on FreeBSD on ARM.
|
||||
- [#2341](https://github.com/xmrig/xmrig/pull/2341) `sse2neon` updated to the latest version.
|
||||
- [#2351](https://github.com/xmrig/xmrig/issues/2351) Fixed help output for `--cpu-priority` and `--cpu-affinity` option.
|
||||
- [#2375](https://github.com/xmrig/xmrig/pull/2375) Fixed macOS CUDA backend default loader name.
|
||||
- [#2378](https://github.com/xmrig/xmrig/pull/2378) Fixed broken light mode mining on x86.
|
||||
- [#2379](https://github.com/xmrig/xmrig/pull/2379) Fixed CL code for KawPow where it assumes everything is AMD.
|
||||
- [#2386](https://github.com/xmrig/xmrig/pull/2386) RandomX: enabled `IMUL_RCP` optimization for light mode mining.
|
||||
- [#2393](https://github.com/xmrig/xmrig/pull/2393) RandomX: added BMI2 version for scratchpad prefetch.
|
||||
- [#2395](https://github.com/xmrig/xmrig/pull/2395) RandomX: rewrote dataset read code.
|
||||
- [#2398](https://github.com/xmrig/xmrig/pull/2398) RandomX: optimized ARMv8 dataset read.
|
||||
- Added `argon2/ninja` alias for `argon2/wrkz` algorithm.
|
||||
|
||||
# v6.12.1
|
||||
- [#2296](https://github.com/xmrig/xmrig/pull/2296) Fixed Zen3 assembly code for `cn/upx2` algorithm.
|
||||
|
||||
# v6.12.0
|
||||
- [#2276](https://github.com/xmrig/xmrig/pull/2276) Added support for Uplexa (`cn/upx2` algorithm).
|
||||
- [#2261](https://github.com/xmrig/xmrig/pull/2261) Show total hashrate if compiled without OpenCL.
|
||||
- [#2289](https://github.com/xmrig/xmrig/pull/2289) RandomX: optimized `IMUL_RCP` instruction.
|
||||
- Added support for `--user` command line option for online benchmark.
|
||||
|
||||
# v6.11.2
|
||||
- [#2207](https://github.com/xmrig/xmrig/issues/2207) Fixed regression in HTTP parser and llhttp updated to v5.1.0.
|
||||
|
||||
# v6.11.1
|
||||
- [#2239](https://github.com/xmrig/xmrig/pull/2239) Fixed broken `coin` setting functionality.
|
||||
|
||||
# v6.11.0
|
||||
- [#2196](https://github.com/xmrig/xmrig/pull/2196) Improved DNS subsystem and added new DNS specific options.
|
||||
- [#2172](https://github.com/xmrig/xmrig/pull/2172) Fixed build on Alpine 3.13.
|
||||
- [#2177](https://github.com/xmrig/xmrig/pull/2177) Fixed ARM specific compilation error with GCC 10.2.
|
||||
- [#2214](https://github.com/xmrig/xmrig/pull/2214) [#2216](https://github.com/xmrig/xmrig/pull/2216) [#2235](https://github.com/xmrig/xmrig/pull/2235) Optimized `cn-heavy` algorithm.
|
||||
- [#2217](https://github.com/xmrig/xmrig/pull/2217) Fixed mining job creation sequence.
|
||||
- [#2225](https://github.com/xmrig/xmrig/pull/2225) Fixed build without OpenCL support on some systems.
|
||||
- [#2229](https://github.com/xmrig/xmrig/pull/2229) Don't use RandomX JIT if `WITH_ASM=OFF`.
|
||||
- [#2228](https://github.com/xmrig/xmrig/pull/2228) Removed useless code for cryptonight algorithms.
|
||||
- [#2234](https://github.com/xmrig/xmrig/pull/2234) Fixed build error on gcc 4.8.
|
||||
|
||||
# v6.10.0
|
||||
- [#2122](https://github.com/xmrig/xmrig/pull/2122) Fixed pause logic when both pause on battery and user activity are enabled.
|
||||
- [#2123](https://github.com/xmrig/xmrig/issues/2123) Fixed compatibility with gcc 4.8.
|
||||
|
||||
@@ -5,10 +5,11 @@ option(WITH_HWLOC "Enable hwloc support" ON)
|
||||
option(WITH_CN_LITE "Enable CryptoNight-Lite algorithms family" ON)
|
||||
option(WITH_CN_HEAVY "Enable CryptoNight-Heavy algorithms family" ON)
|
||||
option(WITH_CN_PICO "Enable CryptoNight-Pico algorithm" ON)
|
||||
option(WITH_CN_FEMTO "Enable CryptoNight-UPX2 algorithm" ON)
|
||||
option(WITH_RANDOMX "Enable RandomX algorithms family" ON)
|
||||
option(WITH_ARGON2 "Enable Argon2 algorithms family" ON)
|
||||
option(WITH_ASTROBWT "Enable AstroBWT algorithms family" ON)
|
||||
option(WITH_KAWPOW "Enable KawPow algorithms family" ON)
|
||||
option(WITH_GHOSTRIDER "Enable GhostRider algorithm" ON)
|
||||
option(WITH_HTTP "Enable HTTP protocol support (client/server)" ON)
|
||||
option(WITH_DEBUG_LOG "Enable debug log output" OFF)
|
||||
option(WITH_TLS "Enable OpenSSL support" ON)
|
||||
@@ -17,6 +18,8 @@ option(WITH_MSR "Enable MSR mod & 1st-gen Ryzen fix" ON)
|
||||
option(WITH_ENV_VARS "Enable environment variables support in config file" ON)
|
||||
option(WITH_EMBEDDED_CONFIG "Enable internal embedded JSON config" OFF)
|
||||
option(WITH_OPENCL "Enable OpenCL backend" ON)
|
||||
set(WITH_OPENCL_VERSION 200 CACHE STRING "Target OpenCL version")
|
||||
set_property(CACHE WITH_OPENCL_VERSION PROPERTY STRINGS 120 200 210 220)
|
||||
option(WITH_CUDA "Enable CUDA backend" ON)
|
||||
option(WITH_NVML "Enable NVML (NVIDIA Management Library) support (only if CUDA backend enabled)" ON)
|
||||
option(WITH_ADL "Enable ADL (AMD Display Library) or sysfs support (only if OpenCL backend enabled)" ON)
|
||||
@@ -24,6 +27,7 @@ option(WITH_STRICT_CACHE "Enable strict checks for OpenCL cache" ON)
|
||||
option(WITH_INTERLEAVE_DEBUG_LOG "Enable debug log for threads interleave" OFF)
|
||||
option(WITH_PROFILING "Enable profiling for developers" OFF)
|
||||
option(WITH_SSE4_1 "Enable SSE 4.1 for Blake2" ON)
|
||||
option(WITH_VAES "Enable VAES instructions for Cryptonight" ON)
|
||||
option(WITH_BENCHMARK "Enable builtin RandomX benchmark and stress test" ON)
|
||||
option(WITH_SECURE_JIT "Enable secure access to JIT memory" OFF)
|
||||
option(WITH_DMI "Enable DMI/SMBIOS reader" ON)
|
||||
@@ -55,6 +59,7 @@ set(HEADERS
|
||||
src/core/config/usage.h
|
||||
src/core/Controller.h
|
||||
src/core/Miner.h
|
||||
src/core/Taskbar.h
|
||||
src/net/interfaces/IJobResultListener.h
|
||||
src/net/JobResult.h
|
||||
src/net/JobResults.h
|
||||
@@ -103,6 +108,7 @@ set(SOURCES
|
||||
src/core/config/ConfigTransform.cpp
|
||||
src/core/Controller.cpp
|
||||
src/core/Miner.cpp
|
||||
src/core/Taskbar.cpp
|
||||
src/net/JobResults.cpp
|
||||
src/net/Network.cpp
|
||||
src/net/strategies/DonateStrategy.cpp
|
||||
@@ -123,6 +129,19 @@ set(SOURCES_CRYPTO
|
||||
src/crypto/common/VirtualMemory.cpp
|
||||
)
|
||||
|
||||
if (CMAKE_C_COMPILER_ID MATCHES GNU)
|
||||
set_source_files_properties(src/crypto/cn/CnHash.cpp PROPERTIES COMPILE_FLAGS "-Ofast -fno-tree-vectorize")
|
||||
endif()
|
||||
|
||||
if (WITH_VAES)
|
||||
add_definitions(-DXMRIG_VAES)
|
||||
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/cn/CryptoNight_x86_vaes.h)
|
||||
set(SOURCES_CRYPTO "${SOURCES_CRYPTO}" src/crypto/cn/CryptoNight_x86_vaes.cpp)
|
||||
if (CMAKE_C_COMPILER_ID MATCHES GNU OR CMAKE_C_COMPILER_ID MATCHES Clang)
|
||||
set_source_files_properties(src/crypto/cn/CryptoNight_x86_vaes.cpp PROPERTIES COMPILE_FLAGS "-Ofast -fno-tree-vectorize -mavx2 -mvaes")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (WITH_HWLOC)
|
||||
list(APPEND HEADERS_CRYPTO
|
||||
src/crypto/common/NUMAMemoryPool.h
|
||||
@@ -137,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
|
||||
)
|
||||
|
||||
@@ -153,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
|
||||
)
|
||||
|
||||
@@ -171,16 +187,21 @@ 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)
|
||||
include(cmake/astrobwt.cmake)
|
||||
include(cmake/kawpow.cmake)
|
||||
include(cmake/ghostrider.cmake)
|
||||
include(cmake/OpenSSL.cmake)
|
||||
include(cmake/asm.cmake)
|
||||
|
||||
@@ -196,6 +217,10 @@ if (WITH_CN_PICO)
|
||||
add_definitions(/DXMRIG_ALGO_CN_PICO)
|
||||
endif()
|
||||
|
||||
if (WITH_CN_FEMTO)
|
||||
add_definitions(/DXMRIG_ALGO_CN_FEMTO)
|
||||
endif()
|
||||
|
||||
if (WITH_EMBEDDED_CONFIG)
|
||||
add_definitions(/DXMRIG_FEATURE_EMBEDDED_CONFIG)
|
||||
endif()
|
||||
@@ -203,16 +228,12 @@ 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()
|
||||
|
||||
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${TLS_SOURCES} ${XMRIG_ASM_SOURCES})
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB} ${ARGON2_LIBRARY} ${ETHASH_LIBRARY})
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB} ${ARGON2_LIBRARY} ${ETHASH_LIBRARY} ${GHOSTRIDER_LIBRARY})
|
||||
|
||||
if (WIN32)
|
||||
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/bin/WinRing0/WinRing0x64.sys" $<TARGET_FILE_DIR:${CMAKE_PROJECT_NAME}>)
|
||||
@@ -220,6 +241,7 @@ if (WIN32)
|
||||
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/scripts/benchmark_10M.cmd" $<TARGET_FILE_DIR:${CMAKE_PROJECT_NAME}>)
|
||||
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/scripts/pool_mine_example.cmd" $<TARGET_FILE_DIR:${CMAKE_PROJECT_NAME}>)
|
||||
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/scripts/solo_mine_example.cmd" $<TARGET_FILE_DIR:${CMAKE_PROJECT_NAME}>)
|
||||
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/scripts/rtm_ghostrider_example.cmd" $<TARGET_FILE_DIR:${CMAKE_PROJECT_NAME}>)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES Clang AND CMAKE_BUILD_TYPE STREQUAL Release AND NOT CMAKE_GENERATOR STREQUAL Xcode)
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
[](https://github.com/xmrig/xmrig/stargazers)
|
||||
[](https://github.com/xmrig/xmrig/network)
|
||||
|
||||
XMRig is a high performance, open source, cross platform RandomX, KawPow, CryptoNight and AstroBWT unified CPU/GPU miner and [RandomX benchmark](https://xmrig.com/benchmark). Official binaries are available for Windows, Linux, macOS and FreeBSD.
|
||||
XMRig is a high performance, open source, cross platform RandomX, KawPow, CryptoNight and [GhostRider](https://github.com/xmrig/xmrig/tree/master/src/crypto/ghostrider#readme) unified CPU/GPU miner and [RandomX benchmark](https://xmrig.com/benchmark). Official binaries are available for Windows, Linux, macOS and FreeBSD.
|
||||
|
||||
## Mining backends
|
||||
- **CPU** (x64/ARMv8)
|
||||
- **CPU** (x64/ARMv7/ARMv8)
|
||||
- **OpenCL** for AMD GPUs.
|
||||
- **CUDA** for NVIDIA GPUs via external [CUDA plugin](https://github.com/xmrig/xmrig-cuda).
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
if (WITH_ASTROBWT)
|
||||
add_definitions(/DXMRIG_ALGO_ASTROBWT)
|
||||
|
||||
list(APPEND HEADERS_CRYPTO
|
||||
src/crypto/astrobwt/AstroBWT.h
|
||||
)
|
||||
|
||||
list(APPEND SOURCES_CRYPTO
|
||||
src/crypto/astrobwt/AstroBWT.cpp
|
||||
)
|
||||
|
||||
if (XMRIG_ARM)
|
||||
list(APPEND HEADERS_CRYPTO
|
||||
src/crypto/astrobwt/salsa20_ref/ecrypt-config.h
|
||||
src/crypto/astrobwt/salsa20_ref/ecrypt-machine.h
|
||||
src/crypto/astrobwt/salsa20_ref/ecrypt-portable.h
|
||||
src/crypto/astrobwt/salsa20_ref/ecrypt-sync.h
|
||||
)
|
||||
|
||||
list(APPEND SOURCES_CRYPTO
|
||||
src/crypto/astrobwt/salsa20_ref/salsa20.c
|
||||
)
|
||||
else()
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
add_definitions(/DASTROBWT_AVX2)
|
||||
if (CMAKE_C_COMPILER_ID MATCHES MSVC)
|
||||
enable_language(ASM_MASM)
|
||||
list(APPEND SOURCES_CRYPTO src/crypto/astrobwt/sha3_256_avx2.asm)
|
||||
else()
|
||||
enable_language(ASM)
|
||||
list(APPEND SOURCES_CRYPTO src/crypto/astrobwt/sha3_256_avx2.S)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(APPEND HEADERS_CRYPTO
|
||||
src/crypto/astrobwt/Salsa20.hpp
|
||||
)
|
||||
|
||||
list(APPEND SOURCES_CRYPTO
|
||||
src/crypto/astrobwt/Salsa20.cpp
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
remove_definitions(/DXMRIG_ALGO_ASTROBWT)
|
||||
endif()
|
||||
@@ -1,11 +1,31 @@
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(XMRIG_64_BIT ON)
|
||||
add_definitions(-DXMRIG_64_BIT)
|
||||
else()
|
||||
set(XMRIG_64_BIT OFF)
|
||||
endif()
|
||||
|
||||
if (NOT CMAKE_SYSTEM_PROCESSOR)
|
||||
message(WARNING "CMAKE_SYSTEM_PROCESSOR not defined")
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64)$" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
add_definitions(/DRAPIDJSON_SSE2)
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||
set(VAES_SUPPORTED ON)
|
||||
else()
|
||||
CHECK_CXX_COMPILER_FLAG("-mavx2 -mvaes" VAES_SUPPORTED)
|
||||
endif()
|
||||
|
||||
if (NOT VAES_SUPPORTED)
|
||||
set(WITH_VAES OFF)
|
||||
endif()
|
||||
|
||||
if (XMRIG_64_BIT AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64)$")
|
||||
add_definitions(-DRAPIDJSON_SSE2)
|
||||
else()
|
||||
set(WITH_SSE4_1 OFF)
|
||||
set(WITH_VAES OFF)
|
||||
endif()
|
||||
|
||||
if (NOT ARM_TARGET)
|
||||
@@ -17,31 +37,23 @@ if (NOT ARM_TARGET)
|
||||
endif()
|
||||
|
||||
if (ARM_TARGET AND ARM_TARGET GREATER 6)
|
||||
set(XMRIG_ARM ON)
|
||||
add_definitions(/DXMRIG_ARM)
|
||||
set(XMRIG_ARM ON)
|
||||
add_definitions(-DXMRIG_ARM=${ARM_TARGET})
|
||||
|
||||
message(STATUS "Use ARM_TARGET=${ARM_TARGET} (${CMAKE_SYSTEM_PROCESSOR})")
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
if (ARM_TARGET EQUAL 8)
|
||||
set(XMRIG_ARMv8 ON)
|
||||
add_definitions(/DXMRIG_ARMv8)
|
||||
|
||||
CHECK_CXX_COMPILER_FLAG(-march=armv8-a+crypto XMRIG_ARM_CRYPTO)
|
||||
|
||||
if (XMRIG_ARM_CRYPTO)
|
||||
add_definitions(/DXMRIG_ARM_CRYPTO)
|
||||
add_definitions(-DXMRIG_ARM_CRYPTO)
|
||||
set(ARM8_CXX_FLAGS "-march=armv8-a+crypto")
|
||||
else()
|
||||
set(ARM8_CXX_FLAGS "-march=armv8-a")
|
||||
endif()
|
||||
elseif (ARM_TARGET EQUAL 7)
|
||||
set(XMRIG_ARMv7 ON)
|
||||
add_definitions(/DXMRIG_ARMv7)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (WITH_SSE4_1)
|
||||
add_definitions(/DXMRIG_FEATURE_SSE4_1)
|
||||
add_definitions(-DXMRIG_FEATURE_SSE4_1)
|
||||
endif()
|
||||
|
||||
@@ -22,12 +22,12 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fexceptions -fno-rtti -Wno-strict-aliasing -Wno-class-memaccess")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s")
|
||||
|
||||
if (XMRIG_ARMv8)
|
||||
if (ARM_TARGET EQUAL 8)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARM8_CXX_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARM8_CXX_FLAGS} -flax-vector-conversions")
|
||||
elseif (XMRIG_ARMv7)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -flax-vector-conversions")
|
||||
elseif (ARM_TARGET EQUAL 7)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -mfpu=neon")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv7-a -mfpu=neon -flax-vector-conversions")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
|
||||
@@ -80,10 +80,10 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fexceptions -fno-rtti -Wno-missing-braces")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
|
||||
|
||||
if (XMRIG_ARMv8)
|
||||
if (ARM_TARGET EQUAL 8)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARM8_CXX_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARM8_CXX_FLAGS}")
|
||||
elseif (XMRIG_ARMv7)
|
||||
elseif (ARM_TARGET EQUAL 7)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon -march=${CMAKE_SYSTEM_PROCESSOR}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -march=${CMAKE_SYSTEM_PROCESSOR}")
|
||||
else()
|
||||
|
||||
8
cmake/ghostrider.cmake
Normal file
8
cmake/ghostrider.cmake
Normal file
@@ -0,0 +1,8 @@
|
||||
if (WITH_GHOSTRIDER)
|
||||
add_definitions(/DXMRIG_ALGO_GHOSTRIDER)
|
||||
add_subdirectory(src/crypto/ghostrider)
|
||||
set(GHOSTRIDER_LIBRARY ghostrider)
|
||||
else()
|
||||
remove_definitions(/DXMRIG_ALGO_GHOSTRIDER)
|
||||
set(GHOSTRIDER_LIBRARY "")
|
||||
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)
|
||||
|
||||
@@ -22,32 +22,31 @@ endif()
|
||||
|
||||
|
||||
if (XMRIG_OS_WIN)
|
||||
add_definitions(/DWIN32)
|
||||
add_definitions(/DXMRIG_OS_WIN)
|
||||
add_definitions(-DWIN32 -DXMRIG_OS_WIN)
|
||||
elseif(XMRIG_OS_APPLE)
|
||||
add_definitions(/DXMRIG_OS_APPLE)
|
||||
add_definitions(-DXMRIG_OS_APPLE)
|
||||
|
||||
if (XMRIG_OS_IOS)
|
||||
add_definitions(/DXMRIG_OS_IOS)
|
||||
add_definitions(-DXMRIG_OS_IOS)
|
||||
else()
|
||||
add_definitions(/DXMRIG_OS_MACOS)
|
||||
add_definitions(-DXMRIG_OS_MACOS)
|
||||
endif()
|
||||
|
||||
if (XMRIG_ARM)
|
||||
set(WITH_SECURE_JIT ON)
|
||||
endif()
|
||||
elseif(XMRIG_OS_UNIX)
|
||||
add_definitions(/DXMRIG_OS_UNIX)
|
||||
add_definitions(-DXMRIG_OS_UNIX)
|
||||
|
||||
if (XMRIG_OS_ANDROID)
|
||||
add_definitions(/DXMRIG_OS_ANDROID)
|
||||
add_definitions(-DXMRIG_OS_ANDROID)
|
||||
elseif (XMRIG_OS_LINUX)
|
||||
add_definitions(/DXMRIG_OS_LINUX)
|
||||
add_definitions(-DXMRIG_OS_LINUX)
|
||||
elseif (XMRIG_OS_FREEBSD)
|
||||
add_definitions(/DXMRIG_OS_FREEBSD)
|
||||
add_definitions(-DXMRIG_OS_FREEBSD)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (WITH_SECURE_JIT)
|
||||
add_definitions(/DXMRIG_SECURE_JIT)
|
||||
add_definitions(-DXMRIG_SECURE_JIT)
|
||||
endif()
|
||||
|
||||
@@ -42,13 +42,13 @@ if (WITH_RANDOMX)
|
||||
src/crypto/rx/RxVm.cpp
|
||||
)
|
||||
|
||||
if (CMAKE_C_COMPILER_ID MATCHES MSVC)
|
||||
if (WITH_ASM AND CMAKE_C_COMPILER_ID MATCHES MSVC)
|
||||
enable_language(ASM_MASM)
|
||||
list(APPEND SOURCES_CRYPTO
|
||||
src/crypto/randomx/jit_compiler_x86_static.asm
|
||||
src/crypto/randomx/jit_compiler_x86.cpp
|
||||
)
|
||||
elseif (NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
elseif (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
list(APPEND SOURCES_CRYPTO
|
||||
src/crypto/randomx/jit_compiler_x86_static.S
|
||||
src/crypto/randomx/jit_compiler_x86.cpp
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
HWLOC_VERSION="2.4.1"
|
||||
HWLOC_VERSION_MAJOR="2"
|
||||
HWLOC_VERSION_MINOR="7"
|
||||
HWLOC_VERSION_PATCH="1"
|
||||
|
||||
HWLOC_VERSION="${HWLOC_VERSION_MAJOR}.${HWLOC_VERSION_MINOR}.${HWLOC_VERSION_PATCH}"
|
||||
|
||||
mkdir -p deps
|
||||
mkdir -p deps/include
|
||||
@@ -8,7 +12,7 @@ mkdir -p deps/lib
|
||||
|
||||
mkdir -p build && cd build
|
||||
|
||||
wget https://download.open-mpi.org/release/hwloc/v2.4/hwloc-${HWLOC_VERSION}.tar.gz -O hwloc-${HWLOC_VERSION}.tar.gz
|
||||
wget https://download.open-mpi.org/release/hwloc/v${HWLOC_VERSION_MAJOR}.${HWLOC_VERSION_MINOR}/hwloc-${HWLOC_VERSION}.tar.gz -O hwloc-${HWLOC_VERSION}.tar.gz
|
||||
tar -xzf hwloc-${HWLOC_VERSION}.tar.gz
|
||||
|
||||
cd hwloc-${HWLOC_VERSION}
|
||||
@@ -16,4 +20,4 @@ cd hwloc-${HWLOC_VERSION}
|
||||
make -j$(nproc || sysctl -n hw.ncpu || sysctl -n hw.logicalcpu)
|
||||
cp -fr include ../../deps
|
||||
cp hwloc/.libs/libhwloc.a ../../deps/lib
|
||||
cd ..
|
||||
cd ..
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
LIBRESSL_VERSION="3.0.2"
|
||||
LIBRESSL_VERSION="3.5.2"
|
||||
|
||||
mkdir -p deps
|
||||
mkdir -p deps/include
|
||||
@@ -17,4 +17,4 @@ make -j$(nproc || sysctl -n hw.ncpu || sysctl -n hw.logicalcpu)
|
||||
cp -fr include ../../deps
|
||||
cp crypto/.libs/libcrypto.a ../../deps/lib
|
||||
cp ssl/.libs/libssl.a ../../deps/lib
|
||||
cd ..
|
||||
cd ..
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
OPENSSL_VERSION="1.1.1j"
|
||||
OPENSSL_VERSION="1.1.1o"
|
||||
|
||||
mkdir -p deps
|
||||
mkdir -p deps/include
|
||||
@@ -17,4 +17,4 @@ make -j$(nproc || sysctl -n hw.ncpu || sysctl -n hw.logicalcpu)
|
||||
cp -fr include ../../deps
|
||||
cp libcrypto.a ../../deps/lib
|
||||
cp libssl.a ../../deps/lib
|
||||
cd ..
|
||||
cd ..
|
||||
|
||||
20
scripts/build.openssl3.sh
Executable file
20
scripts/build.openssl3.sh
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
OPENSSL_VERSION="3.0.3"
|
||||
|
||||
mkdir -p deps
|
||||
mkdir -p deps/include
|
||||
mkdir -p deps/lib
|
||||
|
||||
mkdir -p build && cd build
|
||||
|
||||
wget https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz -O openssl-${OPENSSL_VERSION}.tar.gz
|
||||
tar -xzf openssl-${OPENSSL_VERSION}.tar.gz
|
||||
|
||||
cd openssl-${OPENSSL_VERSION}
|
||||
./config -no-shared -no-asm -no-zlib -no-comp -no-dgram -no-filenames -no-cms
|
||||
make -j$(nproc || sysctl -n hw.ncpu || sysctl -n hw.logicalcpu)
|
||||
cp -fr include ../../deps
|
||||
cp libcrypto.a ../../deps/lib
|
||||
cp libssl.a ../../deps/lib
|
||||
cd ..
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
UV_VERSION="1.41.0"
|
||||
UV_VERSION="1.44.1"
|
||||
|
||||
mkdir -p deps
|
||||
mkdir -p deps/include
|
||||
@@ -17,4 +17,4 @@ sh autogen.sh
|
||||
make -j$(nproc || sysctl -n hw.ncpu || sysctl -n hw.logicalcpu)
|
||||
cp -fr include ../../deps
|
||||
cp .libs/libuv.a ../../deps/lib
|
||||
cd ..
|
||||
cd ..
|
||||
|
||||
@@ -51,6 +51,7 @@ function rx()
|
||||
'randomx_constants_wow.h',
|
||||
'randomx_constants_arqma.h',
|
||||
'randomx_constants_keva.h',
|
||||
'randomx_constants_graft.h',
|
||||
'aes.cl',
|
||||
'blake2b.cl',
|
||||
'randomx_vm.cl',
|
||||
@@ -66,15 +67,6 @@ function rx()
|
||||
}
|
||||
|
||||
|
||||
function astrobwt()
|
||||
{
|
||||
const astrobwt = opencl_minify(addIncludes('astrobwt.cl', [ 'BWT.cl', 'salsa20.cl', 'sha3.cl' ]));
|
||||
|
||||
// fs.writeFileSync('astrobwt_gen.cl', astrobwt);
|
||||
fs.writeFileSync('astrobwt_cl.h', text2h(astrobwt, 'xmrig', 'astrobwt_cl'));
|
||||
}
|
||||
|
||||
|
||||
function kawpow()
|
||||
{
|
||||
const kawpow = opencl_minify(addIncludes('kawpow.cl', [ 'defs.h' ]));
|
||||
@@ -96,11 +88,6 @@ process.chdir(path.resolve('src/backend/opencl/cl/rx'));
|
||||
|
||||
rx();
|
||||
|
||||
process.chdir(cwd);
|
||||
process.chdir(path.resolve('src/backend/opencl/cl/astrobwt'));
|
||||
|
||||
astrobwt();
|
||||
|
||||
process.chdir(cwd);
|
||||
process.chdir(path.resolve('src/backend/opencl/cl/kawpow'));
|
||||
|
||||
|
||||
@@ -1,28 +1,34 @@
|
||||
#!/bin/bash
|
||||
#!/bin/sh -e
|
||||
|
||||
modprobe msr
|
||||
MSR_FILE=/sys/module/msr/parameters/allow_writes
|
||||
|
||||
if cat /proc/cpuinfo | grep "AMD Ryzen" > /dev/null;
|
||||
if test -e "$MSR_FILE"; then
|
||||
echo on > $MSR_FILE
|
||||
else
|
||||
modprobe msr allow_writes=on
|
||||
fi
|
||||
|
||||
if grep -E 'AMD Ryzen|AMD EPYC' /proc/cpuinfo > /dev/null;
|
||||
then
|
||||
if cat /proc/cpuinfo | grep "cpu family[[:space:]]:[[:space:]]25" > /dev/null;
|
||||
if grep "cpu family[[:space:]]:[[:space:]]25" /proc/cpuinfo > /dev/null;
|
||||
then
|
||||
echo "Detected Ryzen (Zen3)"
|
||||
echo "Detected Zen3 CPU"
|
||||
wrmsr -a 0xc0011020 0x4480000000000
|
||||
wrmsr -a 0xc0011021 0x1c000200000040
|
||||
wrmsr -a 0xc0011022 0xc000000401500000
|
||||
wrmsr -a 0xc001102b 0x2000cc14
|
||||
echo "MSR register values for Ryzen (Zen3) applied"
|
||||
echo "MSR register values for Zen3 applied"
|
||||
else
|
||||
echo "Detected Ryzen (Zen1/Zen2)"
|
||||
echo "Detected Zen1/Zen2 CPU"
|
||||
wrmsr -a 0xc0011020 0
|
||||
wrmsr -a 0xc0011021 0x40
|
||||
wrmsr -a 0xc0011022 0x1510000
|
||||
wrmsr -a 0xc001102b 0x2000cc16
|
||||
echo "MSR register values for Ryzen (Zen1/Zen2) applied"
|
||||
echo "MSR register values for Zen1/Zen2 applied"
|
||||
fi
|
||||
elif cat /proc/cpuinfo | grep "Intel" > /dev/null;
|
||||
elif grep "Intel" /proc/cpuinfo > /dev/null;
|
||||
then
|
||||
echo "Detected Intel"
|
||||
echo "Detected Intel CPU"
|
||||
wrmsr -a 0x1a4 0xf
|
||||
echo "MSR register values for Intel applied"
|
||||
else
|
||||
|
||||
23
scripts/rtm_ghostrider_example.cmd
Normal file
23
scripts/rtm_ghostrider_example.cmd
Normal file
@@ -0,0 +1,23 @@
|
||||
:: Example batch file for mining Raptoreum at a pool
|
||||
::
|
||||
:: Format:
|
||||
:: xmrig.exe -a gr -o <pool address>:<pool port> -u <pool username/wallet> -p <pool password>
|
||||
::
|
||||
:: Fields:
|
||||
:: pool address The host name of the pool stratum or its IP address, for example raptoreumemporium.com
|
||||
:: pool port The port of the pool's stratum to connect to, for example 3333. Check your pool's getting started page.
|
||||
:: pool username/wallet For most pools, this is the wallet address you want to mine to. Some pools require a username
|
||||
:: pool password For most pools this can be just 'x'. For pools using usernames, you may need to provide a password as configured on the pool.
|
||||
::
|
||||
:: List of Raptoreum mining pools:
|
||||
:: https://miningpoolstats.stream/raptoreum
|
||||
::
|
||||
:: Choose pools outside of top 5 to help Raptoreum network be more decentralized!
|
||||
:: Smaller pools also often have smaller fees/payout limits.
|
||||
|
||||
cd %~dp0
|
||||
:: Use this command line to connect to non-SSL port
|
||||
xmrig.exe -a gr -o raptoreumemporium.com:3008 -u WALLET_ADDRESS -p x
|
||||
:: Or use this command line to connect to an SSL port
|
||||
:: xmrig.exe -a gr -o rtm.suprnova.cc:4273 --tls -u WALLET_ADDRESS -p x
|
||||
pause
|
||||
4
src/3rdparty/CL/cl_dx9_media_sharing.h
vendored
4
src/3rdparty/CL/cl_dx9_media_sharing.h
vendored
@@ -44,7 +44,7 @@ extern "C" {
|
||||
|
||||
typedef cl_uint cl_dx9_media_adapter_type_khr;
|
||||
typedef cl_uint cl_dx9_media_adapter_set_khr;
|
||||
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <d3d9.h>
|
||||
typedef struct _cl_dx9_surface_info_khr
|
||||
@@ -105,7 +105,7 @@ typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromDX9MediaSurfaceKHR_fn)(
|
||||
cl_mem_flags flags,
|
||||
cl_dx9_media_adapter_type_khr adapter_type,
|
||||
void * surface_info,
|
||||
cl_uint plane,
|
||||
cl_uint plane,
|
||||
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_2;
|
||||
|
||||
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueAcquireDX9MediaSurfacesKHR_fn)(
|
||||
|
||||
2
src/3rdparty/CL/cl_gl_ext.h
vendored
2
src/3rdparty/CL/cl_gl_ext.h
vendored
@@ -35,7 +35,7 @@ extern "C" {
|
||||
|
||||
#include <CL/cl_gl.h>
|
||||
|
||||
/*
|
||||
/*
|
||||
* cl_khr_gl_event extension
|
||||
*/
|
||||
#define CL_COMMAND_GL_FENCE_SYNC_OBJECT_KHR 0x200D
|
||||
|
||||
12
src/3rdparty/adl/adl_defines.h
vendored
12
src/3rdparty/adl/adl_defines.h
vendored
@@ -1471,7 +1471,7 @@ typedef enum _ADLProfilePropertyType
|
||||
#define ADL_HDR_FREESYNC_HDR 0x0004 ///< FreeSync HDR supported
|
||||
/// @}
|
||||
|
||||
/// \defgroup define_FreesyncFlags ADLDDCInfo2 Freesync HDR flags
|
||||
/// \defgroup define_FreesyncFlags ADLDDCInfo2 Freesync HDR flags
|
||||
/// @{
|
||||
/// defines for iFreesyncFlags in ADLDDCInfo2
|
||||
#define ADL_HDR_FREESYNC_BACKLIGHT_SUPPORT 0x0001 ///< Global backlight control supported
|
||||
@@ -1738,7 +1738,7 @@ enum ADLODNDPMMaskType
|
||||
ADL_ODN_DPM_MASK = 1 << 2,
|
||||
};
|
||||
|
||||
//ODN features Bits for ADLODNCapabilitiesX2
|
||||
//ODN features Bits for ADLODNCapabilitiesX2
|
||||
enum ADLODNFeatureControl
|
||||
{
|
||||
ADL_ODN_SCLK_DPM = 1 << 0,
|
||||
@@ -1764,7 +1764,7 @@ enum ADLODNFeatureControl
|
||||
|
||||
//If any new feature is added, PPLIB only needs to add ext feature ID and Item ID(Seeting ID). These IDs should match the drive defined in CWDDEPM.h
|
||||
enum ADLODNExtFeatureControl
|
||||
{
|
||||
{
|
||||
ADL_ODN_EXT_FEATURE_MEMORY_TIMING_TUNE = 1 << 0,
|
||||
ADL_ODN_EXT_FEATURE_FAN_ZERO_RPM_CONTROL = 1 << 1,
|
||||
ADL_ODN_EXT_FEATURE_AUTO_UV_ENGINE = 1 << 2, //Auto under voltage
|
||||
@@ -1794,7 +1794,7 @@ enum ADLODNExtSettingId
|
||||
ADL_ODN_PARAMETER_FAN_CURVE_SPEED_5,
|
||||
ADL_ODN_POWERGAUGE,
|
||||
ODN_COUNT
|
||||
|
||||
|
||||
} ;
|
||||
|
||||
//OD8 Capability features bits
|
||||
@@ -1811,7 +1811,7 @@ enum ADLOD8FeatureControl
|
||||
ADL_OD8_MEMORY_TIMING_TUNE = 1 << 8,
|
||||
ADL_OD8_FAN_ZERO_RPM_CONTROL = 1 << 9 ,
|
||||
ADL_OD8_AUTO_UV_ENGINE = 1 << 10, //Auto under voltage
|
||||
ADL_OD8_AUTO_OC_ENGINE = 1 << 11, //Auto overclock engine
|
||||
ADL_OD8_AUTO_OC_ENGINE = 1 << 11, //Auto overclock engine
|
||||
ADL_OD8_AUTO_OC_MEMORY = 1 << 12, //Auto overclock memory
|
||||
ADL_OD8_FAN_CURVE = 1 << 13, //Fan curve
|
||||
ADL_OD8_WS_AUTO_FAN_ACOUSTIC_LIMIT = 1 << 14, //Workstation Manual Fan controller
|
||||
@@ -1888,7 +1888,7 @@ typedef enum _ADLSensorType
|
||||
PMLOG_TEMPERATURE_VRSOC = 24,
|
||||
PMLOG_TEMPERATURE_VRMVDD0 = 25,
|
||||
PMLOG_TEMPERATURE_VRMVDD1 = 26,
|
||||
PMLOG_TEMPERATURE_HOTSPOT = 27,
|
||||
PMLOG_TEMPERATURE_HOTSPOT = 27,
|
||||
PMLOG_TEMPERATURE_GFX = 28,
|
||||
PMLOG_TEMPERATURE_SOC = 29,
|
||||
PMLOG_GFX_POWER = 30,
|
||||
|
||||
2
src/3rdparty/adl/adl_sdk.h
vendored
2
src/3rdparty/adl/adl_sdk.h
vendored
@@ -37,7 +37,7 @@
|
||||
#define __stdcall
|
||||
#endif /* (LINUX) */
|
||||
|
||||
/// Memory Allocation Call back
|
||||
/// Memory Allocation Call back
|
||||
typedef void* ( __stdcall *ADL_MAIN_MALLOC_CALLBACK )( int );
|
||||
|
||||
|
||||
|
||||
2
src/3rdparty/adl/adl_structures.h
vendored
2
src/3rdparty/adl/adl_structures.h
vendored
@@ -1753,7 +1753,7 @@ typedef struct ADLPXConfigCaps
|
||||
///\brief Enum containing PX or HG type
|
||||
///
|
||||
/// This enum is used to get PX or hG type
|
||||
///
|
||||
///
|
||||
/// \nosubgrouping
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
enum ADLPxType
|
||||
|
||||
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_
|
||||
10
src/3rdparty/getopt/getopt.h
vendored
10
src/3rdparty/getopt/getopt.h
vendored
@@ -3,9 +3,9 @@
|
||||
* DISCLAIMER
|
||||
* This file is part of the mingw-w64 runtime package.
|
||||
*
|
||||
* The mingw-w64 runtime package and its code is distributed in the hope that it
|
||||
* will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR
|
||||
* IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to
|
||||
* The mingw-w64 runtime package and its code is distributed in the hope that it
|
||||
* will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR
|
||||
* IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to
|
||||
* warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
/*
|
||||
@@ -109,11 +109,7 @@ char *optarg; /* argument associated with option */
|
||||
extern char __declspec(dllimport) *__progname;
|
||||
#endif
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
static char EMSG[] = "";
|
||||
#else
|
||||
#define EMSG ""
|
||||
#endif
|
||||
|
||||
static int getopt_internal(int, char * const *, const char *,
|
||||
const struct option *, int *, int);
|
||||
|
||||
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.
|
||||
1826
src/3rdparty/hwloc/NEWS
vendored
1826
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=4
|
||||
release=0
|
||||
|
||||
# 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="Nov 26, 2020"
|
||||
|
||||
# If snapshot=1, then use the value from snapshot_version as the
|
||||
# entire hwloc version (i.e., ignore major, minor, release, and
|
||||
# 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=19:0:4
|
||||
libnetloc_so_version=0:0:0
|
||||
|
||||
# Please also update the <TargetName> lines in contrib/windows/libhwloc.vcxproj
|
||||
2479
src/3rdparty/hwloc/include/hwloc.h
vendored
2479
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-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.
|
||||
*/
|
||||
|
||||
/* The configuration file */
|
||||
|
||||
#ifndef HWLOC_CONFIG_H
|
||||
#define HWLOC_CONFIG_H
|
||||
|
||||
#define HWLOC_VERSION "2.4.1"
|
||||
#define HWLOC_VERSION_MAJOR 2
|
||||
#define HWLOC_VERSION_MINOR 4
|
||||
#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 */
|
||||
188
src/3rdparty/hwloc/include/hwloc/cpukinds.h
vendored
188
src/3rdparty/hwloc/include/hwloc/cpukinds.h
vendored
@@ -1,188 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2020 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Kinds of CPU cores.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_CPUKINDS_H
|
||||
#define HWLOC_CPUKINDS_H
|
||||
|
||||
#include "hwloc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#elif 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \defgroup hwlocality_cpukinds Kinds of CPU cores
|
||||
*
|
||||
* Platforms with heterogeneous CPUs may have some cores with
|
||||
* different features or frequencies.
|
||||
* This API exposes identical PUs in sets called CPU kinds.
|
||||
* Each PU of the topology may only be in a single kind.
|
||||
*
|
||||
* The number of kinds may be obtained with hwloc_cpukinds_get_nr().
|
||||
* If the platform is homogeneous, there may be a single kind
|
||||
* with all PUs.
|
||||
* If the platform or operating system does not expose any
|
||||
* information about CPU cores, there may be no kind at all.
|
||||
*
|
||||
* The index of the kind that describes a given CPU set
|
||||
* (if any, and not partially)
|
||||
* may be obtained with hwloc_cpukinds_get_by_cpuset().
|
||||
*
|
||||
* From the index of a kind, it is possible to retrieve information
|
||||
* with hwloc_cpukinds_get_info():
|
||||
* an abstracted efficiency value,
|
||||
* and an array of info attributes
|
||||
* (for instance the "CoreType" and "FrequencyMaxMHz",
|
||||
* see \ref topoattrs_cpukinds).
|
||||
*
|
||||
* A higher efficiency value means intrinsic greater performance
|
||||
* (and possibly less performance/power efficiency).
|
||||
* Kinds with lower efficiency are ranked first:
|
||||
* Passing 0 as \p kind_index to hwloc_cpukinds_get_info() will
|
||||
* return information about the less efficient CPU kind.
|
||||
*
|
||||
* When available, efficiency values are gathered from the operating
|
||||
* system (when \p cpukind_efficiency is set in the
|
||||
* struct hwloc_topology_discovery_support array, only on Windows 10 for now).
|
||||
* Otherwise hwloc tries to compute efficiencies
|
||||
* by comparing CPU kinds using frequencies (on ARM),
|
||||
* or core types and frequencies (on other architectures).
|
||||
* The environment variable HWLOC_CPUKINDS_RANKING may be used
|
||||
* to change this heuristics, see \ref envvar.
|
||||
*
|
||||
* If hwloc fails to rank any kind, for instance because the operating
|
||||
* system does not expose efficiencies and core frequencies,
|
||||
* all kinds will have an unknown efficiency (\c -1),
|
||||
* and they are not indexed/ordered in any specific way.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Get the number of different kinds of CPU cores in the topology.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* \return The number of CPU kinds (positive integer) on success.
|
||||
* \return \c 0 if no information about kinds was found.
|
||||
* \return \c -1 with \p errno set to \c EINVAL if \p flags is invalid.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_cpukinds_get_nr(hwloc_topology_t topology,
|
||||
unsigned long flags);
|
||||
|
||||
/** \brief Get the index of the CPU kind that contains CPUs listed in \p cpuset.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* \return The index of the CPU kind (positive integer or 0) on success.
|
||||
* \return \c -1 with \p errno set to \c EXDEV if \p cpuset is
|
||||
* only partially included in the some kind.
|
||||
* \return \c -1 with \p errno set to \c ENOENT if \p cpuset is
|
||||
* not included in any kind, even partially.
|
||||
* \return \c -1 with \p errno set to \c EINVAL if parameters are invalid.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_cpukinds_get_by_cpuset(hwloc_topology_t topology,
|
||||
hwloc_const_bitmap_t cpuset,
|
||||
unsigned long flags);
|
||||
|
||||
/** \brief Get the CPU set and infos about a CPU kind in the topology.
|
||||
*
|
||||
* \p kind_index identifies one kind of CPU between 0 and the number
|
||||
* of kinds returned by hwloc_cpukinds_get_nr() minus 1.
|
||||
*
|
||||
* If not \c NULL, the bitmap \p cpuset will be filled with
|
||||
* the set of PUs of this kind.
|
||||
*
|
||||
* The integer pointed by \p efficiency, if not \c NULL will, be filled
|
||||
* with the ranking of this kind of CPU in term of efficiency (see above).
|
||||
* It ranges from \c 0 to the number of kinds
|
||||
* (as reported by hwloc_cpukinds_get_nr()) minus 1.
|
||||
*
|
||||
* Kinds with lower efficiency are reported first.
|
||||
*
|
||||
* If there is a single kind in the topology, its efficiency \c 0.
|
||||
* If the efficiency of some kinds of cores is unknown,
|
||||
* the efficiency of all kinds is set to \c -1,
|
||||
* and kinds are reported in no specific order.
|
||||
*
|
||||
* The array of info attributes (for instance the "CoreType",
|
||||
* "FrequencyMaxMHz" or "FrequencyBaseMHz", see \ref topoattrs_cpukinds)
|
||||
* and its length are returned in \p infos or \p nr_infos.
|
||||
* The array belongs to the topology, it should not be freed or modified.
|
||||
*
|
||||
* If \p nr_infos or \p infos is \c NULL, no info is returned.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c -1 with \p errno set to \c ENOENT if \p kind_index does not match any CPU kind.
|
||||
* \return \c -1 with \p errno set to \c EINVAL if parameters are invalid.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_cpukinds_get_info(hwloc_topology_t topology,
|
||||
unsigned kind_index,
|
||||
hwloc_bitmap_t cpuset,
|
||||
int *efficiency,
|
||||
unsigned *nr_infos, struct hwloc_info_s **infos,
|
||||
unsigned long flags);
|
||||
|
||||
/** \brief Register a kind of CPU in the topology.
|
||||
*
|
||||
* Mark the PUs listed in \p cpuset as being of the same kind
|
||||
* with respect to the given attributes.
|
||||
*
|
||||
* \p forced_efficiency should be \c -1 if unknown.
|
||||
* Otherwise it is an abstracted efficiency value to enforce
|
||||
* the ranking of all kinds if all of them have valid (and
|
||||
* different) efficiencies.
|
||||
*
|
||||
* The array \p infos of size \p nr_infos may be used to provide
|
||||
* info names and values describing this kind of PUs.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* Parameters \p cpuset and \p infos will be duplicated internally,
|
||||
* the caller is responsible for freeing them.
|
||||
*
|
||||
* If \p cpuset overlaps with some existing kinds, those might get
|
||||
* modified or split. For instance if existing kind A contains
|
||||
* PUs 0 and 1, and one registers another kind for PU 1 and 2,
|
||||
* there will be 3 resulting kinds:
|
||||
* existing kind A is restricted to only PU 0;
|
||||
* new kind B contains only PU 1 and combines information from A
|
||||
* and from the newly-registered kind;
|
||||
* new kind C contains only PU 2 and only gets information from
|
||||
* the newly-registered kind.
|
||||
*
|
||||
* \note The efficiency \p forced_efficiency provided to this function
|
||||
* may be different from the one reported later by hwloc_cpukinds_get_info()
|
||||
* because hwloc will scale efficiency values down to
|
||||
* between 0 and the number of kinds minus 1.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c -1 with \p errno set to \c EINVAL if some parameters are invalid,
|
||||
* for instance if \p cpuset is \c NULL or empty.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_cpukinds_register(hwloc_topology_t topology,
|
||||
hwloc_bitmap_t cpuset,
|
||||
int forced_efficiency,
|
||||
unsigned nr_infos, struct hwloc_info_s *infos,
|
||||
unsigned long flags);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_CPUKINDS_H */
|
||||
220
src/3rdparty/hwloc/include/hwloc/cuda.h
vendored
220
src/3rdparty/hwloc/include/hwloc/cuda.h
vendored
@@ -1,220 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2010-2020 Inria. All rights reserved.
|
||||
* Copyright © 2010-2011 Université Bordeaux
|
||||
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \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.
|
||||
*
|
||||
* Return 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 PCI device object describing the CUDA device \p cudevice.
|
||||
* Return NULL if there is none.
|
||||
*
|
||||
* 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 NULL if there is none.
|
||||
*
|
||||
* 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 OS device object describing the CUDA 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 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-2020 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.
|
||||
*
|
||||
* Return 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 PCI device object describing the CUDA device whose
|
||||
* index is \p idx. Return NULL if there is none.
|
||||
*
|
||||
* 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 OS device object describing the CUDA 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 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 */
|
||||
208
src/3rdparty/hwloc/include/hwloc/deprecated.h
vendored
208
src/3rdparty/hwloc/include/hwloc/deprecated.h
vendored
@@ -1,208 +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_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 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 */
|
||||
297
src/3rdparty/hwloc/include/hwloc/distances.h
vendored
297
src/3rdparty/hwloc/include/hwloc/distances.h
vendored
@@ -1,297 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2010-2020 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".
|
||||
*
|
||||
* The matrix may also contain bandwidths between random sets of objects,
|
||||
* possibly provided by the user, as specified in the \p kind attribute.
|
||||
*/
|
||||
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.
|
||||
* \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".
|
||||
*/
|
||||
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);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
/** \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 or remove distances between objects
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \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.
|
||||
* \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 Provide a new distance matrix.
|
||||
*
|
||||
* Provide the matrix of distances between a set of objects given by \p nbobjs
|
||||
* and the \p objs array. \p nbobjs must be at least 2.
|
||||
* The distances 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 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 added
|
||||
* if objects of different types are given.
|
||||
*
|
||||
* \p flags configures the behavior of the function using an optional OR'ed set of
|
||||
* ::hwloc_distances_add_flag_e.
|
||||
*/
|
||||
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);
|
||||
|
||||
/** \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 */
|
||||
135
src/3rdparty/hwloc/include/hwloc/gl.h
vendored
135
src/3rdparty/hwloc/include/hwloc/gl.h
vendored
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Blue Brain Project, EPFL. All rights reserved.
|
||||
* Copyright © 2012-2013 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 OS device object describing the OpenGL display
|
||||
* whose port (server) is \p port and device (screen) is \p device.
|
||||
* 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 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 OS device object describing the OpenGL display
|
||||
* whose name is \p name, built as ":port.device" such as ":0.0" .
|
||||
* 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 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.
|
||||
*
|
||||
* Return 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 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 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 */
|
||||
1188
src/3rdparty/hwloc/include/hwloc/helper.h
vendored
1188
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 */
|
||||
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 */
|
||||
80
src/3rdparty/hwloc/include/hwloc/linux.h
vendored
80
src/3rdparty/hwloc/include/hwloc/linux.h
vendored
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2016 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 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.
|
||||
*
|
||||
* \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-2020 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Memory node attributes.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_MEMATTR_H
|
||||
#define HWLOC_MEMATTR_H
|
||||
|
||||
#include "hwloc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#elif 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \defgroup hwlocality_memattrs Comparing memory node attributes for finding where to allocate on
|
||||
*
|
||||
* Platforms with heterogeneous memory require ways to decide whether
|
||||
* a buffer should be allocated on "fast" memory (such as HBM),
|
||||
* "normal" memory (DDR) or even "slow" but large-capacity memory
|
||||
* (non-volatile memory).
|
||||
* These memory nodes are called "Targets" while the CPU accessing them
|
||||
* is called the "Initiator". Access performance depends on their
|
||||
* locality (NUMA platforms) as well as the intrinsic performance
|
||||
* of the targets (heterogeneous platforms).
|
||||
*
|
||||
* The following attributes describe the performance of memory accesses
|
||||
* from an Initiator to a memory Target, for instance their latency
|
||||
* or bandwidth.
|
||||
* Initiators performing these memory accesses are usually some PUs or Cores
|
||||
* (described as a CPU set).
|
||||
* Hence a Core may choose where to allocate a memory buffer by comparing
|
||||
* the attributes of different target memory nodes nearby.
|
||||
*
|
||||
* There are also some attributes that are system-wide.
|
||||
* Their value does not depend on a specific initiator performing
|
||||
* an access.
|
||||
* The memory node Capacity is an example of such attribute without
|
||||
* initiator.
|
||||
*
|
||||
* One way to use this API is to start with a cpuset describing the Cores where
|
||||
* a program is bound. The best target NUMA node for allocating memory in this
|
||||
* program on these Cores may be obtained by passing this cpuset as an initiator
|
||||
* to hwloc_memattr_get_best_target() with the relevant memory attribute.
|
||||
* For instance, if the code is latency limited, use the Latency attribute.
|
||||
*
|
||||
* A more flexible approach consists in getting the list of local NUMA nodes
|
||||
* by passing this cpuset to hwloc_get_local_numanode_objs().
|
||||
* Attribute values for these nodes, if any, may then be obtained with
|
||||
* hwloc_memattr_get_value() and manually compared with the desired criteria.
|
||||
*
|
||||
* \note The API also supports specific objects as initiator,
|
||||
* but it is currently not used internally by hwloc.
|
||||
* Users may for instance use it to provide custom performance
|
||||
* values for host memory accesses performed by GPUs.
|
||||
*
|
||||
* \note The interface actually also accepts targets that are not NUMA nodes.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Memory node attributes. */
|
||||
enum hwloc_memattr_id_e {
|
||||
/** \brief "Capacity".
|
||||
* The capacity is returned in bytes
|
||||
* (local_memory attribute in objects).
|
||||
*
|
||||
* Best capacity nodes are nodes with <b>higher capacity</b>.
|
||||
*
|
||||
* No initiator is involved when looking at this attribute.
|
||||
* The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST.
|
||||
*/
|
||||
HWLOC_MEMATTR_ID_CAPACITY = 0,
|
||||
|
||||
/** \brief "Locality".
|
||||
* The locality is returned as the number of PUs in that locality
|
||||
* (e.g. the weight of its cpuset).
|
||||
*
|
||||
* Best locality nodes are nodes with <b>smaller locality</b>
|
||||
* (nodes that are local to very few PUs).
|
||||
* Poor locality nodes are nodes with larger locality
|
||||
* (nodes that are local to the entire machine).
|
||||
*
|
||||
* No initiator is involved when looking at this attribute.
|
||||
* The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST.
|
||||
*/
|
||||
HWLOC_MEMATTR_ID_LOCALITY = 1,
|
||||
|
||||
/** \brief "Bandwidth".
|
||||
* The bandwidth is returned in MiB/s, as seen from the given initiator location.
|
||||
* Best bandwidth nodes are nodes with <b>higher bandwidth</b>.
|
||||
* The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST
|
||||
* and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
|
||||
*/
|
||||
HWLOC_MEMATTR_ID_BANDWIDTH = 2,
|
||||
|
||||
/** \brief "Latency".
|
||||
* The latency is returned as nanoseconds, as seen from the given initiator location.
|
||||
* Best latency nodes are nodes with <b>smaller latency</b>.
|
||||
* The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_LOWER_FIRST
|
||||
* and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
|
||||
*/
|
||||
HWLOC_MEMATTR_ID_LATENCY = 3
|
||||
|
||||
/* TODO read vs write, persistence? */
|
||||
};
|
||||
|
||||
/** \brief A memory attribute identifier.
|
||||
* May be either one of ::hwloc_memattr_id_e or a new id returned by hwloc_memattr_register().
|
||||
*/
|
||||
typedef unsigned hwloc_memattr_id_t;
|
||||
|
||||
/** \brief Return the identifier of the memory attribute with the given name.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_get_by_name(hwloc_topology_t topology,
|
||||
const char *name,
|
||||
hwloc_memattr_id_t *id);
|
||||
|
||||
|
||||
/** \brief Type of location. */
|
||||
enum hwloc_location_type_e {
|
||||
/** \brief Location is given as a cpuset, in the location cpuset union field. \hideinitializer */
|
||||
HWLOC_LOCATION_TYPE_CPUSET = 1,
|
||||
/** \brief Location is given as an object, in the location object union field. \hideinitializer */
|
||||
HWLOC_LOCATION_TYPE_OBJECT = 0
|
||||
};
|
||||
|
||||
/** \brief Where to measure attributes from. */
|
||||
struct hwloc_location {
|
||||
/** \brief Type of location. */
|
||||
enum hwloc_location_type_e type;
|
||||
/** \brief Actual location. */
|
||||
union hwloc_location_u {
|
||||
/** \brief Location as a cpuset, when the location type is ::HWLOC_LOCATION_TYPE_CPUSET. */
|
||||
hwloc_cpuset_t cpuset;
|
||||
/** \brief Location as an object, when the location type is ::HWLOC_LOCATION_TYPE_OBJECT. */
|
||||
hwloc_obj_t object;
|
||||
} location;
|
||||
};
|
||||
|
||||
|
||||
/** \brief Flags for selecting target NUMA nodes. */
|
||||
enum hwloc_local_numanode_flag_e {
|
||||
/** \brief Select NUMA nodes whose locality is larger than the given cpuset.
|
||||
* For instance, if a single PU (or its cpuset) is given in \p initiator,
|
||||
* select all nodes close to the package that contains this PU.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY = (1UL<<0),
|
||||
|
||||
/** \brief Select NUMA nodes whose locality is smaller than the given cpuset.
|
||||
* For instance, if a package (or its cpuset) is given in \p initiator,
|
||||
* also select nodes that are attached to only a half of that package.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY = (1UL<<1),
|
||||
|
||||
/** \brief Select all NUMA nodes in the topology.
|
||||
* The initiator \p initiator is ignored.
|
||||
* \hideinitializer
|
||||
*/
|
||||
HWLOC_LOCAL_NUMANODE_FLAG_ALL = (1UL<<2)
|
||||
};
|
||||
|
||||
/** \brief Return an array of local NUMA nodes.
|
||||
*
|
||||
* By default only select the NUMA nodes whose locality is exactly
|
||||
* the given \p location. More nodes may be selected if additional flags
|
||||
* are given as a OR'ed set of ::hwloc_local_numanode_flag_e.
|
||||
*
|
||||
* If \p location is given as an explicit object, its CPU set is used
|
||||
* to find NUMA nodes with the corresponding locality.
|
||||
* If the object does not have a CPU set (e.g. I/O object), the CPU
|
||||
* parent (where the I/O object is attached) is used.
|
||||
*
|
||||
* On input, \p nr points to the number of nodes that may be stored
|
||||
* in the \p nodes array.
|
||||
* On output, \p nr will be changed to the number of stored nodes,
|
||||
* or the number of nodes that would have been stored if there were
|
||||
* enough room.
|
||||
*
|
||||
* \note Some of these NUMA nodes may not have any memory attribute
|
||||
* values and hence not be reported as actual targets in other functions.
|
||||
*
|
||||
* \note The number of NUMA nodes in the topology (obtained by
|
||||
* hwloc_bitmap_weight() on the root object nodeset) may be used
|
||||
* to allocate the \p nodes array.
|
||||
*
|
||||
* \note When an object CPU set is given as locality, for instance a Package,
|
||||
* and when flags contain both ::HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY
|
||||
* and ::HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY,
|
||||
* the returned array corresponds to the nodeset of that object.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_get_local_numanode_objs(hwloc_topology_t topology,
|
||||
struct hwloc_location *location,
|
||||
unsigned *nr,
|
||||
hwloc_obj_t *nodes,
|
||||
unsigned long flags);
|
||||
|
||||
|
||||
|
||||
/** \brief Return an attribute value for a specific target NUMA node.
|
||||
*
|
||||
* If the attribute does not relate to a specific initiator
|
||||
* (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
|
||||
* location \p initiator is ignored and may be \c NULL.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
|
||||
* when refering to accesses performed by CPU cores.
|
||||
* ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
|
||||
* but users may for instance use it to provide custom information about
|
||||
* host memory accesses performed by GPUs.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_get_value(hwloc_topology_t topology,
|
||||
hwloc_memattr_id_t attribute,
|
||||
hwloc_obj_t target_node,
|
||||
struct hwloc_location *initiator,
|
||||
unsigned long flags,
|
||||
hwloc_uint64_t *value);
|
||||
|
||||
/** \brief Return the best target NUMA node for the given attribute and initiator.
|
||||
*
|
||||
* If the attribute does not relate to a specific initiator
|
||||
* (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
|
||||
* location \p initiator is ignored and may be \c NULL.
|
||||
*
|
||||
* If \p value is non \c NULL, the corresponding value is returned there.
|
||||
*
|
||||
* If multiple targets have the same attribute values, only one is
|
||||
* returned (and there is no way to clarify how that one is chosen).
|
||||
* Applications that want to detect targets with identical/similar
|
||||
* values, or that want to look at values for multiple attributes,
|
||||
* should rather get all values using hwloc_memattr_get_value()
|
||||
* and manually select the target they consider the best.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* If there are no matching targets, \c -1 is returned with \p errno set to \c ENOENT;
|
||||
*
|
||||
* \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
|
||||
* when refering to accesses performed by CPU cores.
|
||||
* ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
|
||||
* but users may for instance use it to provide custom information about
|
||||
* host memory accesses performed by GPUs.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_get_best_target(hwloc_topology_t topology,
|
||||
hwloc_memattr_id_t attribute,
|
||||
struct hwloc_location *initiator,
|
||||
unsigned long flags,
|
||||
hwloc_obj_t *best_target, hwloc_uint64_t *value);
|
||||
|
||||
/** \brief Return the best initiator for the given attribute and target NUMA node.
|
||||
*
|
||||
* If the attribute does not relate to a specific initiator
|
||||
* (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
|
||||
* \c -1 is returned and \p errno is set to \c EINVAL.
|
||||
*
|
||||
* If \p value is non \c NULL, the corresponding value is returned there.
|
||||
*
|
||||
* If multiple initiators have the same attribute values, only one is
|
||||
* returned (and there is no way to clarify how that one is chosen).
|
||||
* Applications that want to detect initiators with identical/similar
|
||||
* values, or that want to look at values for multiple attributes,
|
||||
* should rather get all values using hwloc_memattr_get_value()
|
||||
* and manually select the initiator they consider the best.
|
||||
*
|
||||
* The returned initiator should not be modified or freed,
|
||||
* it belongs to the topology.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* If there are no matching initiators, \c -1 is returned with \p errno set to \c ENOENT;
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_get_best_initiator(hwloc_topology_t topology,
|
||||
hwloc_memattr_id_t attribute,
|
||||
hwloc_obj_t target,
|
||||
unsigned long flags,
|
||||
struct hwloc_location *best_initiator, hwloc_uint64_t *value);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/** \defgroup hwlocality_memattrs_manage Managing memory attributes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Return the name of a memory attribute.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_get_name(hwloc_topology_t topology,
|
||||
hwloc_memattr_id_t attribute,
|
||||
const char **name);
|
||||
|
||||
/** \brief Return the flags of the given attribute.
|
||||
*
|
||||
* Flags are a OR'ed set of ::hwloc_memattr_flag_e.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_get_flags(hwloc_topology_t topology,
|
||||
hwloc_memattr_id_t attribute,
|
||||
unsigned long *flags);
|
||||
|
||||
/** \brief Memory attribute flags.
|
||||
* Given to hwloc_memattr_register() and returned by hwloc_memattr_get_flags().
|
||||
*/
|
||||
enum hwloc_memattr_flag_e {
|
||||
/** \brief The best nodes for this memory attribute are those with the higher values.
|
||||
* For instance Bandwidth.
|
||||
*/
|
||||
HWLOC_MEMATTR_FLAG_HIGHER_FIRST = (1UL<<0),
|
||||
/** \brief The best nodes for this memory attribute are those with the lower values.
|
||||
* For instance Latency.
|
||||
*/
|
||||
HWLOC_MEMATTR_FLAG_LOWER_FIRST = (1UL<<1),
|
||||
/** \brief The value returned for this memory attribute depends on the given initiator.
|
||||
* For instance Bandwidth and Latency, but not Capacity.
|
||||
*/
|
||||
HWLOC_MEMATTR_FLAG_NEED_INITIATOR = (1UL<<2)
|
||||
};
|
||||
|
||||
/** \brief Register a new memory attribute.
|
||||
*
|
||||
* Add a specific memory attribute that is not defined in ::hwloc_memattr_id_e.
|
||||
* Flags are a OR'ed set of ::hwloc_memattr_flag_e. It must contain at least
|
||||
* one of ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST or ::HWLOC_MEMATTR_FLAG_LOWER_FIRST.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_register(hwloc_topology_t topology,
|
||||
const char *name,
|
||||
unsigned long flags,
|
||||
hwloc_memattr_id_t *id);
|
||||
|
||||
/** \brief Set an attribute value for a specific target NUMA node.
|
||||
*
|
||||
* If the attribute does not relate to a specific initiator
|
||||
* (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
|
||||
* location \p initiator is ignored and may be \c NULL.
|
||||
*
|
||||
* The initiator will be copied into the topology,
|
||||
* the caller should free anything allocated to store the initiator,
|
||||
* for instance the cpuset.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
|
||||
* when refering to accesses performed by CPU cores.
|
||||
* ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
|
||||
* but users may for instance use it to provide custom information about
|
||||
* host memory accesses performed by GPUs.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_set_value(hwloc_topology_t topology,
|
||||
hwloc_memattr_id_t attribute,
|
||||
hwloc_obj_t target_node,
|
||||
struct hwloc_location *initiator,
|
||||
unsigned long flags,
|
||||
hwloc_uint64_t value);
|
||||
|
||||
/** \brief Return the target NUMA nodes that have some values for a given attribute.
|
||||
*
|
||||
* Return targets for the given attribute in the \p targets array
|
||||
* (for the given initiator if any).
|
||||
* If \p values is not \c NULL, the corresponding attribute values
|
||||
* are stored in the array it points to.
|
||||
*
|
||||
* On input, \p nr points to the number of targets that may be stored
|
||||
* in the array \p targets (and \p values).
|
||||
* On output, \p nr points to the number of targets (and values) that
|
||||
* were actually found, even if some of them couldn't be stored in the array.
|
||||
* Targets that couldn't be stored are ignored, but the function still
|
||||
* returns success (\c 0). The caller may find out by comparing the value pointed
|
||||
* by \p nr before and after the function call.
|
||||
*
|
||||
* The returned targets should not be modified or freed,
|
||||
* they belong to the topology.
|
||||
*
|
||||
* Argument \p initiator is ignored if the attribute does not relate to a specific
|
||||
* initiator (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR).
|
||||
* Otherwise \p initiator may be non \c NULL to report only targets
|
||||
* that have a value for that initiator.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* \note This function is meant for tools and debugging (listing internal information)
|
||||
* rather than for application queries. Applications should rather select useful
|
||||
* NUMA nodes with hwloc_get_local_numanode_objs() and then look at their attribute
|
||||
* values.
|
||||
*
|
||||
* \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
|
||||
* when refering to accesses performed by CPU cores.
|
||||
* ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
|
||||
* but users may for instance use it to provide custom information about
|
||||
* host memory accesses performed by GPUs.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_get_targets(hwloc_topology_t topology,
|
||||
hwloc_memattr_id_t attribute,
|
||||
struct hwloc_location *initiator,
|
||||
unsigned long flags,
|
||||
unsigned *nrp, hwloc_obj_t *targets, hwloc_uint64_t *values);
|
||||
|
||||
/** \brief Return the initiators that have values for a given attribute for a specific target NUMA node.
|
||||
*
|
||||
* Return initiators for the given attribute and target node in the
|
||||
* \p initiators array.
|
||||
* If \p values is not \c NULL, the corresponding attribute values
|
||||
* are stored in the array it points to.
|
||||
*
|
||||
* On input, \p nr points to the number of initiators that may be stored
|
||||
* in the array \p initiators (and \p values).
|
||||
* On output, \p nr points to the number of initiators (and values) that
|
||||
* were actually found, even if some of them couldn't be stored in the array.
|
||||
* Initiators that couldn't be stored are ignored, but the function still
|
||||
* returns success (\c 0). The caller may find out by comparing the value pointed
|
||||
* by \p nr before and after the function call.
|
||||
*
|
||||
* The returned initiators should not be modified or freed,
|
||||
* they belong to the topology.
|
||||
*
|
||||
* \p flags must be \c 0 for now.
|
||||
*
|
||||
* If the attribute does not relate to a specific initiator
|
||||
* (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
|
||||
* no initiator is returned.
|
||||
*
|
||||
* \note This function is meant for tools and debugging (listing internal information)
|
||||
* rather than for application queries. Applications should rather select useful
|
||||
* NUMA nodes with hwloc_get_local_numanode_objs() and then look at their attribute
|
||||
* values for some relevant initiators.
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_memattr_get_initiators(hwloc_topology_t topology,
|
||||
hwloc_memattr_id_t attribute,
|
||||
hwloc_obj_t target_node,
|
||||
unsigned long flags,
|
||||
unsigned *nr, struct hwloc_location *initiators, hwloc_uint64_t *values);
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HWLOC_MEMATTR_H */
|
||||
181
src/3rdparty/hwloc/include/hwloc/nvml.h
vendored
181
src/3rdparty/hwloc/include/hwloc/nvml.h
vendored
@@ -1,181 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012-2020 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.
|
||||
*
|
||||
* Return 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 OS device object describing the NVML device whose
|
||||
* index is \p idx. Returns 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 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 NULL if there is none.
|
||||
*
|
||||
* 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 */
|
||||
251
src/3rdparty/hwloc/include/hwloc/opencl.h
vendored
251
src/3rdparty/hwloc/include/hwloc/opencl.h
vendored
@@ -1,251 +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.
|
||||
*
|
||||
* Return 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 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 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.
|
||||
*
|
||||
* Use OpenCL device attributes to find the corresponding hwloc OS device object.
|
||||
* Return NULL if there is none or if useful 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 */
|
||||
150
src/3rdparty/hwloc/include/hwloc/openfabrics-verbs.h
vendored
150
src/3rdparty/hwloc/include/hwloc/openfabrics-verbs.h
vendored
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009-2010 Université Bordeaux
|
||||
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/** \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.
|
||||
*
|
||||
* Return 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 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).
|
||||
* Returns NULL if there is none.
|
||||
* 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 OS device object describing the OpenFabrics device \p ibdev
|
||||
* (InfiniBand, etc). Returns NULL if there is none.
|
||||
*
|
||||
* 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 */
|
||||
598
src/3rdparty/hwloc/include/hwloc/plugins.h
vendored
598
src/3rdparty/hwloc/include/hwloc/plugins.h
vendored
@@ -1,598 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013-2020 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
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \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
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \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
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \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
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Check whether insertion errors are hidden */
|
||||
HWLOC_DECLSPEC int hwloc_hide_errors(void);
|
||||
|
||||
/** \brief Add an object to the topology.
|
||||
*
|
||||
* Insert new object \p obj in the topology starting under existing object \p root
|
||||
* (if \c NULL, the topology root object is used).
|
||||
*
|
||||
* It is sorted along the tree of other objects according to the inclusion of
|
||||
* cpusets, to eventually be added as a child of the smallest object including
|
||||
* 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
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \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 == 0x0b /* PCI_BASE_CLASS_PROCESSOR */
|
||||
|| classid == 0x0c04 /* PCI_CLASS_SERIAL_FIBER */
|
||||
|| classid == 0x0c06 /* PCI_CLASS_SERIAL_INFINIBAND */
|
||||
|| 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
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \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
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Find the normal parent of a PCI bus ID.
|
||||
*
|
||||
* Look at PCI affinity to find out where the given PCI bus ID should be attached.
|
||||
*
|
||||
* This function should be used to attach an I/O device under the corresponding
|
||||
* PCI object (if any), or under a normal (non-I/O) object with same locality.
|
||||
*/
|
||||
HWLOC_DECLSPEC struct hwloc_obj * hwloc_pci_find_parent_by_busid(struct hwloc_topology *topology, unsigned domain, unsigned bus, unsigned dev, unsigned func);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* HWLOC_PLUGINS_H */
|
||||
869
src/3rdparty/hwloc/include/hwloc/rename.h
vendored
869
src/3rdparty/hwloc/include/hwloc/rename.h
vendored
@@ -1,869 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright © 2010-2020 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_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_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_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 HWLOC_NAME(distances_add)
|
||||
#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)
|
||||
|
||||
/* 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)
|
||||
|
||||
/* 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_parent_by_busid HWLOC_NAME(pcidisc_find_busid_parent)
|
||||
|
||||
/* hwloc/deprecated.h */
|
||||
|
||||
#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_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_pci_find_by_busid HWLOC_NAME(pcidisc_find_by_busid)
|
||||
#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 */
|
||||
201
src/3rdparty/hwloc/include/hwloc/rsmi.h
vendored
201
src/3rdparty/hwloc/include/hwloc/rsmi.h
vendored
@@ -1,201 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012-2020 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.
|
||||
*
|
||||
* Return 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 OS device object describing the AMD GPU device whose
|
||||
* index is \p dv_ind. Returns 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 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 NULL if there is none.
|
||||
*
|
||||
* 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 */
|
||||
676
src/3rdparty/hwloc/include/private/autogen/config.h
vendored
676
src/3rdparty/hwloc/include/private/autogen/config.h
vendored
@@ -1,676 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009, 2011, 2012 CNRS. All rights reserved.
|
||||
* Copyright © 2009-2020 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'. */
|
||||
#define HAVE_SYSTEM_LOGICAL_PROCESSOR_INFORMATION 1
|
||||
|
||||
/* 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,41 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2018-2019 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_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_
|
||||
534
src/3rdparty/hwloc/include/private/private.h
vendored
534
src/3rdparty/hwloc/include/private/private.h
vendored
@@ -1,534 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009-2012, 2020 Université Bordeaux
|
||||
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
|
||||
*
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/* 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 */
|
||||
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 the given domain/bus/func,
|
||||
* either exactly or return the smallest container bridge
|
||||
*/
|
||||
extern struct hwloc_obj * hwloc_pci_find_by_busid(struct hwloc_topology *topology, unsigned domain, unsigned bus, unsigned dev, unsigned func);
|
||||
|
||||
/* 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 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 int hwloc_internal_distances_add_by_index(hwloc_topology_t topology, const char *name, hwloc_obj_type_t unique_type, hwloc_obj_type_t *different_types, unsigned nbobjs, uint64_t *indexes, uint64_t *values, unsigned long kind, unsigned long flags);
|
||||
extern void hwloc_internal_distances_invalidate_cached_objs(hwloc_topology_t topology);
|
||||
|
||||
extern void hwloc_internal_memattrs_init(hwloc_topology_t topology);
|
||||
extern void hwloc_internal_memattrs_prepare(hwloc_topology_t topology);
|
||||
extern void hwloc_internal_memattrs_destroy(hwloc_topology_t topology);
|
||||
extern void hwloc_internal_memattrs_need_refresh(hwloc_topology_t topology);
|
||||
extern void hwloc_internal_memattrs_refresh(hwloc_topology_t topology);
|
||||
extern int hwloc_internal_memattrs_dup(hwloc_topology_t new, hwloc_topology_t old);
|
||||
extern int hwloc_internal_memattr_set_value(hwloc_topology_t topology, hwloc_memattr_id_t id, hwloc_obj_type_t target_type, hwloc_uint64_t target_gp_index, unsigned target_os_index, struct hwloc_internal_location_s *initiator, hwloc_uint64_t value);
|
||||
|
||||
extern void hwloc_internal_cpukinds_init(hwloc_topology_t topology);
|
||||
extern int hwloc_internal_cpukinds_rank(hwloc_topology_t topology);
|
||||
extern void hwloc_internal_cpukinds_destroy(hwloc_topology_t topology);
|
||||
extern int hwloc_internal_cpukinds_dup(hwloc_topology_t new, hwloc_topology_t old);
|
||||
#define HWLOC_CPUKINDS_REGISTER_FLAG_OVERWRITE_FORCED_EFFICIENCY (1<<0)
|
||||
extern int hwloc_internal_cpukinds_register(hwloc_topology_t topology, hwloc_cpuset_t cpuset, int forced_efficiency, const struct hwloc_info_s *infos, unsigned nr_infos, unsigned long flags);
|
||||
extern void hwloc_internal_cpukinds_restrict(hwloc_topology_t topology);
|
||||
|
||||
/* encode src buffer into target buffer.
|
||||
* targsize must be at least 4*((srclength+2)/3)+1.
|
||||
* target will be 0-terminated.
|
||||
*/
|
||||
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 */
|
||||
/* 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 */
|
||||
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
1086
src/3rdparty/hwloc/src/components.c
vendored
1086
src/3rdparty/hwloc/src/components.c
vendored
File diff suppressed because it is too large
Load Diff
649
src/3rdparty/hwloc/src/cpukinds.c
vendored
649
src/3rdparty/hwloc/src/cpukinds.c
vendored
@@ -1,649 +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;
|
||||
|
||||
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,
|
||||
HWLOC_CPUKINDS_RANKING_CORETYPE,
|
||||
HWLOC_CPUKINDS_RANKING_FREQUENCY,
|
||||
HWLOC_CPUKINDS_RANKING_FREQUENCY_MAX,
|
||||
HWLOC_CPUKINDS_RANKING_FREQUENCY_BASE,
|
||||
HWLOC_CPUKINDS_RANKING_NONE
|
||||
};
|
||||
|
||||
static int
|
||||
hwloc__cpukinds_try_rank_by_info(struct hwloc_topology *topology,
|
||||
enum hwloc_cpukinds_ranking heuristics,
|
||||
struct hwloc_cpukinds_info_summary *summary)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (HWLOC_CPUKINDS_RANKING_CORETYPE_FREQUENCY == heuristics) {
|
||||
hwloc_debug("Trying to rank cpukinds by coretype+frequency...\n");
|
||||
/* we need intel_core_type + (base or max freq) for all kinds */
|
||||
if (!summary->have_intel_core_type
|
||||
|| (!summary->have_max_freq && !summary->have_base_freq))
|
||||
return -1;
|
||||
/* rank first by coretype (Core>>Atom) then by frequency, base if available, max otherwise */
|
||||
for(i=0; i<topology->nr_cpukinds; i++) {
|
||||
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
|
||||
if (summary->have_base_freq)
|
||||
kind->ranking_value = (summary->summaries[i].intel_core_type << 20) + summary->summaries[i].base_freq;
|
||||
else
|
||||
kind->ranking_value = (summary->summaries[i].intel_core_type << 20) + summary->summaries[i].max_freq;
|
||||
}
|
||||
|
||||
} else if (HWLOC_CPUKINDS_RANKING_CORETYPE == heuristics) {
|
||||
hwloc_debug("Trying to rank cpukinds by coretype...\n");
|
||||
/* we need intel_core_type */
|
||||
if (!summary->have_intel_core_type)
|
||||
return -1;
|
||||
/* rank by coretype (Core>>Atom) */
|
||||
for(i=0; i<topology->nr_cpukinds; i++) {
|
||||
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
|
||||
kind->ranking_value = (summary->summaries[i].intel_core_type << 20);
|
||||
}
|
||||
|
||||
} else if (HWLOC_CPUKINDS_RANKING_FREQUENCY == heuristics) {
|
||||
hwloc_debug("Trying to rank cpukinds by frequency...\n");
|
||||
/* we need base or max freq for all kinds */
|
||||
if (!summary->have_max_freq && !summary->have_base_freq)
|
||||
return -1;
|
||||
/* rank first by frequency, base if available, max otherwise */
|
||||
for(i=0; i<topology->nr_cpukinds; i++) {
|
||||
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
|
||||
if (summary->have_base_freq)
|
||||
kind->ranking_value = summary->summaries[i].base_freq;
|
||||
else
|
||||
kind->ranking_value = summary->summaries[i].max_freq;
|
||||
}
|
||||
|
||||
} else if (HWLOC_CPUKINDS_RANKING_FREQUENCY_MAX == heuristics) {
|
||||
hwloc_debug("Trying to rank cpukinds by frequency max...\n");
|
||||
/* we need max freq for all kinds */
|
||||
if (!summary->have_max_freq)
|
||||
return -1;
|
||||
/* rank first by frequency, base if available, max otherwise */
|
||||
for(i=0; i<topology->nr_cpukinds; i++) {
|
||||
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
|
||||
kind->ranking_value = summary->summaries[i].max_freq;
|
||||
}
|
||||
|
||||
} else if (HWLOC_CPUKINDS_RANKING_FREQUENCY_BASE == heuristics) {
|
||||
hwloc_debug("Trying to rank cpukinds by frequency base...\n");
|
||||
/* we need max freq for all kinds */
|
||||
if (!summary->have_base_freq)
|
||||
return -1;
|
||||
/* rank first by frequency, base if available, max otherwise */
|
||||
for(i=0; i<topology->nr_cpukinds; i++) {
|
||||
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
|
||||
kind->ranking_value = summary->summaries[i].base_freq;
|
||||
}
|
||||
|
||||
} else assert(0);
|
||||
|
||||
return hwloc__cpukinds_check_duplicate_rankings(topology);
|
||||
}
|
||||
|
||||
static int hwloc__cpukinds_compare_ranking_values(const void *_a, const void *_b)
|
||||
{
|
||||
const struct hwloc_internal_cpukind_s *a = _a;
|
||||
const struct hwloc_internal_cpukind_s *b = _b;
|
||||
return a->ranking_value - b->ranking_value;
|
||||
}
|
||||
|
||||
/* this function requires ranking values to be unique */
|
||||
static void
|
||||
hwloc__cpukinds_finalize_ranking(struct hwloc_topology *topology)
|
||||
{
|
||||
unsigned i;
|
||||
/* sort */
|
||||
qsort(topology->cpukinds, topology->nr_cpukinds, sizeof(*topology->cpukinds), hwloc__cpukinds_compare_ranking_values);
|
||||
/* define our own efficiency between 0 and N-1 */
|
||||
for(i=0; i<topology->nr_cpukinds; i++)
|
||||
topology->cpukinds[i].efficiency = i;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_internal_cpukinds_rank(struct hwloc_topology *topology)
|
||||
{
|
||||
enum hwloc_cpukinds_ranking heuristics;
|
||||
char *env;
|
||||
unsigned i;
|
||||
int err;
|
||||
|
||||
if (!topology->nr_cpukinds)
|
||||
return 0;
|
||||
|
||||
if (topology->nr_cpukinds == 1) {
|
||||
topology->cpukinds[0].efficiency = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_DEFAULT;
|
||||
env = getenv("HWLOC_CPUKINDS_RANKING");
|
||||
if (env) {
|
||||
if (!strcmp(env, "default"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_DEFAULT;
|
||||
else if (!strcmp(env, "none"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_NONE;
|
||||
else if (!strcmp(env, "coretype+frequency"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_CORETYPE_FREQUENCY;
|
||||
else if (!strcmp(env, "coretype"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_CORETYPE;
|
||||
else if (!strcmp(env, "frequency"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_FREQUENCY;
|
||||
else if (!strcmp(env, "frequency_max"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_FREQUENCY_MAX;
|
||||
else if (!strcmp(env, "frequency_base"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_FREQUENCY_BASE;
|
||||
else if (!strcmp(env, "forced_efficiency"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_FORCED_EFFICIENCY;
|
||||
else if (!strcmp(env, "no_forced_efficiency"))
|
||||
heuristics = HWLOC_CPUKINDS_RANKING_NO_FORCED_EFFICIENCY;
|
||||
else if (!hwloc_hide_errors())
|
||||
fprintf(stderr, "Failed to recognize HWLOC_CPUKINDS_RANKING value %s\n", env);
|
||||
}
|
||||
|
||||
if (heuristics == HWLOC_CPUKINDS_RANKING_DEFAULT
|
||||
|| heuristics == HWLOC_CPUKINDS_RANKING_NO_FORCED_EFFICIENCY) {
|
||||
/* default is forced_efficiency first */
|
||||
struct hwloc_cpukinds_info_summary summary;
|
||||
enum hwloc_cpukinds_ranking subheuristics;
|
||||
const char *arch;
|
||||
|
||||
if (heuristics == HWLOC_CPUKINDS_RANKING_DEFAULT)
|
||||
hwloc_debug("Using default ranking strategy...\n");
|
||||
else
|
||||
hwloc_debug("Using custom ranking strategy from HWLOC_CPUKINDS_RANKING=%s\n", env);
|
||||
|
||||
if (heuristics != HWLOC_CPUKINDS_RANKING_NO_FORCED_EFFICIENCY) {
|
||||
err = hwloc__cpukinds_try_rank_by_forced_efficiency(topology);
|
||||
if (!err)
|
||||
goto ready;
|
||||
}
|
||||
|
||||
summary.summaries = calloc(topology->nr_cpukinds, sizeof(*summary.summaries));
|
||||
if (!summary.summaries)
|
||||
goto failed;
|
||||
hwloc__cpukinds_summarize_info(topology, &summary);
|
||||
|
||||
arch = hwloc_obj_get_info_by_name(topology->levels[0][0], "Architecture");
|
||||
/* TODO: rather coretype_frequency only on x86/Intel? */
|
||||
if (arch && (!strncmp(arch, "arm", 3) || !strncmp(arch, "aarch", 5)))
|
||||
/* then frequency on ARM */
|
||||
subheuristics = HWLOC_CPUKINDS_RANKING_FREQUENCY;
|
||||
else
|
||||
/* or coretype+frequency otherwise */
|
||||
subheuristics = HWLOC_CPUKINDS_RANKING_CORETYPE_FREQUENCY;
|
||||
|
||||
err = hwloc__cpukinds_try_rank_by_info(topology, subheuristics, &summary);
|
||||
free(summary.summaries);
|
||||
if (!err)
|
||||
goto ready;
|
||||
|
||||
} else if (heuristics == HWLOC_CPUKINDS_RANKING_FORCED_EFFICIENCY) {
|
||||
hwloc_debug("Using custom ranking strategy from HWLOC_CPUKINDS_RANKING=%s\n", env);
|
||||
|
||||
err = hwloc__cpukinds_try_rank_by_forced_efficiency(topology);
|
||||
if (!err)
|
||||
goto ready;
|
||||
|
||||
} else if (heuristics != HWLOC_CPUKINDS_RANKING_NONE) {
|
||||
/* custom heuristics */
|
||||
struct hwloc_cpukinds_info_summary summary;
|
||||
|
||||
hwloc_debug("Using custom ranking strategy from HWLOC_CPUKINDS_RANKING=%s\n", env);
|
||||
|
||||
summary.summaries = calloc(topology->nr_cpukinds, sizeof(*summary.summaries));
|
||||
if (!summary.summaries)
|
||||
goto failed;
|
||||
hwloc__cpukinds_summarize_info(topology, &summary);
|
||||
|
||||
err = hwloc__cpukinds_try_rank_by_info(topology, heuristics, &summary);
|
||||
free(summary.summaries);
|
||||
if (!err)
|
||||
goto ready;
|
||||
}
|
||||
|
||||
failed:
|
||||
/* failed to rank, clear efficiencies */
|
||||
for(i=0; i<topology->nr_cpukinds; i++)
|
||||
topology->cpukinds[i].efficiency = HWLOC_CPUKIND_EFFICIENCY_UNKNOWN;
|
||||
hwloc_debug("Failed to rank cpukinds.\n\n");
|
||||
return 0;
|
||||
|
||||
ready:
|
||||
for(i=0; i<topology->nr_cpukinds; i++)
|
||||
hwloc_debug("cpukind #%u got ranking value %llu\n", i, (unsigned long long) topology->cpukinds[i].ranking_value);
|
||||
hwloc__cpukinds_finalize_ranking(topology);
|
||||
#ifdef HWLOC_DEBUG
|
||||
for(i=0; i<topology->nr_cpukinds; i++)
|
||||
assert(topology->cpukinds[i].efficiency == (int) i);
|
||||
#endif
|
||||
hwloc_debug("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
* Consulting
|
||||
*/
|
||||
|
||||
int
|
||||
hwloc_cpukinds_get_nr(hwloc_topology_t topology, unsigned long flags)
|
||||
{
|
||||
if (flags) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return topology->nr_cpukinds;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_cpukinds_get_info(hwloc_topology_t topology,
|
||||
unsigned id,
|
||||
hwloc_bitmap_t cpuset,
|
||||
int *efficiencyp,
|
||||
unsigned *nr_infosp, struct hwloc_info_s **infosp,
|
||||
unsigned long flags)
|
||||
{
|
||||
struct hwloc_internal_cpukind_s *kind;
|
||||
|
||||
if (flags) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (id >= topology->nr_cpukinds) {
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
kind = &topology->cpukinds[id];
|
||||
|
||||
if (cpuset)
|
||||
hwloc_bitmap_copy(cpuset, kind->cpuset);
|
||||
|
||||
if (efficiencyp)
|
||||
*efficiencyp = kind->efficiency;
|
||||
|
||||
if (nr_infosp && infosp) {
|
||||
*nr_infosp = kind->nr_infos;
|
||||
*infosp = kind->infos;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hwloc_cpukinds_get_by_cpuset(hwloc_topology_t topology,
|
||||
hwloc_const_bitmap_t cpuset,
|
||||
unsigned long flags)
|
||||
{
|
||||
unsigned id;
|
||||
|
||||
if (flags) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!cpuset || hwloc_bitmap_iszero(cpuset)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(id=0; id<topology->nr_cpukinds; id++) {
|
||||
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[id];
|
||||
int res = hwloc_bitmap_compare_inclusion(cpuset, kind->cpuset);
|
||||
if (res == HWLOC_BITMAP_EQUAL || res == HWLOC_BITMAP_INCLUDED) {
|
||||
return (int) id;
|
||||
} else if (res == HWLOC_BITMAP_INTERSECTS || res == HWLOC_BITMAP_CONTAINS) {
|
||||
errno = EXDEV;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
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 */
|
||||
}
|
||||
1089
src/3rdparty/hwloc/src/distances.c
vendored
1089
src/3rdparty/hwloc/src/distances.c
vendored
File diff suppressed because it is too large
Load Diff
1197
src/3rdparty/hwloc/src/memattrs.c
vendored
1197
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 */
|
||||
}
|
||||
1046
src/3rdparty/hwloc/src/pci-common.c
vendored
1046
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
1399
src/3rdparty/hwloc/src/topology-windows.c
vendored
1399
src/3rdparty/hwloc/src/topology-windows.c
vendored
File diff suppressed because it is too large
Load Diff
1792
src/3rdparty/hwloc/src/topology-x86.c
vendored
1792
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
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user