hwloc 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,68 @@
1
+ module Hwloc
2
+
3
+ attach_function :hwloc_topology_insert_misc_object_by_cpuset, [:topology, :cpuset, :string], Obj.ptr
4
+ attach_function :hwloc_topology_insert_misc_object_by_parent, [:topology, Obj.ptr, :string], Obj.ptr
5
+
6
+ RestrictFlags = enum( FFI::find_type(:ulong), :restrict_flags, [
7
+ :RESTRICT_FLAG_ADAPT_DISTANCES, 1<<0,
8
+ :RESTRICT_FLAG_ADAPT_MISC, 1<<1,
9
+ :RESTRICT_FLAG_ADAPT_IO, 1<<2
10
+ ] )
11
+
12
+ attach_function :hwloc_topology_restrict, [:topology, :cpuset, :ulong], :int
13
+ attach_function :hwloc_custom_insert_topology, [:topology, Obj.ptr, :topology, Obj.ptr,], :int
14
+ attach_function :hwloc_custom_insert_group_object_by_parent, [:topology, Obj.ptr, :int], Obj.ptr
15
+
16
+ class EditionError < TopologyError
17
+ end
18
+
19
+ class Topology
20
+
21
+ def insert_misc_object_by_cpuset(cpuset, name)
22
+ obj = Hwloc.hwloc_topology_insert_misc_object_by_cpuset(@ptr, cpuset, name)
23
+ raise EditionError if obj.to_ptr.null?
24
+ obj.instance_variable_set(:@topology, self)
25
+ return obj
26
+ end
27
+
28
+ def insert_misc_object_by_parent(parent, name)
29
+ obj = Hwloc.hwloc_topology_insert_misc_object_by_parent(@ptr, parent, name)
30
+ raise EditionError if obj.to_ptr.null?
31
+ obj.instance_variable_set(:@topology, self)
32
+ return obj
33
+ end
34
+
35
+ def restrict(cpuset, flags)
36
+ err = Hwloc.hwloc_topology_restrict(@ptr, cpuset, flags)
37
+ raise EditionError if err == -1
38
+ return self
39
+ end
40
+
41
+ def custom_insert_topology(newparent, oldtopology, oldroot = nil)
42
+ err = Hwloc.hwloc_custom_insert_topology(@ptr, newparent, oldtopology.ptr, oldroot)
43
+ raise EditionError if err == -1
44
+ return self
45
+ end
46
+
47
+ def custom_insert_group_object_by_parent(parent, groupdepth)
48
+ obj = Hwloc.hwloc_custom_insert_group_object_by_parent(@ptr, parent, groupdepth)
49
+ raise EditionError if obj.to_ptr.null?
50
+ obj.instance_variable_set(:@topology, self)
51
+ return obj
52
+ end
53
+
54
+ end
55
+
56
+ class Obj
57
+
58
+ def to_topo
59
+ new_topo = Topology::new
60
+ new_topo.set_custom
61
+ new_topo.custom_insert_topology( new_topo.root_obj , @topology, self)
62
+ new_topo.load
63
+ return new_topo
64
+ end
65
+
66
+ end
67
+
68
+ end
@@ -0,0 +1,66 @@
1
+ module Hwloc
2
+
3
+ attach_function :hwloc_topology_export_xml, [:topology, :string], :int
4
+ attach_function :hwloc_topology_export_xmlbuffer, [:topology, :pointer, :pointer], :int
5
+ attach_function :hwloc_free_xmlbuffer, [:topology, :pointer], :void
6
+
7
+ callback :hwloc_topology_set_userdata_export_callback_callback, [:pointer, :topology, Obj.ptr], :void
8
+ attach_function :hwloc_topology_set_userdata_export_callback, [:topology, :hwloc_topology_set_userdata_export_callback_callback], :void
9
+
10
+ attach_function :hwloc_export_obj_userdata, [:pointer, :topology, Obj.ptr, :string, :pointer, :size_t], :int
11
+ attach_function :hwloc_export_obj_userdata_base64, [:pointer, :topology, Obj.ptr, :string, :pointer, :size_t], :int
12
+
13
+ callback :hwloc_topology_set_userdata_import_callback_callback, [:topology, Obj.ptr, :string, :pointer, :size_t], :void
14
+ attach_function :hwloc_topology_set_userdata_import_callback, [:topology, :hwloc_topology_set_userdata_import_callback_callback], :void
15
+
16
+ TopologyExportSyntheticFlags = enum( FFI::find_type(:ulong), :topology_export_synthetic_flags, [
17
+ :TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES, 1<<0,
18
+ :TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS, 1<<1
19
+ ] )
20
+
21
+ attach_function :hwloc_topology_export_synthetic, [:topology, :pointer, :size_t, :uint], :int
22
+
23
+ class ExportError < TopologyError
24
+ end
25
+
26
+ class Topology
27
+
28
+ def export_xml(xmlpath)
29
+ err = Hwloc.hwloc_topology_export_xml(@ptr, xmlpath)
30
+ raise ExportError if err == -1
31
+ return self
32
+ end
33
+
34
+ def export_xmlbuffer
35
+ data_p = FFI::MemoryPointer::new(:pointer)
36
+ count_p = FFI::MemoryPointer::new(:int)
37
+ err = Hwloc.hwloc_topology_export_xmlbuffer(@ptr, data_p, count_p)
38
+ raise ExportError if err == -1
39
+ xmlbuffer_p = data_p.read_pointer.slice(0, count_p.read_int)
40
+ return FFI::AutoPointer::new(xmlbuffer_p, self.method(:free_xmlbuffer))
41
+ end
42
+
43
+ def free_xmlbuffer(pointer)
44
+ Hwloc.hwloc_free_xmlbuffer(@self, pointer)
45
+ end
46
+
47
+ private :free_xmlbuffer
48
+
49
+ def export_synthetic(flags = 0)
50
+ str_ptr = FFI::MemoryPointer::new(:char, 2048)
51
+ err = Hwloc.hwloc_topology_export_synthetic(@ptr, str_ptr, str_ptr.size, flags)
52
+ raise ExportError, "Topology not symetric" if err == -1
53
+ return str_ptr.read_string
54
+ end
55
+
56
+ def to_s
57
+ begin
58
+ return export_synthetic
59
+ rescue ExportError
60
+ return super
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,24 @@
1
+ require 'ffi'
2
+
3
+ module Hwloc
4
+ extend FFI::Library
5
+ ffi_lib 'hwloc'
6
+
7
+ attach_function :hwloc_get_api_version, [], :uint
8
+
9
+ raise RuntimeError, "Wrong hwloc api version (#{Hwloc.hwloc_get_api_version.to_a(16)})!" if Hwloc.hwloc_get_api_version < 0x00010a00
10
+
11
+ attach_function :strerror, [:int], :string
12
+
13
+ def self.error_string
14
+ return Hwloc.strerror(FFI::LastError::error)
15
+ end
16
+
17
+ class Error < RuntimeError
18
+ def initialize(msg = nil)
19
+ msg = Hwloc.error_string unless msg
20
+ super( msg )
21
+ end
22
+ end
23
+
24
+ end
data/lib/hwloc/Obj.rb ADDED
@@ -0,0 +1,432 @@
1
+ module Hwloc
2
+
3
+ class ObjError < Error
4
+ end
5
+
6
+ ObjType = enum( :obj_type, [
7
+ :OBJ_SYSTEM,
8
+ :OBJ_MACHINE,
9
+ :OBJ_NUMANODE,
10
+ :OBJ_PACKAGE,
11
+ :OBJ_CACHE,
12
+ :OBJ_CORE,
13
+ :OBJ_PU,
14
+ :OBJ_GROUP,
15
+ :OBJ_MISC,
16
+ :OBJ_BRIDGE,
17
+ :OBJ_PCI_DEVICE,
18
+ :OBJ_OS_DEVICE,
19
+ :OBJ_TYPE_MAX
20
+ ] )
21
+
22
+ attach_function :hwloc_compare_types, [:obj_type, :obj_type], :int
23
+
24
+ def self.compare_types(type1, type2)
25
+ return Hwloc.hwloc_compare_types(type1, type2)
26
+ end
27
+
28
+ ObjCacheType = enum( :obj_cache_type, [
29
+ :OBJ_CACHE_UNIFIED,
30
+ :OBJ_CACHE_DATA,
31
+ :OBJ_CACHE_INSTRUCTION
32
+ ] )
33
+
34
+ ObjBrigeType = enum( :obj_bridge_type, [
35
+ :OBJ_BRIDGE_HOST,
36
+ :OBJ_BRIDGE_PCI
37
+ ] )
38
+
39
+ ObjOsdevType = enum( :obj_osdev_type, [
40
+ :OBJ_OSDEV_BLOCK,
41
+ :OBJ_OSDEV_GPU,
42
+ :OBJ_OSDEV_NETWORK,
43
+ :OBJ_OSDEV_OPENFABRICS,
44
+ :OBJ_OSDEV_DMA,
45
+ :OBJ_OSDEV_COPROC
46
+ ] )
47
+
48
+ class Struct < FFI::Struct
49
+
50
+ def method_missing(m, *args, &block)
51
+ begin
52
+ return self[m]
53
+ rescue
54
+ super
55
+ end
56
+ end
57
+
58
+ def [](symbol)
59
+ o = super
60
+ o.instance_variable_set(:@topology, @topology) if o.kind_of?(Hwloc::Struct) || o.kind_of?(Hwloc::Union)
61
+ return o
62
+ end
63
+
64
+ attr_reader :topology
65
+
66
+ end
67
+
68
+ class Union < FFI::Union
69
+
70
+ def method_missing(m, *args, &block)
71
+ begin
72
+ return self[m]
73
+ rescue
74
+ super
75
+ end
76
+ end
77
+
78
+ def [](symbol)
79
+ o = super
80
+ o.instance_variable_set(:@topology, @topology) if o.kind_of?(Hwloc::Struct) || o.kind_of?(Hwloc::Union)
81
+ return o
82
+ end
83
+
84
+ attr_reader :topology
85
+
86
+ end
87
+
88
+ class BoolStruct < FFI::Struct
89
+
90
+ def method_missing(m, *args, &block)
91
+ begin
92
+ return self[m] == 1
93
+ rescue
94
+ super
95
+ end
96
+ end
97
+
98
+ def each
99
+ if block_given? then
100
+ members.each { |m|
101
+ yield m, (self[m] ==1)
102
+ }
103
+ else
104
+ to_enum(:each)
105
+ end
106
+ end
107
+
108
+ attr_reader :topology
109
+
110
+ end
111
+
112
+ class Distances < Struct
113
+ layout :relative_depth, :uint,
114
+ :nbobjs, :uint,
115
+ :latency, :pointer,
116
+ :latency_max, :float,
117
+ :latency_base, :float
118
+ end
119
+
120
+ class ObjInfo < Struct
121
+ layout :name, :string,
122
+ :value, :string
123
+
124
+ def to_s
125
+ return "#{self[:name]}:#{self[:value]}"
126
+ end
127
+
128
+ end
129
+
130
+ class ObjMemoryPageType < Struct
131
+ layout :size, :uint64,
132
+ :count, :uint64
133
+ def size
134
+ return self[:size]
135
+ end
136
+ end
137
+
138
+ class ObjMemory < Struct
139
+ layout :total_memory, :uint64,
140
+ :local_memory, :uint64,
141
+ :page_types_len, :uint,
142
+ :page_types, :pointer
143
+ def page_types
144
+ page_types_ptr = self[:page_types]
145
+ return page_types_len.times.collect { |i|
146
+ pt = ObjMemoryPageType::new(page_types_ptr+i*ObjMemoryPageType.size)
147
+ pt.instance_variable_set(:@topology, @topology)
148
+ pt
149
+ }
150
+ end
151
+ end
152
+
153
+ class CacheAttr < Struct
154
+ layout :size, :uint64,
155
+ :depth, :uint,
156
+ :linesize, :uint,
157
+ :associativity, :int,
158
+ :type, :obj_cache_type
159
+ def size
160
+ return self[:size]
161
+ end
162
+ end
163
+
164
+ class GroupAttr < Struct
165
+ layout :depth, :uint
166
+ end
167
+
168
+ class PcidevAttr < Struct
169
+ layout :domain, :ushort,
170
+ :bus, :uchar,
171
+ :dev, :uchar,
172
+ :func, :uchar,
173
+ :class_id, :ushort,
174
+ :vendor_id, :ushort,
175
+ :device_id, :ushort,
176
+ :subvendor_id, :ushort,
177
+ :subdevice_id, :ushort,
178
+ :revision, :uchar,
179
+ :linkspeed, :float
180
+ end
181
+
182
+ class AnonBridgeAttrUpstream < Union
183
+ layout :pci, PcidevAttr
184
+ end
185
+
186
+ class AnonBridgeAttrDownstreamStruct < Struct
187
+ layout :domain, :ushort,
188
+ :secondary_bus, :uchar,
189
+ :subordinate_bus, :uchar
190
+ end
191
+
192
+ class AnonBridgeAttrDownstream < Union
193
+ layout :pci, AnonBridgeAttrDownstreamStruct
194
+ end
195
+
196
+ class BridgeAttr < Struct
197
+ layout :upstream, AnonBridgeAttrUpstream,
198
+ :upstream_type, :obj_bridge_type,
199
+ :downstream, AnonBridgeAttrDownstream,
200
+ :downstream_type, :obj_bridge_type,
201
+ :depth, :uint
202
+ end
203
+
204
+ class OsdevAttr < Struct
205
+ layout :type, :obj_osdev_type
206
+ end
207
+
208
+ class ObjAttr < Union
209
+ layout :cache, CacheAttr,
210
+ :group, GroupAttr,
211
+ :pcidev, PcidevAttr,
212
+ :bridge, BridgeAttr,
213
+ :osdev, OsdevAttr
214
+ end
215
+
216
+ class Obj < Struct
217
+ end
218
+
219
+ attach_function :hwloc_obj_type_snprintf, [:pointer, :size_t, Obj.ptr, :int], :int
220
+ attach_function :hwloc_obj_attr_snprintf, [:pointer, :size_t, Obj.ptr, :string, :int], :int
221
+
222
+ class Obj
223
+ layout_array = [
224
+ :type, :obj_type,
225
+ :os_index, :uint,
226
+ :name, :string,
227
+ :memory, ObjMemory,
228
+ :attr, ObjAttr.ptr,
229
+ :depth, :uint,
230
+ :logical_index, :uint,
231
+ :os_level, :int,
232
+ :next_cousin, Obj.ptr,
233
+ :prev_cousin, Obj.ptr,
234
+ :parent, Obj.ptr,
235
+ :sibling_rank, :uint,
236
+ :next_sibling, Obj.ptr,
237
+ :prev_sibling, Obj.ptr,
238
+ :arity, :uint,
239
+ :children, :pointer,
240
+ :first_child, Obj.ptr,
241
+ :last_child, Obj.ptr,
242
+ :user_data, :pointer,
243
+ :cpuset, :cpuset,
244
+ :complete_cpuset, :cpuset,
245
+ :online_cpuset, :cpuset,
246
+ :allowed_cpuset, :cpuset,
247
+ :nodeset, :nodeset,
248
+ :complete_nodeset, :nodeset,
249
+ :allowed_nodeset, :nodeset,
250
+ :distances, :pointer,
251
+ :distances_count, :uint,
252
+ :infos, :pointer,
253
+ :infos_count, :uint,
254
+ :symmetric_subtree,:int
255
+ ]
256
+
257
+ layout *layout_array
258
+
259
+ def ==(other)
260
+ return other.kind_of?(Obj) && to_ptr == other.to_ptr
261
+ end
262
+
263
+ def type_snprintf(verbose=0)
264
+ sz = Hwloc.hwloc_obj_type_snprintf(nil, 0, self, verbose) + 1
265
+ str_ptr = FFI::MemoryPointer::new(:char, sz)
266
+ Hwloc.hwloc_obj_type_snprintf(str_ptr, sz, self, verbose)
267
+ return str_ptr.read_string
268
+ end
269
+
270
+ alias type_name type_snprintf
271
+
272
+ def attr_snprintf(verbose=0, separator=",")
273
+ sz = Hwloc.hwloc_obj_attr_snprintf(nil, 0, self, separator, verbose) + 1
274
+ str_ptr = FFI::MemoryPointer::new(:char, sz)
275
+ Hwloc.hwloc_obj_attr_snprintf(str_ptr, sz, self, separator, verbose)
276
+ return str_ptr.read_string
277
+ end
278
+
279
+ def to_s(verbose=0)
280
+ attr_str = attr_snprintf(verbose)
281
+ str = "#{type_snprintf(verbose)} L##{logical_index}"
282
+ str += " (#{attr_str})" if attr_str != ""
283
+ return str
284
+ end
285
+
286
+ def inspect
287
+ return to_s(1)
288
+ end
289
+
290
+ layout_array.each_slice(2) { |f|
291
+ case f[1]
292
+ when :cpuset
293
+ define_method(f[0]) {
294
+ p = self[f[0]]
295
+ return nil if p.null?
296
+ return Cpuset::new(p)
297
+ }
298
+ when :nodeset
299
+ define_method(f[0]) {
300
+ p = self[f[0]]
301
+ return nil if p.null?
302
+ return Nodeset::new(p)
303
+ }
304
+ when Obj.ptr
305
+ define_method(f[0]) {
306
+ p = self[f[0]]
307
+ return nil if p.to_ptr.null?
308
+ return p
309
+ }
310
+ end
311
+ }
312
+
313
+ alias previous_sibling prev_sibling
314
+ alias previous_cousin prev_cousin
315
+
316
+ def children
317
+ arity = self[:arity]
318
+ if arity == 0 then
319
+ return []
320
+ else
321
+ return self[:children].read_array_of_pointer(arity).collect { |p|
322
+ c = Obj::new(p)
323
+ c.instance_variable_set(:@topology, @topology)
324
+ c
325
+ }
326
+ end
327
+ end
328
+
329
+ def each_child(*args, &block)
330
+ return children.each(*args, &block)
331
+ end
332
+
333
+ def each_parent(&block)
334
+ if block then
335
+ if parent then
336
+ block.call parent
337
+ parent.each_parent(&block)
338
+ end
339
+ return self
340
+ else
341
+ to_enum(:each_parent)
342
+ end
343
+ end
344
+
345
+ def parents
346
+ return each_parent.to_a
347
+ end
348
+
349
+ alias ancestors parents
350
+ alias each_ancestor each_parent
351
+
352
+ def each_obj(&block)
353
+ if block then
354
+ block.call self
355
+ children.each { |c|
356
+ c.each_obj(&block)
357
+ }
358
+ return self
359
+ else
360
+ to_enum(:each_obj)
361
+ end
362
+ end
363
+
364
+ alias traverse each_obj
365
+
366
+ def each_descendant
367
+ if block then
368
+ children.each { |c|
369
+ c.each_obj(&block)
370
+ }
371
+ else
372
+ to_enum(:each_descendant)
373
+ end
374
+ end
375
+
376
+ def descendants
377
+ return each_descendant.to_a
378
+ end
379
+
380
+ def distances
381
+ distances_count = self[:distances_count]
382
+ if distances_count == 0 then
383
+ return []
384
+ else
385
+ return self[:distances].read_array_of_pointer(distances_count).collect { |p|
386
+ d = Distances::new(p)
387
+ d.instance_variable_set(:@topology, @topology)
388
+ d
389
+ }
390
+ end
391
+ end
392
+
393
+ def infos
394
+ infos_count = self[:infos_count]
395
+ if infos_count == 0 then
396
+ return []
397
+ else
398
+ inf_array = infos_count.times.collect { |i|
399
+ o = ObjInfo::new(self[:infos] + i*ObjInfo.size)
400
+ }
401
+ inf_h = {}
402
+ inf_array.each { |e| inf_h[e[:name].to_sym] = e[:value] }
403
+ return inf_h
404
+ end
405
+ end
406
+
407
+ def each_info(*args, &block)
408
+ return infos.each(*args, &block)
409
+ end
410
+
411
+ def attr
412
+ at = self[:attr]
413
+ return nil if at.to_ptr.null?
414
+ t = self[:type]
415
+ case t
416
+ when :OBJ_CACHE
417
+ return at[:cache]
418
+ when :OBJ_GROUP
419
+ return at[:group]
420
+ when :OBJ_PCI_DEVICE
421
+ return at[:pcidev]
422
+ when :OBJ_BRIDGE
423
+ return at[:bridge]
424
+ when :OBJ_OS_DEVICE
425
+ return at[:osdev]
426
+ end
427
+ return nil
428
+ end
429
+
430
+ end
431
+
432
+ end