hwloc 0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|