Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AbstractTrees Interface #72

Merged
merged 41 commits into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
39addfe
WIP: Add support for PCI devices
vchuravy Nov 12, 2022
92310da
fixup! WIP: Add support for PCI devices
vchuravy Nov 13, 2022
569e052
Add PCIDevAttr
vchuravy Nov 13, 2022
525cbe4
Merge branch 'master' into vc/pci
JBlaschke Jan 1, 2023
331f9b4
wip on printing pci data
JBlaschke Jan 3, 2023
aa7eedc
Merge branch 'master' into vc/pci
JBlaschke Jul 9, 2023
41c5f20
wip
JBlaschke Jul 10, 2023
74096db
extract more pci data
JBlaschke Jul 14, 2023
c95c25d
read dev class id
JBlaschke Jul 17, 2023
f54ee3e
wip on inserting process information
JBlaschke Jul 21, 2023
448948c
print PCI devices properly now
JBlaschke Jul 23, 2023
f0aa7f8
get lstopo-style printing
JBlaschke Jul 23, 2023
c192376
add coproc subtype
JBlaschke Jul 24, 2023
7b10523
update list of minimal device types
JBlaschke Jul 24, 2023
3152c28
add more minimal devices
JBlaschke Jul 24, 2023
5fb034c
start working on trees
JBlaschke Jul 25, 2023
9b68881
fix
JBlaschke Jul 25, 2023
8d5d31c
add taggable trees
JBlaschke Jul 26, 2023
c8923d2
update Pkg compat
JBlaschke Dec 31, 2023
0685838
add more control whether or not to print I/O devices
JBlaschke Dec 31, 2023
8fc464f
Update docs
JBlaschke Dec 31, 2023
694e629
fix how settings are filtered through
JBlaschke Dec 31, 2023
1d8e48c
remove unnecessary import
JBlaschke Dec 31, 2023
22ad318
try unsafe_wrap instead of convert->copyto
JBlaschke Dec 31, 2023
80c8e50
make abstract tree interface an extension
JBlaschke Dec 31, 2023
17b308e
Merge branch 'vc/pci' into jpb/iteration
JBlaschke Dec 31, 2023
0236046
get extension fully working
JBlaschke Dec 31, 2023
9f0253b
add tests
JBlaschke Dec 31, 2023
7382bf4
update readme
JBlaschke Dec 31, 2023
be2f4b8
Merge branch 'vc/pci' into jpb/iteration
JBlaschke Dec 31, 2023
372fc6a
compatibility with older versions of Julia
JBlaschke Dec 31, 2023
3e020d9
update readme
JBlaschke Jan 1, 2024
e016f43
oops! fixed it
JBlaschke Jan 6, 2024
dcfe3ba
get_io -> io
JBlaschke Jan 6, 2024
3c6e5af
Add iterator over I/O devices
JBlaschke Jan 6, 2024
9b529e9
Add all devices to getinfo
JBlaschke Jan 6, 2024
7e4bd47
Add PCI devices to topology_info
JBlaschke Jan 6, 2024
90afda0
Update topology_graphical()
JBlaschke Jan 7, 2024
1f2135b
Update README to reflect changes to print_topology
JBlaschke Jan 7, 2024
502391f
Merge branch 'vc/pci' into jpb/iteration
JBlaschke Jan 7, 2024
6d4c0e2
typo
JBlaschke Jan 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
name = "Hwloc"
uuid = "0e44f5e4-bd66-52a0-8798-143a42290a1d"
authors = ["Erik Schnetter <[email protected]>"]
version = "3.0.0"
version = "3.1.1"

[deps]
AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"
CEnum = "fa961155-64e5-5f13-b03f-caf6b980ea82"
Hwloc_jll = "e33a78d0-f292-5ffc-b300-72abe9b543c8"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[compat]
CEnum = "0.4"
Hwloc_jll = "2.8"
julia = "1.6"
CEnum = "0.4"

[extras]
CpuId = "adafc99b-e345-5852-983c-f28acb93d879"
Expand Down
3 changes: 3 additions & 0 deletions src/Hwloc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ using Statistics
import Base: show, IteratorSize, IteratorEltype, isempty, eltype, iterate

include("libhwloc.jl")
include("libhwloc_extensions.jl")
include("lowlevel_api.jl")
include("highlevel_api.jl")
include("tree.jl")

export topology, gettopology, topology_info, getinfo, print_topology, topology_graphical
export num_physical_cores, num_virtual_cores, num_packages, num_numa_nodes
export cachesize, cachelinesize
export hwloc_typeof, hwloc_isa, collectobjects
export HwlocTreeNode

const machine_topology = Ref{Object}()

Expand Down
112 changes: 99 additions & 13 deletions src/highlevel_api.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using ..LibHwloc: hwloc_get_api_version
using ..LibHwloc: hwloc_get_api_version, HWLOC_OBJ_BRIDGE_HOST,
HWLOC_OBJ_OSDEV_BLOCK, HWLOC_OBJ_OSDEV_GPU, HWLOC_OBJ_OSDEV_NETWORK,
HWLOC_OBJ_OSDEV_OPENFABRICS, HWLOC_OBJ_OSDEV_DMA, HWLOC_OBJ_OSDEV_COPROC

using Printf

"""
Returns the API version of libhwloc.
Expand All @@ -14,27 +17,102 @@ function get_api_version()
VersionNumber(major, minor, patch)
end

const minimal_classes = [
"VGA", "NVMExp", "SATA", "Network", "Ethernet", "InfiniBand", "3D", "Other"
]
subtype_str(obj) = obj.subtype == "" ? "" : "($(obj.subtype))"

function is_visible(obj::Object; minimal=true)
t = hwloc_typeof(obj)

if t == :Bridge
for child in obj.io_children
if is_visible(child)
return true
end
end
return false
end

if t == :PCI_Device
if minimal
class_string = hwloc_pci_class_string(obj.attr.class_id)
return class_string in minimal_classes
else
return true
end
end

return true
end

"""
print_topology([io::IO = stdout, obj::Object = gettopology()])

Prints the topology of the given `obj` as a tree to `io`.
"""
function print_topology(io::IO = stdout, obj::Object = gettopology(); indent = "", newline = false, prefix = "")
function print_topology(
io::IO = stdout, obj::Object = gettopology();
indent = "", newline = false, prefix = "", minimal=true
)
t = hwloc_typeof(obj)

idxstr = t in (:Package, :Core, :PU) ? "L#$(obj.logical_index) P#$(obj.os_index) " : ""
attrstr = string(obj.attr)

# this is set to false whenever minimal == true and the PCI class_id strings
# don't match the minimal_classes list
print_device = is_visible(obj; minimal=minimal)

if t in (:L1Cache, :L2Cache, :L3Cache, :L1ICache)
tstr = first(string(t), 2)
attrstr = "("*_bytes2string(obj.attr.size)*")"
elseif t == :Bridge
if obj.attr.upstream_type == HWLOC_OBJ_BRIDGE_HOST
tstr = "HostBridge"
attrstr = ""
else
tstr = "PCIBridge"
attrstr = ""
end
elseif t == :PCI_Device
class_string = hwloc_pci_class_string(obj.attr.class_id)
tstr = "PCI"
attrstr = @sprintf(
"%s%02x:%02x.%01x",
Char(obj.attr.domain), obj.attr.bus, obj.attr.dev, obj.attr.func
) * " ($(class_string))"
elseif t == :OS_Device
attrstr = "\"$(obj.name)\""
tstr = if obj.attr.type == HWLOC_OBJ_OSDEV_BLOCK
"Block$(subtype_str(obj))"
elseif obj.attr.type == HWLOC_OBJ_OSDEV_GPU
"GPU"
elseif obj.attr.type == HWLOC_OBJ_OSDEV_NETWORK
"Net"
elseif obj.attr.type == HWLOC_OBJ_OSDEV_OPENFABRICS
"OpenFabrics"
elseif obj.attr.type == HWLOC_OBJ_OSDEV_DMA
"DMA"
elseif obj.attr.type == HWLOC_OBJ_OSDEV_COPROC
"CoProc$(subtype_str(obj))"
else
string(obj.attr)
end
else
tstr = string(t)
attrstr = obj.name
end

newline && print(io, "\n", indent)
print(io, prefix, tstr, " ",
idxstr,
attrstr, obj.mem > 0 ? "("*_bytes2string(obj.mem)*")" : "")
if print_device
newline && print(io, "\n", indent)
print(
io, prefix, tstr, " ", idxstr, attrstr,
obj.mem > 0 ? "("*_bytes2string(obj.mem)*")" : ""
)
else
return nothing
end

for memchild in obj.memory_children
memstr = "("*_bytes2string(memchild.mem)*")"
Expand All @@ -50,19 +128,27 @@ function print_topology(io::IO = stdout, obj::Object = gettopology(); indent = "
print_topology(io, child; indent = indent*repeat(" ", 4), newline=true)
end
end

for child in obj.io_children
print_topology(io, child; indent=indent*repeat(" ", 4), newline=true)
end

return nothing
end
print_topology(obj::Object) = print_topology(stdout, obj)

"""
Returns the top-level system topology `Object`.

On first call, it loads the topology by querying
libhwloc and caches the result.
On first call, it loads the topology by querying libhwloc and caches the result.
Pass `reload=true` in order to force reload.
"""
function gettopology()
if !isassigned(machine_topology)
machine_topology[] = topology_load()
function gettopology(htopo=nothing; reload=false)
if reload || (!isassigned(machine_topology))
if isnothing(htopo)
htopo=topology_init()
end
machine_topology[] = topology_load(htopo)
end

return machine_topology[]
Expand All @@ -71,7 +157,7 @@ end
"""
Prints the system topology as a tree.
"""
topology() = print_topology(gettopology())
topology(htopo=nothing) = print_topology(gettopology(htopo))

"""
Prints a summary of the system topology (loosely similar to `hwloc-info`).
Expand Down Expand Up @@ -306,6 +392,6 @@ The quality of the result might depend on the used terminal and might vary betwe
**Note:** The specific visualization may change between minor versions.
"""
function topology_graphical()
run(`$(lstopo_no_graphics()) --no-io --no-legend --of txt`)
run(`$(lstopo_no_graphics()) --no-legend --of txt`)
return nothing
end
6 changes: 6 additions & 0 deletions src/libhwloc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,12 @@ const hwloc_nodeset_t = hwloc_bitmap_t

const hwloc_const_nodeset_t = hwloc_const_bitmap_t

# TODO: do we need this?
# struct hwloc_obj_memory_page_type_s
# size::Culonglong
# count::Culonglong
# end

@cenum hwloc_obj_type_t::UInt32 begin
HWLOC_OBJ_MACHINE = 0
HWLOC_OBJ_PACKAGE = 1
Expand Down
17 changes: 17 additions & 0 deletions src/libhwloc_extensions.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module LibHwlocExtensions

using ..LibHwloc: libhwloc, Hwloc_jll

using CEnum

function hwloc_pci_class_string(class_id)
val = ccall(
(:hwloc_pci_class_string, libhwloc),
Ptr{Cchar},
(Cushort,),
class_id
)
return unsafe_string(val)
end

end
Loading