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.
@@ -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