hwloc 0.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,7 @@
1
+ require_relative 'hwloc/Hwloc.rb'
2
+ require_relative 'hwloc/Bitmap.rb'
3
+ require_relative 'hwloc/Obj.rb'
4
+ require_relative 'hwloc/Topology.rb'
5
+ require_relative 'hwloc/Bind.rb'
6
+ require_relative 'hwloc/Edition.rb'
7
+ require_relative 'hwloc/Export.rb'
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
@@ -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