hwloc 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +100 -0
- data/hwloc.gemspec +14 -0
- data/lib/hwloc.rb +7 -0
- data/lib/hwloc/Bind.rb +280 -0
- data/lib/hwloc/Bitmap.rb +352 -0
- data/lib/hwloc/Edition.rb +68 -0
- data/lib/hwloc/Export.rb +66 -0
- data/lib/hwloc/Hwloc.rb +24 -0
- data/lib/hwloc/Obj.rb +432 -0
- data/lib/hwloc/Topology.rb +395 -0
- metadata +74 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 61e8806d799ed1d37e565e888eed0de26488116a
|
4
|
+
data.tar.gz: 541e27b80809c3d14acade623fbcdbaab8b25810
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0bf475374cc8559d3552ddb2810aee513b1a50aa2d22d23a95e9580f38e4797c171fb123cc32e63b9fc4e41bdfb1bc2c78a4bf18577a8342bd13f1140d2216f8
|
7
|
+
data.tar.gz: 917a4118dd5ea19bb4f95385cda8cf8ffc331534e9e77ed04c54b0c57f870de687db2406167c5bb8e26e79472afa069fc2a859f0611709ffeccc39fb63e6a062
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2017, Brice Videau <brice.videau@imag.fr>
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
8
|
+
list of conditions and the following disclaimer.
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
10
|
+
this list of conditions and the following disclaimer in the documentation
|
11
|
+
and/or other materials provided with the distribution.
|
12
|
+
|
13
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
14
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
15
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
16
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
17
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
18
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
19
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
20
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
21
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
22
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# hwloc-ruby
|
2
|
+
|
3
|
+
Simple example using only the compute topology.
|
4
|
+
The pagemap tool can be found here: https://forge.imag.fr/projects/pagemap/
|
5
|
+
Note that you will certainly need to be root to be able to use pagemap.
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
require 'hwloc'
|
9
|
+
require 'ffi'
|
10
|
+
|
11
|
+
|
12
|
+
# helper function to print memory location (may need pagemap on older version of hwloc)
|
13
|
+
def print_pointer_location(ptr, t)
|
14
|
+
if t.respond_to? :get_area_memlocation
|
15
|
+
page_number = (ptr.size.to_f / $page_size).ceil
|
16
|
+
base_address = ptr.address - ( ptr.address % $page_size )
|
17
|
+
ptrs = page_number.times.collect { |i|
|
18
|
+
FFI::Pointer::new(base_address + i*$page_size).slice(0, $page_size)
|
19
|
+
}
|
20
|
+
ptrs.each { |ptr|
|
21
|
+
p t.get_area_memlocation(ptr, :MEMBIND_BYNODESET)
|
22
|
+
}
|
23
|
+
else
|
24
|
+
puts "pagemap #{Process::pid} -n #{ptr.address.to_s(16)}-#{(ptr.address+ptr.size-1).to_s(16)}"
|
25
|
+
puts `pagemap #{Process::pid} -n #{ptr.address.to_s(16)}-#{(ptr.address+ptr.size-1).to_s(16)}`
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
t = Hwloc::Topology::new
|
30
|
+
t.flags = Hwloc::Topology::FLAG_ICACHES
|
31
|
+
t.load
|
32
|
+
|
33
|
+
$page_size = t.machines.first.memory.page_types.first.size
|
34
|
+
|
35
|
+
#Get some info on the machine:
|
36
|
+
|
37
|
+
o = t.root_obj
|
38
|
+
puts o.infos
|
39
|
+
|
40
|
+
|
41
|
+
#Print all the object doing a depth first traversal:
|
42
|
+
t.each { |o|
|
43
|
+
puts o
|
44
|
+
}
|
45
|
+
|
46
|
+
#Print all the objects doing a breadth first traversal:
|
47
|
+
t.depth.times { |d|
|
48
|
+
puts t.each_by_depth(d).to_a.join(", ")
|
49
|
+
}
|
50
|
+
|
51
|
+
# find the number of level of caches on the machine and their size:
|
52
|
+
first_core = t.cores.first
|
53
|
+
caches = first_core.ancestors.take_while{ |o| o.type == :OBJ_CACHE }
|
54
|
+
caches.each_with_index { |c,i|
|
55
|
+
puts "#{c.type_name}: #{c.attr.size/1024}KiB"
|
56
|
+
}
|
57
|
+
|
58
|
+
#migrate the execution to different OBJ_PU
|
59
|
+
t.pus.shuffle.first(3).each { |pu|
|
60
|
+
t.set_cpubind(pu.cpuset)
|
61
|
+
puts "Processing on #{pu} #P#{pu.os_index}"
|
62
|
+
i = 0
|
63
|
+
(1<<26).times { i+=1 }
|
64
|
+
}
|
65
|
+
|
66
|
+
#allocate memory on different nodes using hwloc (if you have any)
|
67
|
+
if t.numanodes.length > 0 then
|
68
|
+
ptrs = t.numanodes.collect { |n|
|
69
|
+
ptr = t.alloc_membind(10*4*1024, n.cpuset, :MEMBIND_BIND)
|
70
|
+
ptr.clear
|
71
|
+
}
|
72
|
+
sleep 1
|
73
|
+
ptrs.each { |ptr|
|
74
|
+
p t.get_area_membind(ptr)
|
75
|
+
print_pointer_location(ptr, t)
|
76
|
+
puts
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
#migrating memory using hwloc (We don't control alignment so last page of each allocation can be migrated twice because it overlaps two memory areas)
|
81
|
+
if t.numanodes.length > 0 then
|
82
|
+
ptrs = t.numanodes.collect { |n|
|
83
|
+
ptr = FFI::MemoryPointer::new(10*4*1024)
|
84
|
+
t.set_area_membind(ptr, n.cpuset, :MEMBIND_BIND, :MEMBIND_MIGRATE)
|
85
|
+
ptr.clear
|
86
|
+
}
|
87
|
+
sleep 1
|
88
|
+
ptrs.each { |ptr|
|
89
|
+
p t.get_area_membind(ptr)
|
90
|
+
print_pointer_location(ptr, t)
|
91
|
+
puts
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
#allocate and migrate memory in an interleaved way
|
96
|
+
ptr = FFI::MemoryPointer::new(10*4*1024)
|
97
|
+
t.set_area_membind(ptr, t.machines.first.cpuset, :MEMBIND_INTERLEAVE, :MEMBIND_MIGRATE)
|
98
|
+
p t.get_area_membind(ptr)
|
99
|
+
print_pointer_location(ptr, t)
|
100
|
+
```
|
data/hwloc.gemspec
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'hwloc'
|
3
|
+
s.version = "0.1"
|
4
|
+
s.author = "Brice Videau"
|
5
|
+
s.email = "brice.videau@imag.fr"
|
6
|
+
s.homepage = "https://github.com/Nanosim-LIG/hwloc-ruby"
|
7
|
+
s.summary = "hwloc ruby bindings"
|
8
|
+
s.description = "hwloc ruby bindings for versions 1.10 onward"
|
9
|
+
s.files = Dir['hwloc.gemspec', 'LICENSE', 'README.md', 'lib/**/*']
|
10
|
+
s.has_rdoc = false
|
11
|
+
s.license = 'BSD-2-Clause'
|
12
|
+
s.required_ruby_version = '>= 1.9.3'
|
13
|
+
s.add_dependency 'ffi', '~> 1.9', '>=1.9.3'
|
14
|
+
end
|
data/lib/hwloc.rb
ADDED
data/lib/hwloc/Bind.rb
ADDED
@@ -0,0 +1,280 @@
|
|
1
|
+
module Hwloc
|
2
|
+
CpubindFlags = enum( :cpubin_flags, [
|
3
|
+
:CPUBIND_PROCESS, 1<<0,
|
4
|
+
:CPUBIND_THREAD, 1<<1,
|
5
|
+
:CPUBIND_STRICT, 1<<2,
|
6
|
+
:CPUBIND_NOMEMBIND, 1<<3
|
7
|
+
] )
|
8
|
+
|
9
|
+
MembindPolicy = enum( :membind_policy, [
|
10
|
+
:MEMBIND_DEFAULT, 0,
|
11
|
+
:MEMBIND_FIRSTTOUCH, 1,
|
12
|
+
:MEMBIND_BIND, 2,
|
13
|
+
:MEMBIND_INTERLEAVE, 3,
|
14
|
+
:MEMBIND_REPLICATE, 4,
|
15
|
+
:MEMBIND_NEXTTOUCH, 5,
|
16
|
+
:MEMBIND_MIXED, -1
|
17
|
+
] )
|
18
|
+
|
19
|
+
MembindFlags = enum( :membind_flags, [
|
20
|
+
:MEMBIND_PROCESS, 1<<0,
|
21
|
+
:MEMBIND_THREAD, 1<<1,
|
22
|
+
:MEMBIND_STRICT, 1<<2,
|
23
|
+
:MEMBIND_MIGRATE, 1<<3,
|
24
|
+
:MEMBIND_NOCPUBIND, 1<<4,
|
25
|
+
:MEMBIND_BYNODESET, 1<<5
|
26
|
+
] )
|
27
|
+
|
28
|
+
attach_function :hwloc_set_cpubind, [:topology, :cpuset, :int], :int
|
29
|
+
attach_function :hwloc_get_cpubind, [:topology, :cpuset, :int], :int
|
30
|
+
attach_function :hwloc_set_proc_cpubind, [:topology, :hwloc_pid_t, :cpuset, :int], :int
|
31
|
+
attach_function :hwloc_get_proc_cpubind, [:topology, :hwloc_pid_t, :cpuset, :int], :int
|
32
|
+
attach_function :hwloc_set_thread_cpubind, [:topology, :hwloc_thread_t, :cpuset, :int], :int
|
33
|
+
attach_function :hwloc_get_thread_cpubind, [:topology, :hwloc_thread_t, :cpuset, :int], :int
|
34
|
+
attach_function :hwloc_get_last_cpu_location, [:topology, :cpuset, :int], :int
|
35
|
+
attach_function :hwloc_get_proc_last_cpu_location, [:topology, :hwloc_pid_t, :cpuset, :int], :int
|
36
|
+
|
37
|
+
class BindError < Error
|
38
|
+
end
|
39
|
+
|
40
|
+
class CpubindError < BindError
|
41
|
+
end
|
42
|
+
|
43
|
+
class Topology
|
44
|
+
|
45
|
+
def set_cpubind(cpuset, flags = 0)
|
46
|
+
err = Hwloc.hwloc_set_cpubind(@ptr, cpuset, flags)
|
47
|
+
raise CpubindError if err == -1
|
48
|
+
return self
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_cpubind(flags = 0)
|
52
|
+
cpuset = Cpuset::new
|
53
|
+
err = Hwloc.hwloc_get_cpubind(@ptr, cpuset, flags)
|
54
|
+
raise CpubindError if err == -1
|
55
|
+
return cpuset
|
56
|
+
end
|
57
|
+
|
58
|
+
def set_proc_cpubind(pid, cpuset, flags = 0)
|
59
|
+
err = Hwloc.hwloc_set_proc_cpubind(@ptr, pid, cpuset, flags)
|
60
|
+
raise CpubindError if err == -1
|
61
|
+
return self
|
62
|
+
end
|
63
|
+
|
64
|
+
def get_proc_cpubind(pid, flags)
|
65
|
+
cpuset = Cpuset::new
|
66
|
+
err = Hwloc.hwloc_get_proc_cpubind(@ptr, pid, cpuset, flags)
|
67
|
+
raise CpubindError if err == -1
|
68
|
+
return cpuset
|
69
|
+
end
|
70
|
+
|
71
|
+
def set_thread_cpubind(thread, cpuset, flags = 0)
|
72
|
+
err = Hwloc.hwloc_set_thread_cpubind(@ptr, thread, cpuset, flags)
|
73
|
+
raise CpubindError if err == -1
|
74
|
+
return self
|
75
|
+
end
|
76
|
+
|
77
|
+
def get_thread_cpubind(thread, flags = 0)
|
78
|
+
cpuset = Cpuset::new
|
79
|
+
err = Hwloc.hwloc_get_thread_cpubind(@ptr, thread, cpuset, flags)
|
80
|
+
raise CpubindError if err == -1
|
81
|
+
return cpuset
|
82
|
+
end
|
83
|
+
|
84
|
+
def get_last_cpu_location(flags = 0)
|
85
|
+
cpuset = Cpuset::new
|
86
|
+
err = Hwloc.hwloc_get_last_cpu_location(@ptr, cpuset, flags)
|
87
|
+
raise CpubindError if err == -1
|
88
|
+
return cpuset
|
89
|
+
end
|
90
|
+
|
91
|
+
def get_proc_last_cpu_location(pid, flags = 0)
|
92
|
+
cpuset = Cpuset::new
|
93
|
+
err = Hwloc.hwloc_get_proc_last_cpu_location(@ptr, pid, cpuset, flags)
|
94
|
+
raise CpubindError if err == -1
|
95
|
+
return cpuset
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
class MembindError < BindError
|
101
|
+
end
|
102
|
+
|
103
|
+
attach_function :hwloc_set_membind_nodeset, [:topology, :nodeset, :membind_policy, :int], :int
|
104
|
+
attach_function :hwloc_set_membind, [:topology, :bitmap, :membind_policy, :int], :int
|
105
|
+
attach_function :hwloc_get_membind_nodeset, [:topology, :nodeset, :pointer, :int], :int
|
106
|
+
attach_function :hwloc_get_membind, [:topology, :bitmap, :pointer, :int], :int
|
107
|
+
attach_function :hwloc_set_proc_membind_nodeset, [:topology, :hwloc_pid_t, :nodeset, :membind_policy, :int], :int
|
108
|
+
attach_function :hwloc_set_proc_membind, [:topology, :hwloc_pid_t, :bitmap, :membind_policy, :int], :int
|
109
|
+
attach_function :hwloc_get_proc_membind_nodeset, [:topology, :hwloc_pid_t, :nodeset, :pointer, :int], :int
|
110
|
+
attach_function :hwloc_get_proc_membind, [:topology, :hwloc_pid_t, :bitmap, :pointer, :int], :int
|
111
|
+
|
112
|
+
attach_function :hwloc_set_area_membind_nodeset, [:topology, :pointer, :size_t, :nodeset, :membind_policy, :int], :int
|
113
|
+
attach_function :hwloc_set_area_membind, [:topology, :pointer, :size_t, :bitmap, :membind_policy, :int], :int
|
114
|
+
attach_function :hwloc_get_area_membind_nodeset, [:topology, :pointer, :size_t, :nodeset, :pointer, :int], :int
|
115
|
+
attach_function :hwloc_get_area_membind, [:topology, :pointer, :size_t, :bitmap, :pointer, :int], :int
|
116
|
+
|
117
|
+
begin
|
118
|
+
attach_function :hwloc_get_area_memlocation, [:topology, :pointer, :size_t, :bitmap, :int], :int
|
119
|
+
rescue FFI::NotFoundError
|
120
|
+
warn "Missing hwloc_get_area_memlocation support!"
|
121
|
+
end
|
122
|
+
|
123
|
+
attach_function :hwloc_alloc, [:topology, :size_t], :pointer
|
124
|
+
attach_function :hwloc_alloc_membind_nodeset, [:topology, :size_t, :nodeset, :membind_policy, :int], :pointer
|
125
|
+
attach_function :hwloc_alloc_membind, [:topology, :size_t, :bitmap, :membind_policy, :int], :pointer
|
126
|
+
attach_function :hwloc_free, [:topology, :pointer, :size_t], :int
|
127
|
+
|
128
|
+
class Topology
|
129
|
+
|
130
|
+
def set_membind_nodeset(nodeset, policy, flags=0)
|
131
|
+
err = Hwloc.hwloc_set_membind_nodeset(@ptr, nodeset, policy, flags)
|
132
|
+
raise MembindError if err == -1
|
133
|
+
return self
|
134
|
+
end
|
135
|
+
|
136
|
+
def set_membind(set, policy, flags=0)
|
137
|
+
err = Hwloc.hwloc_set_membind(@ptr, set, policy, flags)
|
138
|
+
raise MembindError if err == -1
|
139
|
+
return self
|
140
|
+
end
|
141
|
+
|
142
|
+
def get_membind_nodeset(flags=0)
|
143
|
+
nodeset = Nodeset::new
|
144
|
+
policy_p = FFI::MemoryPointer::new(MembindPolicy.native_type)
|
145
|
+
err = Hwloc.hwloc_get_membind_nodeset(@ptr, nodeset, policy_p, flags)
|
146
|
+
raise MembindError if err == -1
|
147
|
+
policy = policy_p.read_int
|
148
|
+
return [nodeset, MembindPolicy[policy]]
|
149
|
+
end
|
150
|
+
|
151
|
+
def get_membind(flags=0)
|
152
|
+
set = Bitmap::new
|
153
|
+
policy_p = FFI::MemoryPointer::new(MembindPolicy.native_type)
|
154
|
+
err = Hwloc.hwloc_get_membind(@ptr, set, policy_p, flags)
|
155
|
+
raise MembindError if err == -1
|
156
|
+
policy = policy_p.read_int
|
157
|
+
return [set, MembindPolicy[policy]]
|
158
|
+
end
|
159
|
+
|
160
|
+
def set_proc_membind_nodeset(pid, nodeset, policy, flags=0)
|
161
|
+
err = Hwloc.hwloc_set_proc_membind_nodeset(@ptr, pid, nodeset, policy, flags)
|
162
|
+
raise MembindError if err == -1
|
163
|
+
return self
|
164
|
+
end
|
165
|
+
|
166
|
+
def set_proc_membind(pid, set, policy, flags=0)
|
167
|
+
err = Hwloc.hwloc_set_proc_membind(@ptr, pid, set, policy, flags)
|
168
|
+
raise MembindError if err == -1
|
169
|
+
return self
|
170
|
+
end
|
171
|
+
|
172
|
+
def get_proc_membind_nodeset(pid, flags=0)
|
173
|
+
nodeset = Nodeset::new
|
174
|
+
policy_p = FFI::MemoryPointer::new(MembindPolicy.native_type)
|
175
|
+
err = Hwloc.hwloc_get_proc_membind_nodeset(@ptr, pid, nodeset, policy_p, flags)
|
176
|
+
raise MembindError if err == -1
|
177
|
+
policy = MembindPolicy[policy_p.read_int]
|
178
|
+
return [nodeset, policy]
|
179
|
+
end
|
180
|
+
|
181
|
+
def get_proc_membind(pid, flags=0)
|
182
|
+
set = Bitmap::new
|
183
|
+
policy_p = FFI::MemoryPointer::new(MembindPolicy.native_type)
|
184
|
+
err = Hwloc.hwloc_get_proc_membind(@ptr, pid, set, policy_p, flags)
|
185
|
+
raise MembindError if err == -1
|
186
|
+
policy = MembindPolicy[policy_p.read_int]
|
187
|
+
return [set, policy]
|
188
|
+
end
|
189
|
+
|
190
|
+
def set_area_membind_nodeset(pointer, nodeset, policy, flags=0)
|
191
|
+
err = Hwloc.hwloc_set_area_membind_nodeset(@ptr, pointer, pointer.size, nodeset, policy, flags)
|
192
|
+
raise MembindError if err == -1
|
193
|
+
return self
|
194
|
+
end
|
195
|
+
|
196
|
+
def set_area_membind(pointer, set, policy, flags=0)
|
197
|
+
err = Hwloc.hwloc_set_area_membind(@ptr, pointer, pointer.size, set, policy, flags)
|
198
|
+
raise MembindError if err == -1
|
199
|
+
return self
|
200
|
+
end
|
201
|
+
|
202
|
+
def get_area_membind_nodeset(pointer, flags=0)
|
203
|
+
nodeset = Nodeset::new
|
204
|
+
policy_p = FFI::MemoryPointer::new(MembindPolicy.native_type)
|
205
|
+
err = Hwloc.hwloc_get_area_membind_nodeset(@ptr, pointer, pointer.size, nodeset, policy_p, flags)
|
206
|
+
raise MembindError if err == -1
|
207
|
+
policy = MembindPolicy[policy_p.read_int]
|
208
|
+
return [nodeset, policy]
|
209
|
+
end
|
210
|
+
|
211
|
+
def get_area_membind(pointer, flags=0)
|
212
|
+
set = Bitmap::new
|
213
|
+
policy_p = FFI::MemoryPointer::new(MembindPolicy.native_type)
|
214
|
+
err = Hwloc.hwloc_get_area_membind(@ptr, pointer, pointer.size, set, policy_p, flags)
|
215
|
+
raise MembindError if err == -1
|
216
|
+
policy = MembindPolicy[policy_p.read_int]
|
217
|
+
return [set, policy]
|
218
|
+
end
|
219
|
+
|
220
|
+
if Hwloc.respond_to?(:hwloc_get_area_memlocation)
|
221
|
+
def get_area_memlocation(pointer, flags=0)
|
222
|
+
set = Bitmap::new
|
223
|
+
err = Hwloc.hwloc_get_area_memlocation(@ptr, pointer, pointer.size, set, flags)
|
224
|
+
raise MembindError if err == -1
|
225
|
+
return set
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def alloc(size)
|
230
|
+
ptr = Hwloc.hwloc_alloc(@ptr, size)
|
231
|
+
raise MembindError if ptr.null?
|
232
|
+
ptr = ptr.slice(0, size)
|
233
|
+
return FFI::AutoPointer::new(ptr, self.method(:free))
|
234
|
+
end
|
235
|
+
|
236
|
+
def alloc_membind_nodeset(size, nodeset, policy, flags=0)
|
237
|
+
ptr = Hwloc.hwloc_alloc_membind_nodeset(@ptr, size, nodeset, policy, flags)
|
238
|
+
raise MembindError if ptr.null?
|
239
|
+
ptr = ptr.slice(0, size)
|
240
|
+
return FFI::AutoPointer::new(ptr, self.method(:free))
|
241
|
+
end
|
242
|
+
|
243
|
+
def alloc_membind(size, set, policy, flags=0)
|
244
|
+
ptr = Hwloc.hwloc_alloc_membind(@ptr, size, set, policy, flags)
|
245
|
+
raise MembindError if ptr.null?
|
246
|
+
ptr = ptr.slice(0, size)
|
247
|
+
return FFI::AutoPointer::new(ptr, self.method(:free))
|
248
|
+
end
|
249
|
+
|
250
|
+
def alloc_membind_policy_nodeset(size, nodeset, policy, flags=0)
|
251
|
+
begin
|
252
|
+
return alloc_membind_nodeset(size, nodeset, policy, flags)
|
253
|
+
rescue MembindError
|
254
|
+
set_membind_nodeset(nodeset, policy, flags)
|
255
|
+
ptr = alloc(size)
|
256
|
+
ptr.clear if policy != Hwloc::MEMBIND_FIRSTTOUCH
|
257
|
+
return ptr
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def alloc_membind_policy(size, set, policy, flags=0)
|
262
|
+
begin
|
263
|
+
return alloc_membind(size, set, policy, flags)
|
264
|
+
rescue MembindError
|
265
|
+
set_membind(set, policy, flags)
|
266
|
+
ptr = alloc(size)
|
267
|
+
ptr.clear if policy != Hwloc::MEMBIND_FIRSTTOUCH
|
268
|
+
return ptr
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
def free(pointer)
|
273
|
+
Hwloc.hwloc_free(@ptr, pointer, pointer.size)
|
274
|
+
end
|
275
|
+
|
276
|
+
private :free
|
277
|
+
|
278
|
+
end
|
279
|
+
|
280
|
+
end
|
data/lib/hwloc/Bitmap.rb
ADDED
@@ -0,0 +1,352 @@
|
|
1
|
+
module Hwloc
|
2
|
+
|
3
|
+
typedef :pointer, :bitmap
|
4
|
+
typedef :bitmap, :cpuset
|
5
|
+
typedef :bitmap, :nodeset
|
6
|
+
|
7
|
+
attach_function :hwloc_bitmap_alloc, [], :bitmap
|
8
|
+
attach_function :hwloc_bitmap_free, [:bitmap], :void
|
9
|
+
|
10
|
+
attach_function :hwloc_bitmap_dup, [:bitmap], :bitmap
|
11
|
+
|
12
|
+
attach_function :hwloc_bitmap_snprintf, [:pointer, :size_t, :bitmap], :int
|
13
|
+
attach_function :hwloc_bitmap_sscanf, [:bitmap, :pointer], :int
|
14
|
+
attach_function :hwloc_bitmap_list_snprintf, [:pointer, :size_t, :bitmap], :int
|
15
|
+
attach_function :hwloc_bitmap_list_sscanf, [:bitmap, :pointer], :int
|
16
|
+
|
17
|
+
attach_function :hwloc_bitmap_zero, [:bitmap], :void
|
18
|
+
attach_function :hwloc_bitmap_fill, [:bitmap], :void
|
19
|
+
attach_function :hwloc_bitmap_only, [:bitmap, :uint], :void
|
20
|
+
attach_function :hwloc_bitmap_allbut, [:bitmap, :uint], :void
|
21
|
+
|
22
|
+
attach_function :hwloc_bitmap_set, [:bitmap, :uint], :void
|
23
|
+
attach_function :hwloc_bitmap_clr, [:bitmap, :uint], :void
|
24
|
+
|
25
|
+
attach_function :hwloc_bitmap_set_range, [:bitmap, :uint, :int], :void
|
26
|
+
attach_function :hwloc_bitmap_clr_range, [:bitmap, :uint, :int], :void
|
27
|
+
|
28
|
+
attach_function :hwloc_bitmap_singlify, [:bitmap], :void
|
29
|
+
|
30
|
+
attach_function :hwloc_bitmap_to_ulong, [:bitmap], :ulong
|
31
|
+
attach_function :hwloc_bitmap_to_ith_ulong, [:bitmap, :uint], :ulong
|
32
|
+
attach_function :hwloc_bitmap_isset, [:bitmap, :uint], :int
|
33
|
+
attach_function :hwloc_bitmap_iszero, [:bitmap], :int
|
34
|
+
attach_function :hwloc_bitmap_isfull, [:bitmap], :int
|
35
|
+
attach_function :hwloc_bitmap_first, [:bitmap], :int
|
36
|
+
attach_function :hwloc_bitmap_next, [:bitmap, :int], :int
|
37
|
+
attach_function :hwloc_bitmap_last, [:bitmap], :int
|
38
|
+
attach_function :hwloc_bitmap_weight, [:bitmap], :int
|
39
|
+
|
40
|
+
attach_function :hwloc_bitmap_or, [:bitmap, :bitmap, :bitmap], :void
|
41
|
+
attach_function :hwloc_bitmap_and, [:bitmap, :bitmap, :bitmap], :void
|
42
|
+
attach_function :hwloc_bitmap_andnot, [:bitmap, :bitmap, :bitmap], :void
|
43
|
+
attach_function :hwloc_bitmap_xor, [:bitmap, :bitmap, :bitmap], :void
|
44
|
+
attach_function :hwloc_bitmap_not, [:bitmap, :bitmap], :void
|
45
|
+
|
46
|
+
attach_function :hwloc_bitmap_intersects, [:bitmap, :bitmap], :int
|
47
|
+
attach_function :hwloc_bitmap_isincluded, [:bitmap, :bitmap], :int
|
48
|
+
attach_function :hwloc_bitmap_isequal, [:bitmap, :bitmap], :int
|
49
|
+
attach_function :hwloc_bitmap_compare_first, [:bitmap, :bitmap], :int
|
50
|
+
attach_function :hwloc_bitmap_compare, [:bitmap, :bitmap], :int
|
51
|
+
|
52
|
+
class Bitmap
|
53
|
+
include Enumerable
|
54
|
+
attr_reader :ptr
|
55
|
+
|
56
|
+
alias to_ptr ptr
|
57
|
+
|
58
|
+
def inspect
|
59
|
+
return "#<#{self.class}: {#{to_a.join(",")}}>"
|
60
|
+
end
|
61
|
+
|
62
|
+
def initialize( *args )
|
63
|
+
if args.length == 0 then
|
64
|
+
@ptr = FFI::AutoPointer::new( Hwloc.hwloc_bitmap_alloc, Hwloc.method(:hwloc_bitmap_free) )
|
65
|
+
elsif args.length == 1 then
|
66
|
+
arg = args[0]
|
67
|
+
if arg.kind_of?( Bitmap ) then
|
68
|
+
@ptr = FFI::AutoPointer::new( Hwloc.hwloc_bitmap_dup(arg.ptr), Hwloc.method(:hwloc_bitmap_free) )
|
69
|
+
elsif arg.kind_of?( FFI::Pointer ) then
|
70
|
+
@ptr = FFI::AutoPointer::new( Hwloc.hwloc_bitmap_dup(arg), Hwloc.method(:hwloc_bitmap_free) )
|
71
|
+
elsif arg.kind_of?( String ) then
|
72
|
+
s_ptr = FFI::MemoryPointer::from_string(arg)
|
73
|
+
@ptr = FFI::AutoPointer::new( Hwloc.hwloc_bitmap_alloc, Hwloc.method(:hwloc_bitmap_free) )
|
74
|
+
Hwloc.hwloc_bitmap_sscanf(@ptr,s_ptr)
|
75
|
+
elsif arg.kind_of?( Array ) then
|
76
|
+
list = []
|
77
|
+
arg.each { |e|
|
78
|
+
if e.kind_of?(Range) then
|
79
|
+
if e.last == Float::INFINITY then
|
80
|
+
list << "#{e.first}-"
|
81
|
+
else
|
82
|
+
list << "#{e.first}-#{e.last - (e.exclude_end? ? 1 : 0)}"
|
83
|
+
end
|
84
|
+
else
|
85
|
+
list << e.to_s
|
86
|
+
end
|
87
|
+
}
|
88
|
+
str = list.join(",")
|
89
|
+
s_ptr = FFI::MemoryPointer::from_string(str)
|
90
|
+
@ptr = FFI::AutoPointer::new( Hwloc.hwloc_bitmap_alloc, Hwloc.method(:hwloc_bitmap_free) )
|
91
|
+
Hwloc.hwloc_bitmap_list_sscanf(@ptr,s_ptr)
|
92
|
+
elsif arg.kind_of?( Range ) then
|
93
|
+
if arg.last == Float::INFINITY then
|
94
|
+
str = "#{arg.first}-"
|
95
|
+
else
|
96
|
+
str = "#{arg.first}-#{arg.last - (arg.exclude_end? ? 1 : 0)}"
|
97
|
+
end
|
98
|
+
s_ptr = FFI::MemoryPointer::from_string(str)
|
99
|
+
@ptr = FFI::AutoPointer::new( Hwloc.hwloc_bitmap_alloc, Hwloc.method(:hwloc_bitmap_free) )
|
100
|
+
Hwloc.hwloc_bitmap_list_sscanf(@ptr,s_ptr)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def dup
|
106
|
+
return Bitmap::new( self )
|
107
|
+
end
|
108
|
+
|
109
|
+
def to_s
|
110
|
+
size = Hwloc.hwloc_bitmap_snprintf(nil, 0, @ptr)
|
111
|
+
s_ptr = FFI::MemoryPointer::new(size+1)
|
112
|
+
Hwloc.hwloc_bitmap_snprintf(s_ptr, size+1, @ptr)
|
113
|
+
s_ptr.read_string
|
114
|
+
end
|
115
|
+
|
116
|
+
def to_a
|
117
|
+
size = Hwloc.hwloc_bitmap_list_snprintf(nil, 0, @ptr)
|
118
|
+
s_ptr = FFI::MemoryPointer::new(size+1)
|
119
|
+
Hwloc.hwloc_bitmap_list_snprintf(s_ptr, size+1, @ptr)
|
120
|
+
str = s_ptr.read_string
|
121
|
+
str.split(",").collect { |e|
|
122
|
+
if e.match("-") then
|
123
|
+
rgs = e.split("-")
|
124
|
+
if rgs.length == 1 then
|
125
|
+
en = Float::INFINITY
|
126
|
+
else
|
127
|
+
en = rgs[1].to_i
|
128
|
+
end
|
129
|
+
Range::new(rgs[0].to_i,en)
|
130
|
+
else
|
131
|
+
e.to_i
|
132
|
+
end
|
133
|
+
}
|
134
|
+
end
|
135
|
+
|
136
|
+
def to_i
|
137
|
+
return to_s.to_i(16)
|
138
|
+
end
|
139
|
+
|
140
|
+
def zero!
|
141
|
+
Hwloc.hwloc_bitmap_zero(@ptr)
|
142
|
+
return self
|
143
|
+
end
|
144
|
+
|
145
|
+
alias clear zero!
|
146
|
+
|
147
|
+
def fill!
|
148
|
+
Hwloc.hwloc_bitmap_fill(@ptr)
|
149
|
+
return self
|
150
|
+
end
|
151
|
+
|
152
|
+
def only!(indx)
|
153
|
+
Hwloc.hwloc_bitmap_only(@ptr, indx)
|
154
|
+
return self
|
155
|
+
end
|
156
|
+
|
157
|
+
def all_but!(indx)
|
158
|
+
Hwloc.hwloc_bitmap_allbut(@ptr, indx)
|
159
|
+
return self
|
160
|
+
end
|
161
|
+
|
162
|
+
def set(indx, val)
|
163
|
+
if val then
|
164
|
+
Hwloc.hwloc_bitmap_set(@ptr, indx)
|
165
|
+
else
|
166
|
+
Hwloc.hwloc_bitmap_clr(@ptr, indx)
|
167
|
+
end
|
168
|
+
return val
|
169
|
+
end
|
170
|
+
|
171
|
+
def set_range(indx, val)
|
172
|
+
b = indx.first
|
173
|
+
if indx.last == Float::INFINITY then
|
174
|
+
e = -1
|
175
|
+
else
|
176
|
+
e = indx.last
|
177
|
+
e = e - 1 if indx.exclude_end?
|
178
|
+
end
|
179
|
+
if val then
|
180
|
+
Hwloc.hwloc_bitmap_set_range(@ptr, b, e)
|
181
|
+
else
|
182
|
+
Hwloc.hwloc_bitmap_clr_range(@ptr, b, e)
|
183
|
+
end
|
184
|
+
return val
|
185
|
+
end
|
186
|
+
|
187
|
+
private :set_range, :set
|
188
|
+
|
189
|
+
def []=(indx, val)
|
190
|
+
if indx.kind_of?(Range) then
|
191
|
+
set_range(indx, val)
|
192
|
+
else
|
193
|
+
set(indx, val)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def [](indx)
|
198
|
+
if Hwloc.hwloc_bitmap_isset(@ptr, indx) != 0 then
|
199
|
+
return true
|
200
|
+
else
|
201
|
+
return false
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def singlify!
|
206
|
+
Hwloc.hwloc_bitmap_singlify(@ptr)
|
207
|
+
return self
|
208
|
+
end
|
209
|
+
|
210
|
+
def zero?
|
211
|
+
if Hwloc.hwloc_bitmap_iszero(@ptr) != 0 then
|
212
|
+
return true
|
213
|
+
else
|
214
|
+
return false
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
alias empty? zero?
|
219
|
+
|
220
|
+
def full?
|
221
|
+
if Hwloc.hwloc_bitmap_isfull(@ptr) != 0 then
|
222
|
+
return true
|
223
|
+
else
|
224
|
+
return false
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def first
|
229
|
+
f = Hwloc.hwloc_bitmap_first(@ptr)
|
230
|
+
return nil if f == -1
|
231
|
+
return f
|
232
|
+
end
|
233
|
+
|
234
|
+
def last
|
235
|
+
f = Hwloc.hwloc_bitmap_last(@ptr)
|
236
|
+
if f == -1 then
|
237
|
+
if full? then
|
238
|
+
return Float::INFINITY
|
239
|
+
else
|
240
|
+
return nil
|
241
|
+
end
|
242
|
+
end
|
243
|
+
return f
|
244
|
+
end
|
245
|
+
|
246
|
+
def weight
|
247
|
+
w = Hwloc.hwloc_bitmap_weight(@ptr)
|
248
|
+
return Float::INFINITY if w == -1
|
249
|
+
return w
|
250
|
+
end
|
251
|
+
|
252
|
+
alias size weight
|
253
|
+
|
254
|
+
def each
|
255
|
+
if block_given? then
|
256
|
+
indx = -1
|
257
|
+
while (indx = Hwloc.hwloc_bitmap_next(@ptr, indx) ) != -1 do
|
258
|
+
yield indx
|
259
|
+
end
|
260
|
+
return self
|
261
|
+
else
|
262
|
+
return to_enum(:each)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
def &(other)
|
267
|
+
res = Bitmap::new
|
268
|
+
Hwloc.hwloc_bitmap_and(res.ptr, @ptr, other.ptr)
|
269
|
+
return res
|
270
|
+
end
|
271
|
+
|
272
|
+
alias intersection &
|
273
|
+
|
274
|
+
def |(other)
|
275
|
+
res = Bitmap::new
|
276
|
+
Hwloc.hwloc_bitmap_or(res.ptr, @ptr, other.ptr)
|
277
|
+
return res
|
278
|
+
end
|
279
|
+
|
280
|
+
alias + |
|
281
|
+
|
282
|
+
alias union |
|
283
|
+
|
284
|
+
def ^(other)
|
285
|
+
res = Bitmap::new
|
286
|
+
Hwloc.hwloc_bitmap_xor(res.ptr, @ptr, other.ptr)
|
287
|
+
return res
|
288
|
+
end
|
289
|
+
|
290
|
+
def ~
|
291
|
+
res = Bitmap::new
|
292
|
+
Hwloc.hwloc_bitmap_not(res.ptr, @ptr)
|
293
|
+
return res
|
294
|
+
end
|
295
|
+
|
296
|
+
def -(other)
|
297
|
+
res = Bitmap::new
|
298
|
+
Hwloc.hwloc_bitmap_andnot(res.ptr, @ptr, other.ptr)
|
299
|
+
return res
|
300
|
+
end
|
301
|
+
|
302
|
+
def ==(other)
|
303
|
+
return Hwloc.hwloc_bitmap_isequal(@ptr, other.ptr) != 0
|
304
|
+
end
|
305
|
+
|
306
|
+
def include?(other)
|
307
|
+
return Hwloc.hwloc_bitmap_isincluded(other.ptr, @ptr) != 0
|
308
|
+
end
|
309
|
+
|
310
|
+
alias >= include?
|
311
|
+
|
312
|
+
def >(other)
|
313
|
+
return self >= other && !(self == other)
|
314
|
+
end
|
315
|
+
|
316
|
+
def included?(other)
|
317
|
+
return Hwloc.hwloc_bitmap_isincluded(@ptr, other.ptr) != 0
|
318
|
+
end
|
319
|
+
|
320
|
+
alias <= included?
|
321
|
+
|
322
|
+
def <(other)
|
323
|
+
return self <= other && !(self == other)
|
324
|
+
end
|
325
|
+
|
326
|
+
def intersect?(other)
|
327
|
+
return Hwloc.hwloc_bitmap_intersects(@ptr, other.ptr) != 0
|
328
|
+
end
|
329
|
+
|
330
|
+
def disjoint?(other)
|
331
|
+
return Hwloc.hwloc_bitmap_intersects(@ptr, other.ptr) == 0
|
332
|
+
end
|
333
|
+
|
334
|
+
def compare_first(other)
|
335
|
+
return Hwloc.hwloc_bitmap_compare_first(@ptr, other.ptr)
|
336
|
+
end
|
337
|
+
|
338
|
+
def compare(other)
|
339
|
+
return Hwloc.hwloc_bitmap_compare(@ptr, other.ptr)
|
340
|
+
end
|
341
|
+
|
342
|
+
alias <=> compare
|
343
|
+
|
344
|
+
end
|
345
|
+
|
346
|
+
class Cpuset < Bitmap
|
347
|
+
end
|
348
|
+
|
349
|
+
class Nodeset < Bitmap
|
350
|
+
end
|
351
|
+
|
352
|
+
end
|