PAPI 0.100

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0f46591e6beaf71b1b303a90c2fd08a6f4ce8aa3
4
+ data.tar.gz: 7479c89a0aefed2e55a85da912294e5b9fea5e1c
5
+ SHA512:
6
+ metadata.gz: f0a38ba8caa53bd5f57e219b09782cebef482972ec8304e4e9ed026bf6928aa5997cdccb448b4fca18fe20e5e17cd65adbf6df7ec4babfe9b8af7aa5274c682e
7
+ data.tar.gz: b2e5c9a9ac7ff1e8fe79e359ebdec68a432cd21c63e8afebafa5b5b4b1d06bb025dde85d1e1636438b7422db2aa3a220a58e2dce8402b49db91ce61c287b516e
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014, 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.
@@ -0,0 +1,14 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'PAPI'
3
+ s.version = "0.100"
4
+ s.author = "Brice Videau"
5
+ s.email = "brice.videau@imag.fr"
6
+ s.homepage = "https://github.com/Nanosim-LIG/papi-ruby"
7
+ s.summary = "Ruby PAPI bindings"
8
+ s.description = "Ruby PAPI bindings."
9
+ s.files = %w( PAPI.gemspec LICENSE lib/PAPI.rb lib/PAPI/ lib/PAPI/Version.rb lib/PAPI/Error.rb lib/PAPI/Event.rb lib/PAPI/Component.rb lib/PAPI/EventSet.rb )
10
+ s.has_rdoc = true
11
+ s.license = 'BSD'
12
+ s.required_ruby_version = '>= 1.9.3'
13
+ s.add_dependency 'ffi', '>=1.9.3'
14
+ end
@@ -0,0 +1,5 @@
1
+ require 'PAPI/Version.rb'
2
+ require 'PAPI/Error.rb'
3
+ require 'PAPI/Event.rb'
4
+ require 'PAPI/Component.rb'
5
+ require 'PAPI/EventSet.rb'
@@ -0,0 +1,155 @@
1
+ module PAPI
2
+
3
+ if VERSION >= Version::new(4,0,0,0) then
4
+ attach_function :PAPI_num_components, [], :int
5
+ attach_function :PAPI_get_component_info, [:int], :pointer
6
+ attach_function :PAPI_enum_cmp_event, [:pointer, EventModifier, :int], :int
7
+ else
8
+ attach_function :PAPI_get_substrate_info, [], :pointer
9
+ end
10
+
11
+ COMPONENTS = []
12
+ COMPONENTS_HASH = {}
13
+
14
+ class Component
15
+ class Info < FFI::Struct
16
+ lay = []
17
+ lay.push(:name, [:char, MAX_STR_LEN])
18
+ lay.push(:short_name, [:char, MIN_STR_LEN],
19
+ :description, [:char, MAX_STR_LEN]) if VERSION >= Version::new(5,0,0,0)
20
+ lay.push(:version, [:char, MIN_STR_LEN],
21
+ :support_version, [:char, MIN_STR_LEN],
22
+ :kernel_version, [:char, MIN_STR_LEN])
23
+ lay.push(:disabled_reason, [:char, MAX_STR_LEN],
24
+ :disabled, :int) if VERSION >= Version::new(5,0,0,0)
25
+ lay.push(:CmpIdx, :int) if VERSION >= Version::new(4,0,0,0)
26
+ lay.push(:num_cntrs, :int,
27
+ :num_mpx_cntrs, :int,
28
+ :num_preset_events, :int,
29
+ :num_native_events, :int,
30
+ :default_domain, :int,
31
+ :available_domains, :int,
32
+ :default_granularity, :int,
33
+ :available_granularities, :int)
34
+ lay.push(:itimer_sig, :int,
35
+ :itimer_num, :int,
36
+ :itimer_ns, :int,
37
+ :itimer_res_ns, :int) if VERSION < Version::new(5,0,0,0)
38
+ lay.push(:hardware_intr_sig, :int)
39
+ lay.push(:clock_ticks, :int,
40
+ :opcode_match_width, :int) if VERSION < Version::new(5,0,0,0)
41
+ lay.push(:component_type, :int) if VERSION >= Version::new(5,0,0,0)
42
+ lay.push(:pmu_names, [:pointer, PMU_MAX]) if VERSION >= Version::new(5,4,1,0)
43
+ lay.push(:reserved, [:int, 8]) if VERSION >= Version::new(5,0,0,0)
44
+ lay.push(:os_version, :int,
45
+ :reserved, [:int, 1]) if VERSION < Version::new(5,0,0,0) and VERSION >= Version::new(4,1,1,0)
46
+ lay.push(:reserved, [:int, 2]) if VERSION < Version::new(4,1,1,0)
47
+ lay.push(:bifield, :uint)
48
+
49
+ layout( *lay )
50
+ end
51
+
52
+ attr_reader :info
53
+ attr_accessor :native
54
+ attr_accessor :preset
55
+
56
+ def initialize(info, idx = 0)
57
+ @info = info
58
+ @idx = idx
59
+ end
60
+
61
+ def to_i
62
+ return @idx
63
+ end
64
+
65
+ def to_s
66
+ @info[:name].to_ptr.read_string
67
+ end
68
+
69
+ end
70
+
71
+ def self.get_mask_info( code, component )
72
+ m_p = FFI::MemoryPointer::new(:uint)
73
+ m_p.write_uint( code.read_uint )
74
+ if VERSION < Version::new(4,0,0,0) then
75
+ e = PAPI_enum_event( m_p, :ntv_enum_umasks )
76
+ else
77
+ e = PAPI_enum_cmp_event( m_p, :ntv_enum_umasks, component.to_i )
78
+ end
79
+ return nil if e != OK
80
+ info = Event::Info::new
81
+ e = PAPI_get_event_info( m_p.read_int, info )
82
+ if e == OK then
83
+ ev = Event::new(info)
84
+ masks = []
85
+ masks.push(ev)
86
+ end
87
+ while ( VERSION < Version::new(4,0,0,0) ? PAPI_enum_event(e_p, :ntv_enum_umasks) : PAPI_enum_cmp_event( m_p, :ntv_enum_umasks, component.to_i ) ) == OK do
88
+ info = Event::Info::new
89
+ e = PAPI_get_event_info( m_p.read_int, info )
90
+ next if e != OK
91
+ ev = Event::new(info)
92
+ masks = [] if not masks
93
+ masks.push(ev)
94
+ end
95
+ return masks
96
+ end
97
+
98
+ def self.get_native_events( component )
99
+ e_p = FFI::MemoryPointer::new(:uint)
100
+ e_p.write_uint(0 | Event::NATIVE_MASK)
101
+ if VERSION < Version::new(4,0,0,0) then
102
+ e = PAPI_enum_event(e_p, :enum_first)
103
+ else
104
+ e = PAPI_enum_cmp_event(e_p, :enum_first, component.to_i)
105
+ end
106
+ return if e != OK
107
+ info = Event::Info::new
108
+ e = PAPI_get_event_info( e_p.read_int, info )
109
+ if e == OK then
110
+ ev = Event::new(info, get_mask_info( e_p, component ))
111
+ component.native = []
112
+ component.native.push(ev)
113
+ end
114
+ while ( VERSION < Version::new(4,0,0,0) ? PAPI_enum_event(e_p, :enum_events) : PAPI_enum_cmp_event(e_p, :enum_events, component.to_i) ) == OK do
115
+ info = Event::Info::new
116
+ e = PAPI_get_event_info( e_p.read_int, info )
117
+ next if e != OK
118
+ ev = Event::new(info, get_mask_info( e_p, component ) )
119
+ component.native = [] if not component.native
120
+ component.native.push(ev)
121
+ end
122
+
123
+ #puts "#{component}: #{component.to_i}"
124
+ #puts component.native.length
125
+ #component.native.each { |evt| puts evt.to_s(true, true) }
126
+ end
127
+
128
+ def self.get_components_info
129
+ if VERSION < Version::new(4,0,0,0) then
130
+ info_p = PAPI_get_substrate_info()
131
+ COMPONENTS.push( Component::new(Component::Info::new(info_p)))
132
+ COMPONENTS_HASH[0] = COMPONENTS[0]
133
+ else
134
+ (0...PAPI_num_components()).each { |cid|
135
+ info_p = PAPI_get_component_info(cid)
136
+ info = Component::Info::new(info_p)
137
+ if VERSION >= Version::new(5,0,0,0) and info[:disabled] != 0 then
138
+ #puts "#{info[:name].to_ptr.read_string}: #{info[:disabled_reason].to_ptr.read_string}"
139
+ else
140
+ COMPONENTS.push( Component::new(info, cid) )
141
+ COMPONENTS_HASH[cid] = COMPONENTS.last
142
+ end
143
+ }
144
+ end
145
+ if COMPONENTS.length > 0 then
146
+ COMPONENTS[0].preset = PRESET_EVENTS
147
+ end
148
+ COMPONENTS.each { |c|
149
+ get_native_events( c )
150
+ }
151
+ end
152
+
153
+ get_components_info
154
+
155
+ end
@@ -0,0 +1,115 @@
1
+ module PAPI
2
+
3
+ class Error < StandardError
4
+ attr_reader :code
5
+
6
+ def initialize(code)
7
+ @code = code
8
+ super("#{code}")
9
+ end
10
+
11
+ #:stopdoc:
12
+ CLASSES = {}
13
+ #:startdoc:
14
+
15
+ private_constant :CLASSES
16
+
17
+ def self.error_class(errcode)
18
+ return CLASSES[errcode]
19
+ end
20
+
21
+ def self.name(code)
22
+ if CLASSES[code] then
23
+ return CLASSES[code].name
24
+ else
25
+ return "#{code}"
26
+ end
27
+ end
28
+
29
+ def name
30
+ return "#{@code}"
31
+ end
32
+
33
+ def self.register_error(code, symbol)
34
+ s = <<EOF
35
+ class #{symbol} < Error
36
+
37
+ def initialize
38
+ super(#{code})
39
+ end
40
+
41
+ def self.name
42
+ return "#{symbol}"
43
+ end
44
+
45
+ def name
46
+ return "#{symbol}"
47
+ end
48
+
49
+ def self.code
50
+ return #{code}
51
+ end
52
+
53
+ end
54
+ CLASSES[#{code}] = #{symbol}
55
+ EOF
56
+ end
57
+ errors = []
58
+ errors.push([-1, "EINVAL"],
59
+ [-2, "ENOMEM"],
60
+ [-3, "ESYS"])
61
+ if VERSION >= Version::new(5,0,0,0) then
62
+ errors.push [-4, "ECMP"]
63
+ else
64
+ errors.push [-4, "ESBSTR"]
65
+ end
66
+ errors.push([-5, "ECLOST"],
67
+ [-6, "EBUG"],
68
+ [-7, "ENOEVNT"],
69
+ [-8, "ECNFLCT"],
70
+ [-9, "ENOTRUN"],
71
+ [-10, "EISRUN"],
72
+ [-11, "ENOEVST"],
73
+ [-12, "ENOTPRESET"],
74
+ [-13, "ENOCNTR"],
75
+ [-14, "EMISC"],
76
+ [-15, "EPERM"],
77
+ [-16, "ENOINIT"])
78
+ if VERSION >= Version::new(4,2,0,0) then
79
+ errors.push([-17, "ENOCMP"],
80
+ [-18, "ENOSUPP"],
81
+ [-19, "ENOIMPL"],
82
+ [-20, "EBUF"],
83
+ [-21, "EINVAL_DOM"],
84
+ [-22, "EATTR"],
85
+ [-23, "ECOUNT"],
86
+ [-24, "ECOMBO"])
87
+ elsif VERSION >= Version::new(4,1,0,0) then
88
+ errors.push([-17, "ENOCMP"],
89
+ [-18, "ENOSUPP"],
90
+ [-19, "ENOIMPL"],
91
+ [-20, "EBUF"],
92
+ [-21, "EINVAL_DOM"])
93
+ elsif VERSION >= Version::new(4,0,0,0) then
94
+ errors.push([-17, "EBUF"],
95
+ [-18, "EINVAL_DOM"],
96
+ [-19, "ENOCMP"])
97
+ else
98
+ errors.push([-17, "EBUF"],
99
+ [-18, "EINVAL_DOM"])
100
+ end
101
+ errors.each { |code, symbol| eval register_error(code, symbol) }
102
+
103
+ end
104
+
105
+ def self.error_check(errcode)
106
+ return nil if errcode >= OK
107
+ klass = Error::error_class(errcode)
108
+ if klass then
109
+ raise klass::new
110
+ else
111
+ raise Error::new("#{errcode}")
112
+ end
113
+ end
114
+
115
+ end
@@ -0,0 +1,147 @@
1
+ module PAPI
2
+
3
+ MIN_STR_LEN = 64
4
+ MAX_STR_LEN = 128
5
+ MAX_STR_LEN2 = 256
6
+ HUGE_STR_LEN = 1024
7
+ MAX_INFO_TERMS = 12
8
+ PMU_MAX = 40
9
+
10
+ OK = 0
11
+
12
+ PAPI_NULL = -1
13
+
14
+ class Event
15
+ class Mask < Event
16
+ def initialize(info)
17
+ super(info,nil)
18
+ end
19
+ end
20
+
21
+ PRESET_MASK = 0x80000000
22
+ NATIVE_MASK = 0x40000000
23
+ PRESET_AND_MASK = 0x7FFFFFFF
24
+ NATIVE_AND_MASK = 0xBFFFFFFF
25
+
26
+ MAX_PRESET_EVENTS = 128
27
+
28
+ attr_reader :info
29
+ attr_reader :masks
30
+
31
+ def initialize(info, masks = nil)
32
+ @info = info
33
+ @masks = masks
34
+ end
35
+
36
+ def to_i
37
+ @info[:event_code]
38
+ end
39
+
40
+ def to_s(description = false, masks = false)
41
+ s1 = @info[:symbol].to_ptr.read_string
42
+ s = "#{s1}"
43
+ s += "\n #{@info[:long_descr]}" if description
44
+ if masks and @masks then
45
+ s += "\n "
46
+ s += @masks.collect{ |m| m.to_s.gsub(s1.gsub(/.*::/,""),"")+"\n " + m.info[:long_descr].to_ptr.read_string.gsub(/.*masks:/,"") }.join("\n ")
47
+ end
48
+ return s
49
+ end
50
+
51
+ class Info < FFI::Struct
52
+ if VERSION >= Version::new(5,0,0,0) then
53
+ layout :event_code, :int,
54
+ :symbol, [:char, HUGE_STR_LEN],
55
+ :short_descr, [:char, MIN_STR_LEN],
56
+ :long_descr, [:char, HUGE_STR_LEN],
57
+ :component_index, :int,
58
+ :units, [:char, MIN_STR_LEN],
59
+ :location, :int,
60
+ :data_type, :int,
61
+ :value_type, :int,
62
+ :timescope, :int,
63
+ :update_type, :int,
64
+ :update_freq, :int,
65
+ :count, :uint,
66
+ :event_type, :uint,
67
+ :derived, [:char, MIN_STR_LEN],
68
+ :postfix, [:char, MAX_STR_LEN2],
69
+ :code, [:int, MAX_INFO_TERMS],
70
+ :name, [:char, MAX_INFO_TERMS*MAX_STR_LEN2],
71
+ :note, [:char, HUGE_STR_LEN]
72
+ else
73
+ layout :event_code, :uint,
74
+ :event_type, :uint,
75
+ :count, :uint,
76
+ :symbol, [:char, HUGE_STR_LEN],
77
+ :short_descr, [:char, MIN_STR_LEN],
78
+ :long_descr, [:char, HUGE_STR_LEN],
79
+ :derived, [:char, MIN_STR_LEN],
80
+ :postfix, [:char, MIN_STR_LEN],
81
+ :code, [:int, MAX_INFO_TERMS],
82
+ :name, [:char, MAX_INFO_TERMS*MAX_STR_LEN2],
83
+ :note, [:char, HUGE_STR_LEN]
84
+ end
85
+ end
86
+ end
87
+
88
+ typedef :pointer, :papi_event_info_t
89
+
90
+ EventModifier = enum( :enum_events,
91
+ :enum_first,
92
+ :preset_enum_avail,
93
+ :preset_enum_msc,
94
+ :preset_enum_ins,
95
+ :preset_enum_idl,
96
+ :preset_enum_br,
97
+ :preset_enum_cnd,
98
+ :preset_enum_mem,
99
+ :preset_enum_cach,
100
+ :preset_enum_l1,
101
+ :preset_enum_l2,
102
+ :preset_enum_l3,
103
+ :preset_enum_tlb,
104
+ :preset_enum_fp,
105
+ :ntv_enum_umasks,
106
+ :ntv_enum_umasks_combos,
107
+ :ntv_enum_iarr,
108
+ :ntv_enum_darr,
109
+ :ntv_enum_opcm,
110
+ :ntv_enum_iear,
111
+ :ntv_enum_dear,
112
+ :ntv_enum_groups )
113
+
114
+ attach_function :PAPI_enum_event, [:pointer, EventModifier], :int
115
+ attach_function :PAPI_get_event_info, [:int, :papi_event_info_t], :int
116
+
117
+ PRESET_EVENTS = []
118
+ PRESET_EVENTS_HASH = {}
119
+
120
+ def self.get_events_info
121
+ e_p = FFI::MemoryPointer::new(:uint)
122
+ e_p.write_uint(0 | Event::PRESET_MASK)
123
+ PAPI_enum_event(e_p, :enum_first)
124
+ info = Event::Info::new
125
+ e = PAPI_get_event_info( e_p.read_int, info )
126
+ ev = Event::new(info)
127
+ PRESET_EVENTS.push(ev)
128
+ PRESET_EVENTS_HASH[ev.to_i] = ev
129
+ while PAPI_enum_event(e_p, :preset_enum_avail) == OK do
130
+ info = Event::Info::new
131
+ e = PAPI_get_event_info( e_p.read_int, info )
132
+ ev = Event::new(info)
133
+ PRESET_EVENTS.push(ev)
134
+ PRESET_EVENTS_HASH[ev.to_i] = ev
135
+ end
136
+ end
137
+
138
+ get_events_info
139
+
140
+ PRESET_EVENTS.each_index { |i|
141
+ s = <<EOF
142
+ #{PRESET_EVENTS[i].to_s.gsub("PAPI_","")} = PRESET_EVENTS[#{i}]
143
+ EOF
144
+ eval s
145
+ }
146
+
147
+ end
@@ -0,0 +1,195 @@
1
+ module PAPI
2
+
3
+ typedef :int, :event_set
4
+ attach_function :PAPI_create_eventset, [:pointer], :int
5
+ attach_function :PAPI_add_event, [:event_set, :int], :int
6
+ attach_function :PAPI_add_named_event, [:event_set, :string], :int
7
+ attach_function :PAPI_remove_event, [:event_set, :int], :int
8
+ attach_function :PAPI_remove_named_event, [:event_set, :string], :int
9
+ attach_function :PAPI_num_events, [:event_set], :int
10
+ attach_function :PAPI_list_events, [:event_set, :pointer, :pointer], :int
11
+ attach_function :PAPI_start, [:event_set], :int
12
+ attach_function :PAPI_stop, [:event_set, :pointer], :int
13
+ attach_function :PAPI_accum, [:event_set, :pointer], :int
14
+ attach_function :PAPI_read, [:event_set, :pointer], :int
15
+ attach_function :PAPI_read_ts, [:event_set, :pointer, :pointer], :int
16
+ attach_function :PAPI_assign_eventset_component, [:event_set, :int], :int
17
+ attach_function :PAPI_get_eventset_component, [:event_set], :int
18
+
19
+ class EventSet
20
+
21
+ def initialize
22
+ number = FFI::MemoryPointer::new(:int)
23
+ number.write_int(PAPI_NULL)
24
+ error = PAPI::PAPI_create_eventset( number )
25
+ @number = number.read_int
26
+ PAPI::error_check(error)
27
+ @size = 0
28
+ end
29
+
30
+ def assign_component(component)
31
+ error = PAPI::PAPI_assign_eventset_component( @number, component.to_i )
32
+ PAPI::error_check(error)
33
+ return self
34
+ end
35
+
36
+ def add( events )
37
+ evts = [events].flatten
38
+ evts.each { |ev|
39
+ error = PAPI::PAPI_add_event(@number, ev.to_i)
40
+ PAPI::error_check(error)
41
+ }
42
+ error = PAPI::PAPI_num_events(@number)
43
+ PAPI::error_check(error)
44
+ @size = error
45
+ return self
46
+ end
47
+
48
+ def add_named(events)
49
+ evts = [events].flatten
50
+ evts.each { |ev|
51
+ error = PAPI::PAPI_add_named_event(@number, ev.to_s)
52
+ PAPI::error_check(error)
53
+ }
54
+ error = PAPI::PAPI_num_events(@number)
55
+ PAPI::error_check(error)
56
+ @size = error
57
+ return self
58
+ end
59
+
60
+ def remove( events )
61
+ evts = [events].flatten
62
+ evts.each { |ev|
63
+ error = PAPI::PAPI_remove_event(@number, ev.to_i)
64
+ PAPI::error_check(error)
65
+ }
66
+ error = PAPI::PAPI_num_events(@number)
67
+ PAPI::error_check(error)
68
+ @size = error
69
+ return self
70
+ end
71
+
72
+ def remove_named( events )
73
+ evts = [events].flatten
74
+ evts.each { |ev|
75
+ error = PAPI::PAPI_remove_named_event(@number, ev.to_s)
76
+ PAPI::error_check(error)
77
+ }
78
+ error = PAPI::PAPI_num_events(@number)
79
+ PAPI::error_check(error)
80
+ @size = error
81
+ return self
82
+ end
83
+
84
+ def possible(preset = true)
85
+ cid = nil
86
+ begin
87
+ e = PAPI::PAPI_get_eventset_component(@number)
88
+ PAPI::error_check(e)
89
+ cid = e
90
+ rescue
91
+ cid = 0
92
+ end
93
+ list = []
94
+ if preset and COMPONENTS[cid].preset then
95
+ events = COMPONENTS[cid].preset
96
+ else
97
+ events = COMPONENTS[cid].native
98
+ end
99
+ events.each { |event|
100
+ error = PAPI::PAPI_add_event(@number, event.to_i)
101
+ if( error >= OK ) then
102
+ error = PAPI::PAPI_remove_event(@number, event.to_i)
103
+ PAPI::error_check(error)
104
+ list.push event
105
+ elsif event.masks then
106
+ event.masks.each { |mask|
107
+ error = PAPI::PAPI_add_named_event(@number, mask.info[:symbol])
108
+ if( error >= OK ) then
109
+ error = PAPI::PAPI_remove_named_event(@number, mask.info[:symbol])
110
+ PAPI::error_check(error)
111
+ list.push event
112
+ break
113
+ end
114
+ }
115
+ event.masks.each { |mask|
116
+ error = PAPI::PAPI_add_named_event(@number, mask.info[:symbol].to_ptr.read_string+":cpu=1")
117
+ if( error >= OK ) then
118
+ error = PAPI::PAPI_remove_named_event(@number, mask.info[:symbol].to_ptr.read_string+":cpu=1")
119
+ PAPI::error_check(error)
120
+ list.push event
121
+ break
122
+ end
123
+ }
124
+ else
125
+ error = PAPI::PAPI_add_named_event(@number, (event.info[:symbol].to_ptr.read_string+":cpu=1").gsub(/.*::/,""))
126
+ if( error >= OK ) then
127
+ error = PAPI::PAPI_remove_named_event(@number, (event.info[:symbol].to_ptr.read_string+":cpu=1").gsub(/.*::/,""))
128
+ PAPI::error_check(error)
129
+ list.push event
130
+ end
131
+ end
132
+ }
133
+ return list
134
+ end
135
+
136
+ def size
137
+ return @size
138
+ end
139
+
140
+ alias length size
141
+ alias num_events size
142
+
143
+ def events
144
+ events_p = FFI::MemoryPointer::new(:int, @size)
145
+ size_p = FFI::MemoryPointer::new(:int)
146
+ size_p.write_int(@size)
147
+ error = PAPI::PAPI_list_events(@number, events_p, size_p)
148
+ PAPI::error_check(error)
149
+ evts = events_p.read_array_of_int(size_p.read_int)
150
+ return evts.collect { |code| PRESET_EVENTS_HASH[code] }
151
+ end
152
+
153
+ alias list_events events
154
+
155
+ def start
156
+ error = PAPI::PAPI_start(@number)
157
+ PAPI::error_check(error)
158
+ return self
159
+ end
160
+
161
+ def stop
162
+ values_p = FFI::MemoryPointer::new(:long_long, @size)
163
+ error = PAPI::PAPI_stop(@number, values_p)
164
+ PAPI::error_check(error)
165
+ return values_p.read_array_of_long_long(@size)
166
+ end
167
+
168
+ def accum(values)
169
+ values_p = FFI::MemoryPointer::new(:long_long, @size)
170
+ values_p.write_array_of_long_long(values)
171
+ error = PAPI::PAPI_accum(@number, values_p)
172
+ PAPI::error_check(error)
173
+ new_values = values_p.read_array_of_long_long(@size)
174
+ values.replace(new_values)
175
+ return self
176
+ end
177
+
178
+ def read
179
+ values_p = FFI::MemoryPointer::new(:long_long, @size)
180
+ error = PAPI::PAPI_read(@number, values_p)
181
+ PAPI::error_check(error)
182
+ return values_p.read_array_of_long_long(@size)
183
+ end
184
+
185
+ def read_ts
186
+ values_p = FFI::MemoryPointer::new(:long_long, @size)
187
+ ts_p = FFI::MemoryPointer::new(:long_long)
188
+ error = PAPI::PAPI_read_ts(@number, values_p, ts_p)
189
+ PAPI::error_check(error)
190
+ return [values_p.read_array_of_long_long(@size), ts_p.read_long_long]
191
+ end
192
+
193
+ end
194
+
195
+ end
@@ -0,0 +1,93 @@
1
+ require 'ffi'
2
+
3
+ module PAPI
4
+
5
+ extend FFI::Library
6
+
7
+ ffi_lib "libpapi.so"
8
+ attach_function :PAPI_library_init, [ :int ], :int
9
+ attach_function :PAPI_shutdown, [ ], :void
10
+
11
+ class Version
12
+ include Comparable
13
+
14
+ def initialize( *vals )
15
+ if( vals.length > 1 )
16
+ @number = 0
17
+ 4.times {
18
+ v = vals.shift
19
+ v = 0 unless v
20
+ @number <<= 8
21
+ @number += v & 0xff
22
+ }
23
+ else
24
+ @number = vals[0]
25
+ end
26
+ end
27
+
28
+ def major
29
+ return ( @number >> 24 ) & 0xff
30
+ end
31
+
32
+ def minor
33
+ return ( @number >> 16 ) & 0xff
34
+ end
35
+
36
+ def revision
37
+ return ( @number >> 8 ) & 0xff
38
+ end
39
+
40
+ def increment
41
+ return @number & 0xff
42
+ end
43
+
44
+ def to_int
45
+ return @number
46
+ end
47
+
48
+ def to_s
49
+ return "#{major}.#{minor}.#{revision}.#{increment}"
50
+ end
51
+
52
+ def <=>(v)
53
+ return self.to_int <=> v.to_int
54
+ end
55
+ end
56
+
57
+ def self.init
58
+ 5.downto(3) { |major|
59
+ 9.downto(0) { |minor|
60
+ 9.downto(0) { |revision|
61
+ 9.downto(0) { |increment|
62
+ v = Version::new(major, minor, revision, increment)
63
+ res = PAPI_library_init(v)
64
+ if res == v.to_int then
65
+ return Version::new(res)
66
+ end
67
+ }
68
+ }
69
+ }
70
+ }
71
+ return nil
72
+ end
73
+
74
+ def self.init
75
+ 5.downto(3) { |major|
76
+ 9.downto(0) { |minor|
77
+ 9.downto(0) { |revision|
78
+ 9.downto(0) { |increment|
79
+ v = Version::new(major, minor, revision, increment)
80
+ res = PAPI_library_init(v)
81
+ if res == v.to_int then
82
+ return Version::new(res)
83
+ end
84
+ }
85
+ }
86
+ }
87
+ }
88
+ return nil
89
+ end
90
+
91
+ VERSION = self.init()
92
+
93
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: PAPI
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.100'
5
+ platform: ruby
6
+ authors:
7
+ - Brice Videau
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.9.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.9.3
27
+ description: Ruby PAPI bindings.
28
+ email: brice.videau@imag.fr
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - LICENSE
34
+ - PAPI.gemspec
35
+ - lib/PAPI.rb
36
+ - lib/PAPI/Component.rb
37
+ - lib/PAPI/Error.rb
38
+ - lib/PAPI/Event.rb
39
+ - lib/PAPI/EventSet.rb
40
+ - lib/PAPI/Version.rb
41
+ homepage: https://github.com/Nanosim-LIG/papi-ruby
42
+ licenses:
43
+ - BSD
44
+ metadata: {}
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.9.3
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ requirements: []
60
+ rubyforge_project:
61
+ rubygems_version: 2.2.2
62
+ signing_key:
63
+ specification_version: 4
64
+ summary: Ruby PAPI bindings
65
+ test_files: []