trace_visualization 0.0.2 → 0.0.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a5779b63579f93699f091c22ada7121df9469fc7
4
- data.tar.gz: 336cfdc696d598e2247d09b089ec2b426df18e58
3
+ metadata.gz: 12c27504ea6bbbabd78f47e5bee3df251a5a7050
4
+ data.tar.gz: 75a0bf55e52a108f449def1998de4fbf319d1f94
5
5
  SHA512:
6
- metadata.gz: 583564ac99432f9a0b05e1a51550497ae2f18d30fad51a7443fd8f9e6930567a66cac481a48c9cd594483a35eccdb4eff852a644bc8ce896fe7bffa14c3562fa
7
- data.tar.gz: 721cf7cdf88fe2ac0380f4eb9517ffda3e6846cba7d317e6c5f1cdfac453c288b40b2b7d674de2039a0a2e88aab0a2b33b89dcde0d379a3b0c674b59fb5bb688
6
+ metadata.gz: f6fff098106b2ba908595a05345bebafc5686348454061983671c937c21a26ecb0cee59a8d6209203707949e7283daba5d620b7d386cd1ac230e021668f4a7f5
7
+ data.tar.gz: 6e39264b5f0141746d7fda75d4c2c2be624a0829c12ed548160e6bd9f74afac162b06a6e9e670155ef042f7b7baf65eb0bff43a42236051f0aec81b15842495c
data/Gemfile CHANGED
@@ -2,6 +2,8 @@ source 'https://rubygems.org'
2
2
 
3
3
  ruby '2.0.0'
4
4
 
5
+ gem 'trace_preprocessor', "~> 0.0.2"
6
+
5
7
  # Specify your gem's dependencies in trace_visualization.gemspec
6
8
  gemspec
7
9
 
data/Rakefile CHANGED
@@ -1,9 +1,9 @@
1
1
  require 'bundler/gem_tasks'
2
2
 
3
- desc 'Compile preprocessor'
4
- task :install do
5
- system('cd lib/trace_visualization/preprocessor; make install; make clean')
6
- end
3
+ #desc 'Compile preprocessor'
4
+ #task :install do
5
+ # system('cd ext/preprocessor; make install')
6
+ #end
7
7
 
8
8
  desc 'Spec all functionality of gem'
9
9
  task :spec_all do
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'trace_visualization'
4
+ require 'tempfile'
5
+ require 'benchmark'
6
+ require 'optparse'
7
+
8
+ include TraceVisualization
9
+
10
+ ##
11
+ # Parse command line options
12
+ def parse_options
13
+ options = {}
14
+
15
+ optionParser = OptionParser.new do|opts|
16
+ opts.banner = "Usage: trace_visualization [options] file"
17
+
18
+ options[:offset] = 0
19
+ opts.on('-x', '--offset N', 'Number of lines for offset. Default 0') do |n|
20
+ options[:offset] = n.to_i
21
+ end
22
+
23
+ options[:limit] = 2**32
24
+ opts.on('-l', '--limit N', "Number of lines. Default #{options[:limit]}") do |n|
25
+ options[:limit] = n.to_i
26
+ end
27
+
28
+ options[:out] = 3
29
+ opts.on('-o', '--out N', 'Number of output results') do |n|
30
+ options[:out] = n.to_i
31
+ end
32
+
33
+ options[:positions_min_size] = 3
34
+ opts.on('-m', '--positions_min_size N', "The minimum number of repetition positions. Default #{options[:positions_min_size]}") do |s|
35
+ options[:positions_min_size] = s.to_i
36
+ end
37
+
38
+ options[:test_preprocessor_performance] = false
39
+ opts.on('-t', '--test_preprocessor_performance', 'Test preprocessor performance') do
40
+ options[:test_preprocessor_performance] = true
41
+ end
42
+
43
+ opts.on('-h', '--help', 'Display this screen') do
44
+ puts opts
45
+ exit
46
+ end
47
+ end
48
+
49
+ optionParser.parse!
50
+
51
+ options[:source_file_name] = ARGV[0]
52
+
53
+ options
54
+ end
55
+
56
+ #------------------------------------------------------------------------------
57
+ def foo(options)
58
+
59
+ preprocessorConfig = TracePreprocessor.init do
60
+ use_default_lexemes
61
+
62
+ output_token "printf(\"{TOKEN;%s;%s;%ld;%d}\", name, source, value, value_kind);"
63
+ end
64
+
65
+ preprocessor = nil
66
+ bm('Preprocessor Generate') do
67
+ preprocessor = TracePreprocessor.generate(preprocessorConfig, :c)
68
+ end
69
+
70
+ tmp_file = Tempfile.new('trace_visualization')
71
+
72
+ bm('Preprocessor work') do
73
+ preprocessor.run options[:source_file_name], tmp_file.path
74
+ end
75
+
76
+ mapping = nil
77
+ bm('Mapping') do
78
+ mapping = TraceVisualization::Mapping.new
79
+ mapping.process_without_reorder { from_preprocessed_file(tmp_file.path, options[:offset], options[:limit], !options[:test_preprocessor_performance]) }
80
+ end
81
+
82
+ source_file_length = `wc -c #{options[:source_file_name]}`.to_i
83
+ tmp_file_length = tmp_file.length
84
+
85
+ puts "source_file_length = #{source_file_length}"
86
+ puts "tmp_file_length = #{tmp_file_length} (+#{((tmp_file_length - source_file_length) * 100.0 / source_file_length).round(2)}%)"
87
+ puts "mapping_length = #{mapping.length} (-#{((source_file_length - mapping.length) * 100.0 / source_file_length).round(2)}%)"
88
+
89
+ tmp_file.close
90
+ tmp_file.unlink
91
+
92
+ if options[:test_preprocessor_performance]
93
+ puts "Finish preprocessor"
94
+ exit 0
95
+ end
96
+
97
+ rs = nil
98
+ bm('PSY1') do
99
+ rs = Repetitions.psy1(mapping, options[:positions_min_size], true)
100
+ end
101
+
102
+ puts "rs.size = #{rs.size}"
103
+
104
+ #context = nil
105
+ #bm('Context') do
106
+ # context = TraceVisualization::Repetitions::Context.new(mapping, rs)
107
+ #end
108
+
109
+ RepetitionsScore.fill_score(rs, :sort => true, :order => 'desc', :version => 'relative')
110
+
111
+ rs[0 ... options[:out]].each do |r|
112
+ puts '---------------------'
113
+ puts r
114
+ puts Visualization::ConsoleColorPrint.hl(mapping, r)
115
+ end
116
+
117
+ rs
118
+ end
119
+
120
+
121
+ def bm(name, &block)
122
+ Benchmark.bm(17) do |x|
123
+ x.report(name, &block)
124
+ end
125
+ end
126
+
127
+
128
+ options = parse_options
129
+ rs = foo(options)
130
+
131
+
132
+
133
+
@@ -2,6 +2,12 @@
2
2
  mapping
3
3
  utils
4
4
  version
5
+ reorder
6
+ repetitions
7
+ repetitions_psy
8
+ repetitions_context
9
+ repetitions_score
10
+ visualization/console_color_print
5
11
  ).each { |file| require File.join(File.dirname(__FILE__), 'trace_visualization', file) }
6
12
 
7
13
  require 'logger'
@@ -58,61 +58,73 @@ module TraceVisualization
58
58
  @max_value = TraceVisualization::Reorder.process(@mapped_str)
59
59
  end
60
60
 
61
+ def process_without_reorder(&block)
62
+ instance_eval(&block)
63
+ end
64
+
65
+ ##
61
66
  # Load data from source file. File is read line by line
67
+
62
68
  def from_file(path)
63
- raise ArgumentError, 'Argument must be a string' unless path.instance_of? String
64
- raise ArgumentError, 'File path is not defined' unless path.empty?
65
- raise RuntimeError, 'File doesn\'t exists' unless File.exists?(path)
66
-
67
- fd = open(path)
68
- process_line(line) while line = fd.gets
69
- fd.close
69
+ validate_file_name_argument(path)
70
+
71
+ open(path) do |fd|
72
+ while (line = fd.gets)
73
+ process_line(line)
74
+ end
75
+ end
70
76
  end
71
77
 
78
+ ##
72
79
  # Load data from preprocessed file. File is read line by line
73
- def from_preprocessed_file(path)
74
- raise ArgumentError, 'Argument must be a string' unless path.instance_of? String
75
- raise ArgumentError, 'File path is not defined' unless path.empty?
76
- raise RuntimeError, 'File doesn\'t exists' unless File.exists?(path)
77
80
 
78
- fd = open(path)
79
- process_preprocessed_line line while line = fd.gets
80
- fd.close
81
+ def from_preprocessed_file(path, offset, limit, use_lexeme_table = true)
82
+ validate_file_name_argument(path)
83
+
84
+ idx = 0
85
+ open(path) do |fd|
86
+ while (line = fd.gets)
87
+ process_preprocessed_line(line, use_lexeme_table) if (idx >= offset && idx < offset + limit)
88
+
89
+ idx += 1
90
+ end
91
+ end
81
92
  end
82
93
 
83
94
  # new
84
95
  def from_string(str)
85
- raise ArgumentError, 'Argument must be a string' unless str.instance_of? String
86
- raise ArgumentError, 'String is not defined' if str.empty?
96
+ validate_string_argument(str)
87
97
 
88
98
  @str = str
89
99
 
90
100
  str.split("\n").each do |line|
91
101
  process_line(line)
92
102
  end
103
+
104
+ @mapped_str.pop if @mapped_str[-1].value == "\n" && str[-1] != "\n"
93
105
  end
94
-
95
- def from_preprocessed_string(str)
96
- raise ArgumentError, 'Argument must be a string' if not str.instance_of? String
97
- raise ArgumentError, 'String is not defined' if str.empty?
106
+
107
+ def from_preprocessed_string(str, use_lexeme_table = true)
108
+ validate_string_argument(str)
98
109
 
99
110
  str.split("\n").each do |line|
100
111
  process_preprocessed_line(line)
101
112
  end
102
113
  end
103
114
 
104
- def process_preprocessed_line(line)
115
+ def process_preprocessed_line(line, use_lexeme_table = true)
105
116
  lexeme_positions = []
106
117
  pos = 0
107
118
  while (m = LEXEME_REGEXP.match(line, pos))
108
119
  pos = m.begin(0)
109
-
110
- lexeme = install_lexeme_m(m)
120
+
121
+ lexeme = install_lexeme_m(m, use_lexeme_table)
111
122
  lexeme_positions << TraceVisualization::Data::LexemePos.new(lexeme, pos)
112
123
 
113
124
  pos += lexeme.lexeme_length
114
125
  end
115
-
126
+
127
+
116
128
  pos, idx = 0, 0
117
129
  while pos < line.length
118
130
  lexeme = nil
@@ -120,13 +132,13 @@ module TraceVisualization
120
132
  lexeme = lexeme_positions[idx].lexeme
121
133
  idx += 1
122
134
  else
123
- lexeme = install_lexeme('CHAR', line[pos], line[pos].ord, 1)
135
+ lexeme = install_lexeme('CHAR', line[pos], line[pos].ord, 1, use_lexeme_table)
124
136
  end
125
137
  pos += lexeme.lexeme_length
126
138
  @mapped_str << lexeme
127
139
  end
128
-
129
- @mapped_str << install_lexeme('CHAR', "\n", "\n".ord, 1)
140
+
141
+ @mapped_str << install_lexeme('CHAR', "\n", "\n".ord, 1, use_lexeme_table)
130
142
  end
131
143
 
132
144
  # new
@@ -164,28 +176,21 @@ module TraceVisualization
164
176
  @mapped_str << install_lexeme('CHAR', "\n", "\n".ord, 1)
165
177
  end
166
178
 
167
- def install_lexeme(name, lexeme_string, int_value, lexeme_length)
168
- lexeme = @lexeme_table[lexeme_string]
179
+ def install_lexeme(name, lexeme_string, int_value, lexeme_length, use_lexeme_table = true)
180
+ lexeme = use_lexeme_table ? @lexeme_table[lexeme_string] : nil
169
181
 
170
- if lexeme == nil
182
+ if lexeme.nil?
171
183
  lexeme = TraceVisualization::Data::Lexeme.new(name, lexeme_string, int_value)
172
184
  lexeme.lexeme_length = lexeme_length
173
- @lexeme_table[lexeme_string] = lexeme
185
+
186
+ @lexeme_table[lexeme_string] = lexeme if use_lexeme_table
174
187
  end
175
188
 
176
189
  lexeme
177
190
  end
178
191
 
179
- def install_lexeme_m(m)
180
- lexeme = @lexeme_table[m[:source]]
181
-
182
- if lexeme == nil
183
- lexeme = TraceVisualization::Data::Lexeme.new(m[:name], m[:source], m[:value].to_i)
184
- lexeme.lexeme_length = m.to_s.length
185
- @lexeme_table[m[:source]] = lexeme
186
- end
187
-
188
- lexeme
192
+ def install_lexeme_m(m, use_lexeme_table = true)
193
+ install_lexeme(m[:name], m[:source], m[:value].to_i, m.to_s.length, use_lexeme_table)
189
194
  end
190
195
 
191
196
  def [](index)
@@ -201,7 +206,9 @@ module TraceVisualization
201
206
  end
202
207
 
203
208
  def <<(object)
204
- @mapped_str << Item.new(object, "unknown")
209
+ lexeme = install_lexeme('UNKNOWN', object, object.to_i, object.to_s.length)
210
+ lexeme.ord = 0 # fake ord because Reorder already processed
211
+ @mapped_str << lexeme
205
212
  end
206
213
 
207
214
  def pop
@@ -279,5 +286,17 @@ module TraceVisualization
279
286
  end
280
287
 
281
288
  end
289
+
290
+ def validate_file_name_argument(path)
291
+ raise ArgumentError, 'Argument must be a string' if not path.instance_of? String
292
+ raise ArgumentError, 'File path is not defined' if path.empty?
293
+ raise RuntimeError, 'File doesn\'t exists' if not File.exists?(path)
294
+ end
295
+
296
+ def validate_string_argument(str)
297
+ raise ArgumentError, 'Argument must be a string' unless str.instance_of? String
298
+ raise ArgumentError, 'String is not defined' if str.empty?
299
+ end
300
+
282
301
  end
283
302
  end
@@ -1,3 +1,5 @@
1
+ require 'trace_visualization'
2
+
1
3
  module TraceVisualization
2
4
  module Reorder
3
5
 
@@ -0,0 +1,87 @@
1
+ module TraceVisualization
2
+ module RepetitionsScore
3
+
4
+ # Priority length when repetition score is calculated
5
+ ALPHA_SCORE = 0.5
6
+
7
+ # Priority positions.size when repetition score is calculated
8
+ BETA_SCORE = 1 - ALPHA_SCORE
9
+
10
+ # Options:
11
+ # *sort* true / false
12
+ # *order* order for sort (default 'asc')
13
+ # *version* version of importance function
14
+ def self.fill_score(rs, options = {})
15
+
16
+ opts = {
17
+ :sort => false,
18
+ :order => 'asc'
19
+ }.merge options
20
+
21
+ case opts[:version]
22
+ when 'relative'
23
+ function_relative(rs)
24
+ when 'linear'
25
+ function_linear(rs)
26
+ else
27
+ throw Exception.new("Unknown version")
28
+ end
29
+
30
+ if opts[:sort]
31
+ rs.sort! do |a, b|
32
+ opts[:order] == 'desc' ? b.score <=> a.score : a.score <=> b.score
33
+ end
34
+ end
35
+ end
36
+
37
+ # f(len, size) = alpha * len' + beta * size'
38
+ # len', size' - relative to max values
39
+ def self.function_relative(rs)
40
+ len_max, size_max = 0, 0
41
+
42
+ rs.each do |r|
43
+ len = r.length
44
+ len_max = len if len > len_max
45
+
46
+ size = r.positions_size
47
+ size_max = size if size > size_max
48
+ end
49
+
50
+ rs.each do |r|
51
+ r.score = ALPHA_SCORE * r.strict_length / len_max +
52
+ BETA_SCORE * r.positions_size / size_max
53
+ end
54
+ end
55
+
56
+ # f(len, size, k) = alpha * len + beta * size + gamma * k
57
+ def self.function_linear(rs)
58
+ len_max, len_min, size_max, size_min, k_max = 0, 2**32, 0, 2**32, 0
59
+
60
+ rs.each do |r|
61
+ len = r.length
62
+ len_max = len if len > len_max
63
+ len_min = len if len < len_min
64
+
65
+ size = r.positions_size
66
+ size_max = size if size > size_max
67
+ size_min = size if size < size_min
68
+
69
+ k_max = r.k if r.k > k_max
70
+ end
71
+
72
+ d = (len_max * size_min + size_max * k_max - size_max * len_min - len_max * k_max).to_f
73
+
74
+ alpha = (size_min + k_max * (size_max - 1)) / d
75
+ beta = - (len_min + k_max * (len_max - 1)) / d
76
+ gamma = (len_max * size_min - size_max * len_min - size_min + len_min) / d
77
+
78
+ puts "len_max = #{len_max}, len_min = #{len_min}, size_max = #{size_max}, size_min = #{size_min}, k_max = #{k_max}"
79
+ puts "alpha = #{alpha}, beta = #{beta}, gamma = #{gamma}"
80
+
81
+ rs.each do |r|
82
+ r.score = alpha * r.length + beta * r.positions_size + gamma * r.k
83
+ end
84
+ end
85
+
86
+ end
87
+ end