{"id":27918775,"url":"https://github.com/juliaparallel/hwloc.jl","last_synced_at":"2025-05-06T18:25:31.399Z","repository":{"id":23311090,"uuid":"26670741","full_name":"JuliaParallel/Hwloc.jl","owner":"JuliaParallel","description":"A Julia API for hwloc","archived":false,"fork":false,"pushed_at":"2024-11-18T18:39:55.000Z","size":244,"stargazers_count":80,"open_issues_count":1,"forks_count":19,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-07T13:48:05.709Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Julia","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JuliaParallel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-11-15T05:46:20.000Z","updated_at":"2025-02-23T12:20:06.000Z","dependencies_parsed_at":"2024-01-13T00:43:06.097Z","dependency_job_id":"f691a0cb-b5c3-4a34-8511-c5dfb3e38de6","html_url":"https://github.com/JuliaParallel/Hwloc.jl","commit_stats":{"total_commits":197,"total_committers":15,"mean_commits":"13.133333333333333","dds":0.4873096446700508,"last_synced_commit":"772b6d3c9507b7450d090790bb6450d9fda15b80"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaParallel%2FHwloc.jl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaParallel%2FHwloc.jl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaParallel%2FHwloc.jl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaParallel%2FHwloc.jl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JuliaParallel","download_url":"https://codeload.github.com/JuliaParallel/Hwloc.jl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252742703,"owners_count":21797297,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-06T18:25:30.579Z","updated_at":"2025-05-06T18:25:31.367Z","avatar_url":"https://github.com/JuliaParallel.png","language":"Julia","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Portable Hardware Locality (Hwloc)\n\n[![Build Status](https://github.com/JuliaParallel/Hwloc.jl/workflows/CI/badge.svg)](https://github.com/JuliaParallel/Hwloc.jl/actions)\n[![Coverage](https://codecov.io/gh/JuliaParallel/Hwloc.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaParallel/Hwloc.jl)\n\nHwloc.jl is a high-level wrapper of the\n[hwloc library](http://www.open-mpi.org/projects/hwloc/). It examines the current machine's\nhardware topology (memories, caches, cores, etc.) and provides\nJulia functions to visualize and access this information conveniently.\n\nTaken from the [hwloc website](http://www.open-mpi.org/projects/hwloc/):\n\u003e The Portable Hardware Locality (hwloc) software package provides a portable abstraction (across OS, versions, architectures, ...) of the hierarchical topology of modern architectures, including NUMA memory nodes, sockets, shared caches, cores and simultaneous multithreading. It also gathers various system attributes such as cache and memory information as well as the locality of I/O devices such as network interfaces, InfiniBand HCAs or GPUs.\n\u003e \n\u003e hwloc primarily aims at helping applications with gathering information about increasingly complex parallel computing platforms so as to exploit them accordingly and efficiently.\n\n# Usage\n\nPerhaps the most important function is `Hwloc.topology()` which\ndisplays a tree structure describing the system topology. This\nroughly corresponds to the output of the `lstopo` program (non-GUI version).\nOn my laptop this gives the following output:\n\n```julia\njulia\u003e using Hwloc\n\njulia\u003e topology()\n\nMachine (31.05 GB)\n    Package L#0 P#0 (31.05 GB)\n        NUMANode (31.05 GB)\n        L3 (12.0 MB)\n            L2 (1.25 MB) + L1 (48.0 kB) + Core L#0 P#0 \n                PU L#0 P#0 \n                PU L#1 P#4 \n            L2 (1.25 MB) + L1 (48.0 kB) + Core L#1 P#1 \n                PU L#2 P#1 \n                PU L#3 P#5 \n            L2 (1.25 MB) + L1 (48.0 kB) + Core L#2 P#2 \n                PU L#4 P#2 \n                PU L#5 P#6 \n            L2 (1.25 MB) + L1 (48.0 kB) + Core L#3 P#3 \n                PU L#6 P#3 \n                PU L#7 P#7 \n    HostBridge \n        PCI 00:02.0 (VGA)\n            GPU \"renderD128\"\n            GPU \"card0\"\n        PCIBridge \n            PCI 01:00.0 (NVMExp)\n                Block(Disk) \"nvme0n1\"\n        PCIBridge \n            PCI 72:00.0 (Network)\n                Net \"wlp114s0\"\n        PCIBridge \n            PCI 73:00.0 (Other)\n                Block \"mmcblk0\"\n\n```\n\nOften, one is only interested in a summary of this topology.\nThe function `topology_info()` provides such a compact description, which is loosely similar to the output of the `hwloc-info` command-line application.\n\n```julia\njulia\u003e topology_info()\nMachine: 1 (31.05 GB)\n Package: 1 (31.05 GB)\n  NUMANode: 1 (31.05 GB)\n   L3Cache: 1 (12.0 MB)\n    L2Cache: 4 (1.25 MB)\n     L1Cache: 4 (48.0 kB)\n      Core: 4\n       PU: 8\n        Bridge: 6\n         PCI_Device: 22\n          OS_Device: 13\n```\n\nIf you prefer a more verbose graphical visualization you may consider using `topology_graphical()`:\n\n```\njulia\u003e topology_graphical()\n┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐\n│ Machine (31GB total)                                                                                              │\n│                                                                                                                   │\n│ ┌────────────────────────────────────────────────────────────────────┐  ├┤╶─┬─────┬─────────────┐                 │\n│ │ Package L#0                                                        │      │     │ PCI 00:02.0 │                 │\n│ │                                                                    │      │     └─────────────┘                 │\n│ │ ┌────────────────────────────────────────────────────────────────┐ │      │                                     │\n│ │ │ NUMANode L#0 P#0 (31GB)                                        │ │      ├─────┼┤╶───────┬───────────────────┐ │\n│ │ └────────────────────────────────────────────────────────────────┘ │      │3.9       3.9  │ PCI 01:00.0       │ │\n│ │                                                                    │      │               │                   │ │\n│ │ ┌────────────────────────────────────────────────────────────────┐ │      │               │ ┌───────────────┐ │ │\n│ │ │ L3 (12MB)                                                      │ │      │               │ │ Block nvme0n1 │ │ │\n│ │ └────────────────────────────────────────────────────────────────┘ │      │               │ │               │ │ │\n│ │                                                                    │      │               │ │ 953 GB        │ │ │\n│ │ ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐ │      │               │ └───────────────┘ │ │\n│ │ │ L2 (1280KB) │  │ L2 (1280KB) │  │ L2 (1280KB) │  │ L2 (1280KB) │ │      │               └───────────────────┘ │\n│ │ └─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘ │      │                                     │\n│ │                                                                    │      ├─────┼┤╶───────┬──────────────────┐  │\n│ │ ┌────────────┐   ┌────────────┐   ┌────────────┐   ┌────────────┐  │      │0.6       0.6  │ PCI 72:00.0      │  │\n│ │ │ L1d (48KB) │   │ L1d (48KB) │   │ L1d (48KB) │   │ L1d (48KB) │  │      │               │                  │  │\n│ │ └────────────┘   └────────────┘   └────────────┘   └────────────┘  │      │               │ ┌──────────────┐ │  │\n│ │                                                                    │      │               │ │ Net wlp114s0 │ │  │\n│ │ ┌────────────┐   ┌────────────┐   ┌────────────┐   ┌────────────┐  │      │               │ └──────────────┘ │  │\n│ │ │ L1i (32KB) │   │ L1i (32KB) │   │ L1i (32KB) │   │ L1i (32KB) │  │      │               └──────────────────┘  │\n│ │ └────────────┘   └────────────┘   └────────────┘   └────────────┘  │      │                                     │\n│ │                                                                    │      └─────┼┤╶───────┬───────────────┐     │\n│ │ ┌────────────┐   ┌────────────┐   ┌────────────┐   ┌────────────┐  │       1.0            │ Block mmcblk0 │     │\n│ │ │ Core L#0   │   │ Core L#1   │   │ Core L#2   │   │ Core L#3   │  │                      │               │     │\n│ │ │            │   │            │   │            │   │            │  │                      │ 238 GB        │     │\n│ │ │ ┌────────┐ │   │ ┌────────┐ │   │ ┌────────┐ │   │ ┌────────┐ │  │                      └───────────────┘     │\n│ │ │ │ PU L#0 │ │   │ │ PU L#2 │ │   │ │ PU L#4 │ │   │ │ PU L#6 │ │  │                                            │\n│ │ │ │        │ │   │ │        │ │   │ │        │ │   │ │        │ │  │                                            │\n│ │ │ │  P#0   │ │   │ │  P#1   │ │   │ │  P#2   │ │   │ │  P#3   │ │  │                                            │\n│ │ │ └────────┘ │   │ └────────┘ │   │ └────────┘ │   │ └────────┘ │  │                                            │\n│ │ │ ┌────────┐ │   │ ┌────────┐ │   │ ┌────────┐ │   │ ┌────────┐ │  │                                            │\n│ │ │ │ PU L#1 │ │   │ │ PU L#3 │ │   │ │ PU L#5 │ │   │ │ PU L#7 │ │  │                                            │\n│ │ │ │        │ │   │ │        │ │   │ │        │ │   │ │        │ │  │                                            │\n│ │ │ │  P#4   │ │   │ │  P#5   │ │   │ │  P#6   │ │   │ │  P#7   │ │  │                                            │\n│ │ │ └────────┘ │   │ └────────┘ │   │ └────────┘ │   │ └────────┘ │  │                                            │\n│ │ └────────────┘   └────────────┘   └────────────┘   └────────────┘  │                                            │\n│ └────────────────────────────────────────────────────────────────────┘                                            │\n└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n(Note that as of now this may produce colorful output on some systems.)\n\n\n## Obtaining particular information:\n\n### Number of cores, NUMA nodes, and sockets\n\n`Hwloc` exports a few convenience functions for obtaining particularly import information,\nsuch as the number of physical and virtual cores (i.e. processing units), NUMA nodes, and sockets / packages:\n\n```julia\njulia\u003e num_physical_cores()\n6\n\njulia\u003e num_virtual_cores()\n12\n\njulia\u003e num_numa_nodes()\n1\n\njulia\u003e num_packages()\n1\n```\n\nOne may also use `getinfo()` to programmatically access some of the output of `topology_info()`:\n\n```julia\njulia\u003e getinfo()\nDict{Symbol, Int64} with 11 entries:\n  :Package    =\u003e 1\n  :PU         =\u003e 8\n  :OS_Device  =\u003e 13\n  :Core       =\u003e 4\n  :L3Cache    =\u003e 1\n  :Machine    =\u003e 1\n  :PCI_Device =\u003e 22\n  :L2Cache    =\u003e 4\n  :NUMANode   =\u003e 1\n  :Bridge     =\u003e 6\n  :L1Cache    =\u003e 4\n```\n\n### Cache properties\n\nAssuming that multiple caches of the same level (e.g. L1) have identical properties, one can use the convenience functions `cachesize()` and `cachelinesize()` to obtain the relevant sizes in Bytes:\n\n```julia\njulia\u003e cachesize()\n(L1 = 32768, L2 = 262144, L3 = 12582912)\n\njulia\u003e cachelinesize()\n(L1 = 64, L2 = 64, L3 = 64)\n```\n\nOtherwise, there are the following more specific functions available:\n```julia\njulia\u003e @show Hwloc.l1cache_sizes();\n       @show Hwloc.l2cache_sizes();\n       @show Hwloc.l3cache_sizes();\nHwloc.l1cache_sizes() = [32768, 32768, 32768, 32768, 32768, 32768]\nHwloc.l2cache_sizes() = [262144, 262144, 262144, 262144, 262144, 262144]\nHwloc.l3cache_sizes() = [12582912]\n````\n\n### Different kind of CPU cores\n\nSome systems have CPU cores of differents kinds, like, e.g., efficiency and performance cores. With Hwloc.jl, you can query the number of different kinds and the count of CPU cores for each kind. For example, on Mac mini M1 (4 efficiency and 4 performance cores):\n\n```julia\njulia\u003e using Hwloc\n\njulia\u003e num_cpukinds()\n2\n\njulia\u003e num_virtual_cores_cpukinds()\n2-element Vector{Int64}:\n 4\n 4\n```\n\nYou can also see which PU belongs to which CPU kind by passing `cpukind=true` to `topology`:\n\n```julia\njulia\u003e topology(; cpukind=true)\n\nMachine (3.49 GB)\n    Package L#0 P#0 (3.49 GB)\n        NUMANode (3.49 GB)\n        L2 (4.0 MB)\n            L1 (64.0 kB) + Core L#0 P#0\n                PU L#0 P#0 (1, DarwinCompatible=apple,icestorm;ARM,v8)\n            L1 (64.0 kB) + Core L#1 P#1\n                PU L#1 P#1 (1, DarwinCompatible=apple,icestorm;ARM,v8)\n            L1 (64.0 kB) + Core L#2 P#2\n                PU L#2 P#2 (1, DarwinCompatible=apple,icestorm;ARM,v8)\n            L1 (64.0 kB) + Core L#3 P#3\n                PU L#3 P#3 (1, DarwinCompatible=apple,icestorm;ARM,v8)\n        L2 (12.0 MB)\n            L1 (128.0 kB) + Core L#4 P#4\n                PU L#4 P#4 (2, DarwinCompatible=apple,firestorm;ARM,v8)\n            L1 (128.0 kB) + Core L#5 P#5\n                PU L#5 P#5 (2, DarwinCompatible=apple,firestorm;ARM,v8)\n            L1 (128.0 kB) + Core L#6 P#6\n                PU L#6 P#6 (2, DarwinCompatible=apple,firestorm;ARM,v8)\n            L1 (128.0 kB) + Core L#7 P#7\n                PU L#7 P#7 (2, DarwinCompatible=apple,firestorm;ARM,v8)\n    CoProc(OpenCL) \"opencl0d0\"\n```\n\n### Manual access\n\nTo manually traverse and investigate the system topology tree, one may use `gettopology()` to\nobtain the top-level `Hwloc.Object`.\n\n```julia\njulia\u003e topo = gettopology()\nHwloc.Object: Machine\n\njulia\u003e fieldnames(typeof(topo))\n(:type_, :os_index, :name, :attr, :mem, :depth, :logical_index, :children, :memory_children)\n\njulia\u003e Hwloc.children(topo)\n1-element Array{Hwloc.Object,1}:\n Hwloc.Object: Package\n\njulia\u003e Hwloc.children(topo.children[1])\n1-element Array{Hwloc.Object,1}:\n Hwloc.Object: L3Cache\n\njulia\u003e l2cache = Hwloc.children(topo.children[1].children[1])[1]\nHwloc.Object: L2Cache\n\njulia\u003e Hwloc.attributes(l2cache)\nCache{size=262144,depth=2,linesize=64,associativity=4,type=Unified}\n\njulia\u003e l2cache |\u003e print_topology\nL2 (256.0 kB) + L1 (32.0 kB) + Core L#0 P#0 \n    PU L#0 P#0 \n    PU L#1 P#1\n```\n\nTopology elements of type `Hwloc.Object` also are Julia iterators. One can thus readily traverse the corresponding part of the topology tree:\n\n```julia\njulia\u003e for obj in l2cache\n           @show hwloc_typeof(obj)\n       end\nhwloc_typeof(obj) = :L2Cache\nhwloc_typeof(obj) = :L1Cache\nhwloc_typeof(obj) = :Core\nhwloc_typeof(obj) = :PU\nhwloc_typeof(obj) = :PU\n\njulia\u003e collect(obj for obj in l2cache)\n5-element Array{Hwloc.Object,1}:\n Hwloc.Object: L2Cache\n Hwloc.Object: L1Cache\n Hwloc.Object: Core\n Hwloc.Object: PU\n Hwloc.Object: PU\n\njulia\u003e count(hwloc_isa(:PU), l2cache)\n2\n\njulia\u003e collectobjects(:PU, l2cache)\n2-element Array{Hwloc.Object,1}:\n Hwloc.Object: PU\n Hwloc.Object: PU\n```\n\n### Manual topology query and caching\n\nOn the first call of `gettopology()`, Hwloc.jl examines the current machine's\nhardware topology and caches the result in `Hwloc.machine_topology`.\n\nTo query the system the system topology again -- i.e. not using the cached\n`Hwloc.Object` representing the entire machine -- simply pass the `reload=true` (`false` by default) kwarg:\n\n```julia\njulia\u003e topo = gettopology(;reload=true)\nHwloc.Object: Machine\n```\n\n### Do not include I/O devices in topology object\n\nYou may prefer not to include I/O devices in you Hwloc tree, then we recommend\npassing the `io=false` (`true` by default) kwarg, in addition to `reload` (cf.\nabove):\n\n```julia\njulia\u003e topo = gettopology(;reload=true, io=false)\nHwloc.Object: Machine\n\njulia\u003e topology(topo)\nMachine (31.05 GB)\n    Package L#0 P#0 (31.05 GB)\n        NUMANode (31.05 GB)\n        L3 (12.0 MB)\n            L2 (1.25 MB) + L1 (48.0 kB) + Core L#0 P#0 \n                PU L#0 P#0 \n                PU L#1 P#4 \n            L2 (1.25 MB) + L1 (48.0 kB) + Core L#1 P#1 \n                PU L#2 P#1 \n                PU L#3 P#5 \n            L2 (1.25 MB) + L1 (48.0 kB) + Core L#2 P#2 \n                PU L#4 P#2 \n                PU L#5 P#6 \n            L2 (1.25 MB) + L1 (48.0 kB) + Core L#3 P#3 \n                PU L#6 P#3 \n                PU L#7 P#7 \n```\n(note: to avoid caching by accident, we recommend passing `reload=true` to\n`gettopology`)\n\n### Low-level API for accessing the underlying topology object.\n\n**Warning:** As discussed earlier, `Hwloc.jl` makes heavy use of caching in the\nhigh-level API. Using the low-level and high-level APIs together can result in\ncached values being used by accident! We therefore recommend that the high-level\n`gettopology` funcion is used, where caching is controlled via the `reload`\nkwarg.\n\nUnder the hood, `gettopology` uses `Hwloc.topology_init` and\n`Hwloc.topology_load` to directly `ccall` into `libhwloc`. `Hwloc.topology_init`\nis reponsible for creating a low-level `LibHwloc.hwloc_topology` object.\n`Hwloc.topology_load` wraps this a `Hwloc.Object` Julia object.\n\n**Note:** `Hwloc.topology_load` is destructive to the `LibHwloc.hwloc_topology`\nobject:\n\n```julia\njulia\u003e htopo = Hwloc.topology_init()\nPtr{Hwloc.LibHwloc.hwloc_topology} @0x000000000883cf60\n\njulia\u003e topo = Hwloc.topology_load(htopo)\nHwloc.Object: Machine\n\njulia\u003e topo = Hwloc.topology_load(htopo)\nERROR: AssertionError: ierr == 0\nStacktrace:\n [1] topology_load(htopo::Ptr{Hwloc.LibHwloc.hwloc_topology})\n   @ Hwloc ~/.julia/dev/Hwloc/src/lowlevel_api.jl:347\n [2] top-level scope\n   @ REPL[78]:1\n```\n\nThis is because `LibHwloc.hwloc_topology` are not garbage-collected (a call to\n`Hwloc.topology_init`, without a later call to `Hwloc.hwloc_topology_destroy`\nwill leak memory). This is why `Hwloc.topology_load` calls\n`Hwloc.hwloc_topology_destroy` after creating the `Hwloc.Object` Julia object\n(which is garbage collected!).\n\n\n## Hwloc objects are `AbstractTrees`\n\nIf the [`AbstractTrees`](https://github.com/JuliaCollections/AbstractTrees.jl)\nmodule is loaded, then passing an `Hwloc.Object` to `AbstractTrees.children`\nwill construct an `HwlocTreeNode`. Calling `children(gettopology())` will\nreturn the Hwloc tree root:\n\n```julia\njulia\u003e using AbstractTrees, Hwloc\n\njulia\u003e t = children(gettopology());\n\njulia\u003e print_tree(t; maxdepth=2)\nHwloc.Object: Machine\n├─ Hwloc.Object: Package [L#0 P#0]\n│  ├─ Hwloc.Object: L3Cache\n│  │  ⋮\n│  │  \n│  └─ Hwloc.Object: NUMANode\n└─ Hwloc.Object: Bridge [HostBridge]\n   ├─ Hwloc.Object: PCI_Device [00:00.0 (HostBridge)]\n   ├─ Hwloc.Object: PCI_Device [00:02.0 (VGA)]\n   │  ⋮\n   │  \n   ├─ Hwloc.Object: PCI_Device [00:04.0 (SignalProcessing)]\n   ├─ Hwloc.Object: Bridge [PCIBridge]\n   │  ⋮\n   │  \n   ├─ Hwloc.Object: Bridge [PCIBridge]\n   ├─ Hwloc.Object: Bridge [PCIBridge]\n   ├─ Hwloc.Object: PCI_Device [00:0a.0 (SignalProcessing)]\n   ├─ Hwloc.Object: PCI_Device [00:0d.0 (USB)]\n   ├─ Hwloc.Object: PCI_Device [00:0d.2 (USB)]\n   ├─ Hwloc.Object: PCI_Device [00:0d.3 (USB)]\n   ├─ Hwloc.Object: PCI_Device [00:12.0 (Serial)]\n   ├─ Hwloc.Object: PCI_Device [00:14.0 (USB)]\n   ├─ Hwloc.Object: PCI_Device [00:14.2 (RAM)]\n   ├─ Hwloc.Object: PCI_Device [00:15.0 (SerialBus)]\n   │  ⋮\n   │  \n   ├─ Hwloc.Object: PCI_Device [00:15.1 (SerialBus)]\n   │  ⋮\n   │  \n   ├─ Hwloc.Object: PCI_Device [00:16.0 (Communication)]\n   ├─ Hwloc.Object: PCI_Device [00:19.0 (SerialBus)]\n   │  ⋮\n   │  \n   ├─ Hwloc.Object: PCI_Device [00:19.1 (SerialBus)]\n   │  ⋮\n   │  \n   ├─ Hwloc.Object: Bridge [PCIBridge]\n   │  ⋮\n   │  \n   ├─ Hwloc.Object: Bridge [PCIBridge]\n   │  ⋮\n   │  \n   ├─ Hwloc.Object: PCI_Device [00:1f.0 (ISABridge)]\n   ├─ Hwloc.Object: PCI_Device [00:1f.3 (MultimediaAudio)]\n   ├─ Hwloc.Object: PCI_Device [00:1f.4 (SMBus)]\n   └─ Hwloc.Object: PCI_Device [00:1f.5 (SerialBus)]\n\n```\n\nFor examples of using the AbstracTree interface to search the Hwloc tree, see:\n[NetworkInterfaceControllers.jl](https://github.com/JuliaParallel/NetworkInterfaceControllers.jl)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuliaparallel%2Fhwloc.jl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjuliaparallel%2Fhwloc.jl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuliaparallel%2Fhwloc.jl/lists"}