darshan-ruby 3.1.1 → 3.1.1.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.
- checksums.yaml +4 -4
- data/bin/quarshan +283 -0
- data/ext/darshan/darshan-ruby.c +4 -0
- data/ext/darshan/darshan-ruby.h +1 -0
- data/ext/darshan/lustre-module.c +9 -9
- data/ext/darshan/stdio-module.c +64 -0
- data/ext/darshan/stdio-module.h +11 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9380f68e1e53b12918ce4ba9e3258d2e20f8534c
|
4
|
+
data.tar.gz: 6d75c01826d8f6a29fe3edda3afb04f7aea45aef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9257397a634d9913b57a94fce91fe435bf3f795e473b7dcd1dce111d76a97f3ea0da24cb761752e0b88fee39aa485d70ca5b48238201ccb2ef76235afac1d2c4
|
7
|
+
data.tar.gz: b6da20235ce6b10b24e3a97db57d0e99a43beb536df390a287eb44583ee0a59d39d393daaad77033636e91c311d384d143790cbce6d4d90fb921193a041faeb8
|
data/bin/quarshan
ADDED
@@ -0,0 +1,283 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#######################################################################
|
3
|
+
# Author: Matthieu Dorier
|
4
|
+
# Institution: Argonne National Laboratory
|
5
|
+
# Mail: mdorier [at] anl.gov
|
6
|
+
# Date: October 2016
|
7
|
+
#######################################################################
|
8
|
+
|
9
|
+
$LOAD_PATH << '../lib'
|
10
|
+
$LOAD_PATH << '../ext/darshan'
|
11
|
+
|
12
|
+
require 'rubygems'
|
13
|
+
require 'darshan'
|
14
|
+
require 'optparse'
|
15
|
+
|
16
|
+
# List of Darshan modules
|
17
|
+
$darshan_mods = { "POSIX" => Darshan::POSIX,
|
18
|
+
"MPI-IO" => Darshan::MPIIO,
|
19
|
+
"HDF5" => Darshan::HDF5,
|
20
|
+
"PNETCDF" => Darshan::PNETCDF,
|
21
|
+
"BG/Q" => Darshan::BGQ,
|
22
|
+
"LUSTRE" => Darshan::LUSTRE,
|
23
|
+
"STDIO" => Darshan::STDIO }
|
24
|
+
|
25
|
+
# List of available reduction operations
|
26
|
+
$reduction_ops = ['min','max','avg','var','std','med', 'sum']
|
27
|
+
|
28
|
+
# Structure for option parsing
|
29
|
+
Options = Struct.new(:counters,:query,:reductions,:header,:files,:mod,:qcounters)
|
30
|
+
|
31
|
+
# Option parsing class
|
32
|
+
class Parser
|
33
|
+
|
34
|
+
def self.parse(options)
|
35
|
+
args = Options.new([],'true',[],false,[],nil,[])
|
36
|
+
opt_parser = OptionParser.new do |opts|
|
37
|
+
opts.banner = "Usage: quarshan file1 [file2 [...]] [options]"
|
38
|
+
|
39
|
+
opts.on("-o COUNTERS", "--output COUNTERS", "Comma-separated list of counters") do |o|
|
40
|
+
args.counters = o.split(',')
|
41
|
+
end
|
42
|
+
|
43
|
+
opts.on("-v", "--verbose", "Display a header before results") do |h|
|
44
|
+
args.header = h
|
45
|
+
end
|
46
|
+
|
47
|
+
opts.on("-s CONDITION", "--select CONDITION", "Record selection condition") do |q|
|
48
|
+
args.query = q
|
49
|
+
end
|
50
|
+
|
51
|
+
opts.on("-r", "--reductions OPERATIONS", "Comma-separated list of reduction operations") do |r|
|
52
|
+
args.reductions = r.split(',')
|
53
|
+
end
|
54
|
+
|
55
|
+
opts.on("-h", "--help", "Prints this help") do
|
56
|
+
puts opts
|
57
|
+
exit
|
58
|
+
end
|
59
|
+
end
|
60
|
+
opt_parser.parse!(options)
|
61
|
+
args.files = options
|
62
|
+
validate(args)
|
63
|
+
return args
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.validate(args)
|
67
|
+
# check that at least one counter is provided, otherwise we can exit right now
|
68
|
+
if(args.counters.size == 0)
|
69
|
+
exit(0)
|
70
|
+
end
|
71
|
+
# check that if reductions are present, there are as many as counters, or 1
|
72
|
+
if(args.reductions.size > 1)
|
73
|
+
if(args.reductions.size != args.counters.size)
|
74
|
+
$stderr << "Number of reduction operations does not match number of output counters\n"
|
75
|
+
exit(-1)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
# if 1 reduction is provided, extend it to all counters
|
79
|
+
if(args.reductions.size == 1 && args.counters.size > 1)
|
80
|
+
args.reductions *= args.counters.size
|
81
|
+
end
|
82
|
+
# check that reduction operation is valid
|
83
|
+
for r in args.reductions
|
84
|
+
if(!$reduction_ops.include?(r))
|
85
|
+
$stderr << "Unknown reduction operation \"" << r << "\"\n"
|
86
|
+
exit(-1)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
# deduce the module based on the first counter's name
|
90
|
+
for name,mod in $darshan_mods
|
91
|
+
counter = args.counters[0]
|
92
|
+
if(mod::NAMES.include?(counter))
|
93
|
+
args.mod = mod
|
94
|
+
break
|
95
|
+
end
|
96
|
+
end
|
97
|
+
# if module not found, error
|
98
|
+
if(args.mod == nil)
|
99
|
+
$stderr << "Could not deduce Darshan module from provided counters\n"
|
100
|
+
exit(-1)
|
101
|
+
end
|
102
|
+
# check that all counters belong to the deduced module
|
103
|
+
for c in args.counters
|
104
|
+
if(!args.mod::NAMES.include?(c))
|
105
|
+
$stderr << "Counter " << c << " does not belong to module "
|
106
|
+
$stderr << "deduced from first provided counter\n"
|
107
|
+
exit(-1)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
# build the list of counters required for the query
|
111
|
+
pass = false
|
112
|
+
qcounters = []
|
113
|
+
query = args.query.dup
|
114
|
+
# tries to evaluate the query and look for unknown names to
|
115
|
+
# find out the list of counters
|
116
|
+
while(!pass)
|
117
|
+
begin
|
118
|
+
str = "x__=1; "+query
|
119
|
+
eval(str)
|
120
|
+
pass=true
|
121
|
+
rescue NameError => e
|
122
|
+
qcounters << e.name.to_s
|
123
|
+
query.gsub!(e.name.to_s,"x__")
|
124
|
+
rescue Exception => other
|
125
|
+
$stderr << "Error while building query counters list\n"
|
126
|
+
$stderr << "(Ruby error is: " << other << ")\n"
|
127
|
+
exit(-1)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
# make sure the query counters are part of the module
|
131
|
+
for q in qcounters
|
132
|
+
if(!args.mod::NAMES.include?(q))
|
133
|
+
$stderr << "Unknown query counter " << q << " in module " << args.mod.name << "\n"
|
134
|
+
exit(-1)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
args.qcounters = qcounters
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# The Query object is initialized with an Option structure created from
|
142
|
+
# the command line options. It accumulates results from parsed log files.
|
143
|
+
class Query
|
144
|
+
|
145
|
+
def initialize(args)
|
146
|
+
@header = args.header
|
147
|
+
@mod = args.mod
|
148
|
+
@query = args.query
|
149
|
+
@counters = args.counters
|
150
|
+
@qcounters = args.qcounters
|
151
|
+
@counters_idx = [nil]*@counters.size
|
152
|
+
@qcounters_idx = [nil]*@counters.size
|
153
|
+
for i in 0...@counters.size
|
154
|
+
@counters_idx[i] = @mod::NAMES.index(@counters[i])
|
155
|
+
end
|
156
|
+
for i in 0...@qcounters.size
|
157
|
+
@qcounters_idx[i] = @mod::NAMES.index(@qcounters[i])
|
158
|
+
end
|
159
|
+
@reductions = args.reductions
|
160
|
+
@results = []
|
161
|
+
(@counters.size+1).times do
|
162
|
+
@results << []
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def read_file(filename)
|
167
|
+
Darshan::LogFile.open(filename) do |file|
|
168
|
+
file.each_module do | m |
|
169
|
+
next if @mod != $darshan_mods[m.name]
|
170
|
+
m.each_record do | r |
|
171
|
+
process_record(r)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def process_record(record)
|
178
|
+
return if(!query_satisfied(record))
|
179
|
+
@results[0] << record.name
|
180
|
+
for i in 0...@counters_idx.size
|
181
|
+
@results[i+1] << record.counter(@counters_idx[i])
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def query_satisfied(record)
|
186
|
+
str = ""
|
187
|
+
for i in 0...@qcounters.size
|
188
|
+
str += "#{@qcounters[i].downcase}=#{record.counter(@qcounters_idx[i])}; "
|
189
|
+
end
|
190
|
+
str += @query.downcase
|
191
|
+
return eval(str)
|
192
|
+
end
|
193
|
+
|
194
|
+
def reduce
|
195
|
+
return if(@reductions.size == 0)
|
196
|
+
@results[0] = [@results[0].size]
|
197
|
+
for i in 0...@reductions.size
|
198
|
+
eval("@results[i+1] = [#{@reductions[i]}(@results[i+1])]")
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def to_s
|
203
|
+
res = ""
|
204
|
+
if(@header)
|
205
|
+
res += "# records\t"
|
206
|
+
for i in 0...@counters.size
|
207
|
+
if(@reductions.size == 0)
|
208
|
+
res += @counters[i]+"\t"
|
209
|
+
else
|
210
|
+
res += @reductions[i]+"("+@counters[i]+")\t"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
res += "\n"
|
214
|
+
end
|
215
|
+
for j in 0...@results[0].size
|
216
|
+
for i in 0...@results.size
|
217
|
+
res += "#{@results[i][j]}\t"
|
218
|
+
end
|
219
|
+
res += "\n"
|
220
|
+
end
|
221
|
+
return res
|
222
|
+
end
|
223
|
+
|
224
|
+
private
|
225
|
+
|
226
|
+
def max(arr)
|
227
|
+
return arr.max
|
228
|
+
end
|
229
|
+
|
230
|
+
def min(arr)
|
231
|
+
return arr.min
|
232
|
+
end
|
233
|
+
|
234
|
+
def var(arr)
|
235
|
+
x = 0.0
|
236
|
+
for i in arr
|
237
|
+
x += i**2
|
238
|
+
end
|
239
|
+
x /= arr.size
|
240
|
+
a = avg(arr)
|
241
|
+
return x - a**2
|
242
|
+
end
|
243
|
+
|
244
|
+
def med(arr)
|
245
|
+
arr2 = arr.sort
|
246
|
+
if(arr.size % 2 == 1)
|
247
|
+
return arr2[arr.size/2]
|
248
|
+
else
|
249
|
+
return (arr2[arr.size/2]+arr2[arr.size/2+1])/2.0
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def std(arr)
|
254
|
+
v = var(arr)
|
255
|
+
return Math.sqrt(v)
|
256
|
+
end
|
257
|
+
|
258
|
+
def avg(arr)
|
259
|
+
x = 0.0
|
260
|
+
for i in arr
|
261
|
+
x += i
|
262
|
+
end
|
263
|
+
x /= arr.size
|
264
|
+
return x
|
265
|
+
end
|
266
|
+
|
267
|
+
def sum(arr)
|
268
|
+
x = 0.0
|
269
|
+
for i in arr
|
270
|
+
x += i
|
271
|
+
end
|
272
|
+
return x
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
options = Parser.parse(ARGV)
|
277
|
+
files = options.files
|
278
|
+
query = Query.new(options)
|
279
|
+
for f in files
|
280
|
+
query.read_file(f)
|
281
|
+
end
|
282
|
+
query.reduce
|
283
|
+
print query
|
data/ext/darshan/darshan-ruby.c
CHANGED
@@ -206,6 +206,9 @@ static VALUE rb_darshan_next_record(VALUE self)
|
|
206
206
|
case DARSHAN_BGQ_MOD:
|
207
207
|
res = Darshan3rb_get_bgq_record(fd,&rec_id);
|
208
208
|
break;
|
209
|
+
case DARSHAN_STDIO_MOD:
|
210
|
+
res = Darshan3rb_get_stdio_record(fd,&rec_id);
|
211
|
+
break;
|
209
212
|
case DARSHAN_LUSTRE_MOD:
|
210
213
|
res = Darshan3rb_get_lustre_record(fd,&rec_id);
|
211
214
|
break;
|
@@ -242,6 +245,7 @@ void Init_Darshan3rb() {
|
|
242
245
|
Darshan3rb_init_hdf5();
|
243
246
|
Darshan3rb_init_pnetcdf();
|
244
247
|
Darshan3rb_init_bgq();
|
248
|
+
Darshan3rb_init_stdio();
|
245
249
|
Darshan3rb_init_lustre();
|
246
250
|
|
247
251
|
rb_define_method(cDarshanLogFile,"next_module",
|
data/ext/darshan/darshan-ruby.h
CHANGED
data/ext/darshan/lustre-module.c
CHANGED
@@ -9,8 +9,8 @@
|
|
9
9
|
extern VALUE cDarshanRecord;
|
10
10
|
extern VALUE mDarshan;
|
11
11
|
|
12
|
-
VALUE
|
13
|
-
VALUE
|
12
|
+
VALUE cDarshanLUSTRERecord;
|
13
|
+
VALUE mDarshanLUSTRE;
|
14
14
|
|
15
15
|
static VALUE Darshan3rb_lustre_get_counter(VALUE self, VALUE index)
|
16
16
|
{
|
@@ -37,19 +37,19 @@ static VALUE Darshan3rb_lustre_get_osts(VALUE self)
|
|
37
37
|
|
38
38
|
void Darshan3rb_init_lustre()
|
39
39
|
{
|
40
|
-
|
40
|
+
mDarshanLUSTRE = rb_define_module_under(mDarshan,"LUSTRE");
|
41
41
|
|
42
42
|
VALUE cnames = rb_ary_new2(LUSTRE_NUM_INDICES);
|
43
43
|
int i;
|
44
44
|
for(i=0; i < LUSTRE_NUM_INDICES; i++) {
|
45
45
|
rb_ary_store(cnames,i,rb_str_new2(mpiio_counter_names[i]));
|
46
|
-
rb_define_const(
|
46
|
+
rb_define_const(mDarshanLUSTRE,mpiio_counter_names[i],INT2NUM(i));
|
47
47
|
}
|
48
|
-
rb_define_const(
|
48
|
+
rb_define_const(mDarshanLUSTRE,"NAMES",cnames);
|
49
49
|
|
50
|
-
|
51
|
-
rb_define_method(
|
52
|
-
rb_define_method(
|
50
|
+
cDarshanLUSTRERecord = rb_define_class_under(mDarshanLUSTRE,"Record",cDarshanRecord);
|
51
|
+
rb_define_method(cDarshanLUSTRERecord,"counter",Darshan3rb_lustre_get_counter,1);
|
52
|
+
rb_define_method(cDarshanLUSTRERecord,"osts",Darshan3rb_lustre_get_osts,0);
|
53
53
|
}
|
54
54
|
|
55
55
|
VALUE Darshan3rb_get_lustre_record(darshan_fd fd, darshan_record_id* rec_id)
|
@@ -58,6 +58,6 @@ VALUE Darshan3rb_get_lustre_record(darshan_fd fd, darshan_record_id* rec_id)
|
|
58
58
|
int r = mod_logutils[DARSHAN_LUSTRE_MOD]->log_get_record(fd, (void**)&c_record);
|
59
59
|
if(r != 1) return Qnil;
|
60
60
|
*rec_id = c_record->base_rec.id;
|
61
|
-
VALUE rb_record = Data_Wrap_Struct(
|
61
|
+
VALUE rb_record = Data_Wrap_Struct(cDarshanLUSTRERecord, NULL , free, c_record);
|
62
62
|
return rb_record;
|
63
63
|
}
|
@@ -0,0 +1,64 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) 2015 University of Chicago.
|
3
|
+
* See COPYRIGHT notice in top-level directory.
|
4
|
+
*
|
5
|
+
*/
|
6
|
+
|
7
|
+
#include "darshan-ruby.h"
|
8
|
+
|
9
|
+
extern VALUE cDarshanRecord;
|
10
|
+
extern VALUE mDarshan;
|
11
|
+
|
12
|
+
VALUE cDarshanSTDIORecord;
|
13
|
+
VALUE mDarshanSTDIO;
|
14
|
+
|
15
|
+
static VALUE Darshan3rb_stdio_get_rank(VALUE self)
|
16
|
+
{
|
17
|
+
struct darshan_stdio_file* c_record = NULL;
|
18
|
+
Data_Get_Struct(self, struct darshan_stdio_file, c_record);
|
19
|
+
if(c_record) return LL2NUM(c_record->base_rec.rank);
|
20
|
+
else return Qnil;
|
21
|
+
}
|
22
|
+
|
23
|
+
static VALUE Darshan3rb_stdio_get_counter(VALUE self, VALUE index)
|
24
|
+
{
|
25
|
+
struct darshan_stdio_file* c_record = NULL;
|
26
|
+
Data_Get_Struct(self,struct darshan_stdio_file, c_record);
|
27
|
+
int i = NUM2INT(index);
|
28
|
+
if((i < 0) || (c_record == NULL)) return Qnil;
|
29
|
+
if(i < STDIO_NUM_INDICES) return LL2NUM(c_record->counters[i]);
|
30
|
+
if(i < STDIO_NUM_INDICES+STDIO_F_NUM_INDICES) return rb_float_new(c_record->fcounters[i-STDIO_NUM_INDICES]);
|
31
|
+
else return Qnil;
|
32
|
+
}
|
33
|
+
|
34
|
+
void Darshan3rb_init_stdio()
|
35
|
+
{
|
36
|
+
mDarshanSTDIO = rb_define_module_under(mDarshan,"STDIO");
|
37
|
+
|
38
|
+
VALUE cnames = rb_ary_new2(STDIO_NUM_INDICES+STDIO_F_NUM_INDICES);
|
39
|
+
int i;
|
40
|
+
for(i=0; i < STDIO_NUM_INDICES; i++) {
|
41
|
+
rb_ary_store(cnames,i,rb_str_new2(stdio_counter_names[i]));
|
42
|
+
rb_define_const(mDarshanSTDIO,stdio_counter_names[i],INT2NUM(i));
|
43
|
+
}
|
44
|
+
for(i=0; i < STDIO_F_NUM_INDICES; i++) {
|
45
|
+
int j = i+STDIO_NUM_INDICES;
|
46
|
+
rb_ary_store(cnames,j,rb_str_new2(stdio_f_counter_names[i]));
|
47
|
+
rb_define_const(mDarshanSTDIO,stdio_f_counter_names[i],INT2NUM(j));
|
48
|
+
}
|
49
|
+
rb_define_const(mDarshanSTDIO,"NAMES",cnames);
|
50
|
+
|
51
|
+
cDarshanSTDIORecord = rb_define_class_under(mDarshanSTDIO,"Record",cDarshanRecord);
|
52
|
+
rb_define_method(cDarshanSTDIORecord,"rank",Darshan3rb_stdio_get_rank,0);
|
53
|
+
rb_define_method(cDarshanSTDIORecord,"counter",Darshan3rb_stdio_get_counter,1);
|
54
|
+
}
|
55
|
+
|
56
|
+
VALUE Darshan3rb_get_stdio_record(darshan_fd fd, darshan_record_id* rec_id)
|
57
|
+
{
|
58
|
+
struct darshan_stdio_file* c_record = NULL;
|
59
|
+
int r = mod_logutils[DARSHAN_STDIO_MOD]->log_get_record(fd, (void**)&c_record);
|
60
|
+
if(r != 1) return Qnil;
|
61
|
+
*rec_id = c_record->base_rec.id;
|
62
|
+
VALUE rb_record = Data_Wrap_Struct(cDarshanSTDIORecord, NULL , free, c_record);
|
63
|
+
return rb_record;
|
64
|
+
}
|
metadata
CHANGED
@@ -1,22 +1,24 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: darshan-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.1
|
4
|
+
version: 3.1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthieu Dorier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Ruby binding to ANL's Darshan library for HPC I/O tracing and analysis
|
14
14
|
email: mdorier@anl.gov
|
15
|
-
executables:
|
15
|
+
executables:
|
16
|
+
- quarshan
|
16
17
|
extensions:
|
17
18
|
- ext/darshan/extconf.rb
|
18
19
|
extra_rdoc_files: []
|
19
20
|
files:
|
21
|
+
- bin/quarshan
|
20
22
|
- ext/darshan/bgq-module.c
|
21
23
|
- ext/darshan/bgq-module.h
|
22
24
|
- ext/darshan/darshan-ruby.c
|
@@ -32,6 +34,8 @@ files:
|
|
32
34
|
- ext/darshan/pnetcdf-module.h
|
33
35
|
- ext/darshan/posix-module.c
|
34
36
|
- ext/darshan/posix-module.h
|
37
|
+
- ext/darshan/stdio-module.c
|
38
|
+
- ext/darshan/stdio-module.h
|
35
39
|
- lib/darshan.rb
|
36
40
|
homepage: http://www.mcs.anl.gov/research/projects/darshan/
|
37
41
|
licenses:
|