All of lore.kernel.org
 help / color / mirror / Atom feed
From: Erwan Velu <erwan@enovance.com>
To: "fio@vger.kernel.org" <fio@vger.kernel.org>
Subject: Re: [Pull Request] Updating tools
Date: Wed, 31 Jul 2013 12:36:14 +0200	[thread overview]
Message-ID: <51F8E89E.4060208@enovance.com> (raw)
In-Reply-To: <51F7ACC3.2000904@enovance.com>

[-- Attachment #1: Type: text/plain, Size: 18511 bytes --]

Dear Jens,

I've been updating my branch to add a new feature and some visual 
improvements.

The main feature is if more than one file is matching the pattern, a new 
set of graphing is generated allowing traces comparaisons on the same 
graph as does fio_generate_plots

I've been adding sample files in the three moods (raw/smooth/trend) as 
an attachement.

That's a good addition to the existing plotting I did with fio2gnuplot.
Cheers,
Erwan

The following changes since commit bf974737b15bad8d740f10503e9eab6e0b420aa2:

   Update sample atomic write job file (2013-07-26 13:11:52 -0600)

are available in the git repository at:

   git@github.com:enovance/fio.git erwan/outputdir

for you to fetch changes up to 428b4f6ba681dbb40c8e2213d0c6ae8f8049dcd5:

   fio2gnuplot: Adding filename as title for 2D graphs (2013-07-31 
12:32:40 +0200)

----------------------------------------------------------------
Erwan Velu (10):
       fio2gnuplot: Option to select gnuplot's output dir
       Makefile: Installing fio2gnuplot & sons
       Makefile: Installing genfio at install time
       Tree: Moving fio_generate_plots in tools/
       fio2gnuplot: Using default install dir for gpm files
       fio2gnuplot: Printing number of selected files
       fio2gnuplot: Adding comparing 2D graphs
       fio2gnuplot: Fixing help message
       fio2gnuplot: Adding information steps
       fio2gnuplot: Adding filename as title for 2D graphs

  Makefile                                           |   8 ++++--
  fio_generate_plots => tools/fio_generate_plots     |   0
  fio_generate_plots.1 => tools/fio_generate_plots.1 |   0
  tools/plot/fio2gnuplot.py                          | 159 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
  4 files changed, 129 insertions(+), 38 deletions(-)
  rename fio_generate_plots => tools/fio_generate_plots (100%)
  rename fio_generate_plots.1 => tools/fio_generate_plots.1 (100%)

diff --git a/Makefile b/Makefile
index 3de9735..8494b27 100644
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,7 @@ OPTFLAGS= -O3 -g -ffast-math
  CFLAGS    = -std=gnu99 -Wwrite-strings -Wall 
-Wdeclaration-after-statement $(OPTFLAGS) $(EXTFLAGS) $(BUILD_CFLAGS)
  LIBS    += -lm $(EXTLIBS)
  PROGS    = fio
-SCRIPTS = fio_generate_plots
+SCRIPTS = tools/fio_generate_plots tools/plot/fio2gnuplot.py tools/genfio

  ifdef CONFIG_GFIO
    PROGS += gfio
@@ -189,8 +189,10 @@ bindir = $(prefix)/bin

  ifeq ($(CONFIG_TARGET_OS), Darwin)
  mandir = /usr/share/man
+sharedir = /usr/share/fio
  else
  mandir = $(prefix)/man
+sharedir = $(prefix)/share/fio
  endif

  all: $(PROGS) $(SCRIPTS) FORCE
@@ -278,4 +280,6 @@ install: $(PROGS) $(SCRIPTS) FORCE
      $(INSTALL) $(PROGS) $(SCRIPTS) $(DESTDIR)$(bindir)
      $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
      $(INSTALL) -m 644 fio.1 $(DESTDIR)$(mandir)/man1
-    $(INSTALL) -m 644 fio_generate_plots.1 $(DESTDIR)$(mandir)/man1
+    $(INSTALL) -m 644 tools/fio_generate_plots.1 $(DESTDIR)$(mandir)/man1
+    $(INSTALL) -m 755 -d $(DESTDIR)$(sharedir)
+    $(INSTALL) -m 644 tools/plot/*gpm $(DESTDIR)$(sharedir)/
diff --git a/fio_generate_plots b/tools/fio_generate_plots
similarity index 100%
rename from fio_generate_plots
rename to tools/fio_generate_plots
diff --git a/fio_generate_plots.1 b/tools/fio_generate_plots.1
similarity index 100%
rename from fio_generate_plots.1
rename to tools/fio_generate_plots.1
diff --git a/tools/plot/fio2gnuplot.py b/tools/plot/fio2gnuplot.py
index 03ef0dd..800c334 100755
--- a/tools/plot/fio2gnuplot.py
+++ b/tools/plot/fio2gnuplot.py
@@ -25,6 +25,7 @@ import sys
  import getopt
  import re
  import math
+import shutil

  def find_file(path, pattern):
      fio_data_file=[]
@@ -37,40 +38,95 @@ def find_file(path, pattern):

      return fio_data_file

-def 
generate_gnuplot_script(fio_data_file,title,gnuplot_output_filename,mode,disk_perf):
-    f=open("mygraph",'w')
+def 
generate_gnuplot_script(fio_data_file,title,gnuplot_output_filename,gnuplot_output_dir,mode,disk_perf,gpm_dir):
+    print "Generating rendering scripts"
+    filename=gnuplot_output_dir+'mygraph'
+    f=open(filename,'w')
+
+    # Plotting 3D or comparing graphs doesn't have a meaning unless if 
there is at least 2 traces
      if len(fio_data_file) > 1:
-            f.write("call \'graph3D.gpm\' \'%s' \'%s\' \'\' \'%s\' 
\'%s\'\n" % (title,gnuplot_output_filename,gnuplot_output_filename,mode))
+            f.write("call \'%s/graph3D.gpm\' \'%s' \'%s\' \'\' \'%s\' 
\'%s\'\n" % 
(gpm_dir,title,gnuplot_output_filename,gnuplot_output_filename,mode))
+
+        # Setting up the compare files that will be plot later
+        compare=open(gnuplot_output_dir + 'compare.gnuplot','w')
+        compare.write('''
+set title '%s'
+set terminal png size 1280,1024
+set ytics axis out auto
+set key top left reverse
+set xlabel "Time (Seconds)"
+set ylabel '%s'
+set xrange [0:]
+set yrange [0:]
+'''% (title,mode))
+        compare.close()
+        #Copying the common file for all kind of graph (raw/smooth/trend)
+        compare_raw_filename="compare-%s-2Draw" % (gnuplot_output_filename)
+        compare_smooth_filename="compare-%s-2Dsmooth" % 
(gnuplot_output_filename)
+        compare_trend_filename="compare-%s-2Dtrend" % 
(gnuplot_output_filename)
+ 
shutil.copy(gnuplot_output_dir+'compare.gnuplot',gnuplot_output_dir+compare_raw_filename+".gnuplot")
+ 
shutil.copy(gnuplot_output_dir+'compare.gnuplot',gnuplot_output_dir+compare_smooth_filename+".gnuplot")
+ 
shutil.copy(gnuplot_output_dir+'compare.gnuplot',gnuplot_output_dir+compare_trend_filename+".gnuplot")
+
+        #Setting up a different output filename for each kind of graph
+        compare_raw=open(gnuplot_output_dir+compare_raw_filename + 
".gnuplot",'a')
+        compare_raw.write("set output '%s.png'\n" % compare_raw_filename)
+ 
compare_smooth=open(gnuplot_output_dir+compare_smooth_filename+".gnuplot",'a')
+        compare_smooth.write("set output '%s.png'\n" % 
compare_smooth_filename)
+ 
compare_trend=open(gnuplot_output_dir+compare_trend_filename+".gnuplot",'a')
+        compare_trend.write("set output '%s.png'\n" % 
compare_trend_filename)

          pos=0
          # Let's create a temporary file for each selected fio file
          for file in fio_data_file:
                  tmp_filename = "gnuplot_temp_file.%d" % pos
-                png_file=file.replace('.log','')
+
+        # Plotting comparing graphs doesn't have a meaning unless if 
there is at least 2 traces
+        if len(fio_data_file) > 1:
+            # Adding the plot instruction for each kind of comparing graphs
+            if pos ==0 :
+                compare_raw.write("plot '%s' using 2:3 with linespoints 
title '%s'" % (tmp_filename,fio_data_file[pos]))
+                compare_smooth.write("plot '%s' using 2:3 smooth 
csplines title '%s'" % (tmp_filename,fio_data_file[pos]))
+                compare_trend.write("plot '%s' using 2:3 smooth bezier 
title '%s'" % (tmp_filename,fio_data_file[pos]))
+            else:
+                compare_raw.write(",\\\n'%s' using 2:3 with linespoints 
title '%s'" % (tmp_filename,fio_data_file[pos]))
+                compare_smooth.write(",\\\n'%s' using 2:3 smooth 
csplines title '%s'" % (tmp_filename,fio_data_file[pos]))
+                compare_trend.write(",\\\n'%s' using 2:3 smooth bezier 
title '%s'" % (tmp_filename,fio_data_file[pos]))
+
+        png_file=file.replace('.log','')
                  raw_filename = "%s-2Draw" % (png_file)
                  smooth_filename = "%s-2Dsmooth" % (png_file)
                  trend_filename = "%s-2Dtrend" % (png_file)
                  avg  = average(disk_perf[pos])
-                f.write("call \'graph2D.gpm\' \'%s' \'%s\' \'\' \'%s\' 
\'%s\' \'%s\' \'%s\' \'%f\'\n" % 
(title,tmp_filename,raw_filename,mode,smooth_filename,trend_filename,avg))
+                f.write("call \'%s/graph2D.gpm\' \'%s' \'%s\' \'%s\' 
\'%s\' \'%s\' \'%s\' \'%s\' \'%f\'\n" % 
(gpm_dir,title,tmp_filename,fio_data_file[pos],raw_filename,mode,smooth_filename,trend_filename,avg))
                  pos = pos +1

+    # Plotting comparing graphs doesn't have a meaning unless if there 
is at least 2 traces
+    if len(fio_data_file) > 1:
+        os.remove(gnuplot_output_dir+"compare.gnuplot")
+        compare_raw.close()
+        compare_smooth.close()
+        compare_trend.close()
      f.close()

-def 
generate_gnuplot_math_script(title,gnuplot_output_filename,mode,average):
-    f=open("mymath",'a')
-        f.write("call \'math.gpm\' \'%s' \'%s\' \'\' \'%s\' \'%s\' 
%s\n" % 
(title,gnuplot_output_filename,gnuplot_output_filename,mode,average))
+def 
generate_gnuplot_math_script(title,gnuplot_output_filename,mode,average,gnuplot_output_dir,gpm_dir):
+    filename=gnuplot_output_dir+'mymath';
+    f=open(filename,'a')
+        f.write("call \'%s/math.gpm\' \'%s' \'%s\' \'\' \'%s\' \'%s\' 
%s\n" % 
(gpm_dir,title,gnuplot_output_filename,gnuplot_output_filename,mode,average))
      f.close()

-def compute_aggregated_file(fio_data_file, gnuplot_output_filename):
+def compute_aggregated_file(fio_data_file, gnuplot_output_filename, 
gnuplot_output_dir):
+    print "Processing data file 2/2"
      temp_files=[]
      pos=0
+
      # Let's create a temporary file for each selected fio file
      for file in fio_data_file:
-        tmp_filename = "gnuplot_temp_file.%d" % pos
+        tmp_filename = "%sgnuplot_temp_file.%d" % (gnuplot_output_dir, pos)
          temp_files.append(open(tmp_filename,'r'))
          pos = pos +1

-    f = open(gnuplot_output_filename, "w")
+    f = open(gnuplot_output_dir+gnuplot_output_filename, "w")
      index=0
      # Let's add some information
      for tempfile in temp_files:
@@ -83,14 +139,15 @@ def compute_aggregated_file(fio_data_file, 
gnuplot_output_filename):

  def average(s): return sum(s) * 1.0 / len(s)

-def compute_temp_file(fio_data_file,disk_perf):
+def compute_temp_file(fio_data_file,disk_perf,gnuplot_output_dir):
+    print "Processing data file 1/2"
      files=[]
      temp_outfile=[]
      blk_size=0
      for file in fio_data_file:
          files.append(open(file))
          pos = len(files) - 1
-        tmp_filename = "gnuplot_temp_file.%d" % pos
+        tmp_filename = "%sgnuplot_temp_file.%d" % (gnuplot_output_dir,pos)
          gnuplot_file=open(tmp_filename,'w')
          temp_outfile.append(gnuplot_file)
          gnuplot_file.write("#Temporary file based on file %s\n" % file)
@@ -144,14 +201,15 @@ def compute_temp_file(fio_data_file,disk_perf):
                  file.close()
      return blk_size

-def compute_math(fio_data_file, 
title,gnuplot_output_filename,mode,disk_perf):
+def compute_math(fio_data_file, 
title,gnuplot_output_filename,gnuplot_output_dir,mode,disk_perf,gpm_dir):
+    print "Computing Maths"
      global_min=[]
      global_max=[]
-    average_file=open(gnuplot_output_filename+'.average', 'w')
-    min_file=open(gnuplot_output_filename+'.min', 'w')
-    max_file=open(gnuplot_output_filename+'.max', 'w')
-    stddev_file=open(gnuplot_output_filename+'.stddev', 'w')
-    global_file=open(gnuplot_output_filename+'.global','w')
+ 
average_file=open(gnuplot_output_dir+gnuplot_output_filename+'.average', 
'w')
+ min_file=open(gnuplot_output_dir+gnuplot_output_filename+'.min', 'w')
+ max_file=open(gnuplot_output_dir+gnuplot_output_filename+'.max', 'w')
+ stddev_file=open(gnuplot_output_dir+gnuplot_output_filename+'.stddev', 
'w')
+ global_file=open(gnuplot_output_dir+gnuplot_output_filename+'.global','w')

      min_file.write('DiskName %s\n' % mode)
      max_file.write('DiskName %s\n'% mode)
@@ -195,14 +253,14 @@ def compute_math(fio_data_file, 
title,gnuplot_output_filename,mode,disk_perf):
      stddev_file.close()
      global_file.close()
      try:
-        os.remove('mymath')
+        os.remove(gnuplot_output_dir+'mymath')
      except:
          True

-    generate_gnuplot_math_script("Average values of 
"+title,gnuplot_output_filename+'.average',mode,int(avg))
-    generate_gnuplot_math_script("Min values of 
"+title,gnuplot_output_filename+'.min',mode,average(global_min))
-    generate_gnuplot_math_script("Max values of 
"+title,gnuplot_output_filename+'.max',mode,average(global_max))
-    generate_gnuplot_math_script("Standard Deviation of 
"+title,gnuplot_output_filename+'.stddev',mode,int(standard_deviation))
+    generate_gnuplot_math_script("Average values of 
"+title,gnuplot_output_filename+'.average',mode,int(avg),gnuplot_output_dir,gpm_dir)
+    generate_gnuplot_math_script("Min values of 
"+title,gnuplot_output_filename+'.min',mode,average(global_min),gnuplot_output_dir,gpm_dir)
+    generate_gnuplot_math_script("Max values of 
"+title,gnuplot_output_filename+'.max',mode,average(global_max),gnuplot_output_dir,gpm_dir)
+    generate_gnuplot_math_script("Standard Deviation of 
"+title,gnuplot_output_filename+'.stddev',mode,int(standard_deviation),gnuplot_output_dir,gpm_dir)

  def parse_global_files(fio_data_file, global_search):
      max_result=0
@@ -249,17 +307,28 @@ def parse_global_files(fio_data_file, global_search):
      else:
          print "Global search %s is not yet implemented\n" % global_search

-def render_gnuplot():
-    print "Running gnuplot Rendering\n"
+def render_gnuplot(fio_data_file, gnuplot_output_dir):
+    print "Running gnuplot Rendering"
      try:
-        os.system("gnuplot mymath")
-        os.system("gnuplot mygraph")
+        # Let's render all the compared files if some
+        if len(fio_data_file) > 1:
+            print " |-> Rendering comparing traces"
+            os.system("cd %s; for i in *.gnuplot; do gnuplot $i; done" 
% gnuplot_output_dir)
+        print " |-> Rendering math traces"
+        os.system("cd %s; gnuplot mymath" % gnuplot_output_dir)
+        print " |-> Rendering 2D & 3D traces"
+        os.system("cd %s; gnuplot mygraph" % gnuplot_output_dir)
+
+        name_of_directory="the current"
+        if gnuplot_output_dir != "./":
+            name_of_directory=gnuplot_output_dir
+        print "\nRendering traces are available in %s directory" % 
name_of_directory
      except:
          print "Could not run gnuplot on mymath or mygraph !\n"
          sys.exit(1);

  def print_help():
-    print 'fio2gnuplot.py -ghbio -t <title> -o <outputfile> -p <pattern>'
+    print 'fio2gnuplot.py -ghbiod -t <title> -o <outputfile> -p 
<pattern> -G <type>'
      print
      print '-h --help                           : Print this help'
      print '-p <pattern> or --pattern <pattern> : A pattern in regexp 
to select fio input files'
@@ -268,6 +337,7 @@ def print_help():
      print '-g           or --gnuplot           : Render gnuplot traces 
before exiting'
      print '-o           or --outputfile <file> : The basename for 
gnuplot traces'
      print '                                       - Basename is set 
with the pattern if defined'
+    print '-d           or --outputdir <dir>   : The directory where 
gnuplot shall render files'
      print '-t           or --title <title>     : The title of the 
gnuplot traces'
      print '                                       - Title is set with 
the block size detected in fio traces'
      print '-G        or --Global <type>     : Search for <type> in 
.global files match by a pattern'
@@ -280,13 +350,21 @@ def main(argv):
      pattern_set_by_user=False
      title='No title'
      gnuplot_output_filename='result'
+    gnuplot_output_dir='./'
+    gpm_dir="/usr/share/fio/"
      disk_perf=[]
      run_gnuplot=False
      parse_global=False
      global_search=''

+    if not os.path.isfile(gpm_dir+'math.gpm'):
+        gpm_dir="/usr/local/share/fio/"
+            if not os.path.isfile(gpm_dir+'math.gpm'):
+            print "Looks like fio didn't got installed properly as no 
gpm files found in '/usr/share/fio' or '/usr/local/share/fio'\n"
+            sys.exit(3)
+
      try:
-        opts, args = getopt.getopt(argv[1:],"ghbio:t:p:G:")
+        opts, args = getopt.getopt(argv[1:],"ghbio:d:t:p:G:")
      except getopt.GetoptError:
       print_help()
           sys.exit(2)
@@ -302,6 +380,12 @@ def main(argv):
       pattern=pattern.replace('\\','')
        elif opt in ("-o", "--outputfile"):
           gnuplot_output_filename=arg
+      elif opt in ("-d", "--outputdir"):
+         gnuplot_output_dir=arg
+     if not gnuplot_output_dir.endswith('/'):
+        gnuplot_output_dir=gnuplot_output_dir+'/'
+     if not os.path.exists(gnuplot_output_dir):
+        os.makedirs(gnuplot_output_dir)
        elif opt in ("-t", "--title"):
           title=arg
        elif opt in ("-g", "--gnuplot"):
@@ -322,10 +406,12 @@ def main(argv):
      if len(fio_data_file) == 0:
          print "No log file found with pattern %s!" % pattern
          sys.exit(1)
+    else:
+        print "%d files Selected with pattern '%s'" % 
(len(fio_data_file), pattern)

      fio_data_file=sorted(fio_data_file, key=str.lower)
      for file in fio_data_file:
-    print 'Selected %s' % file
+    print ' |-> %s' % file
      if "_bw.log" in file :
          mode="Bandwidth (KB/sec)"
      if "_iops.log" in file :
@@ -336,6 +422,7 @@ def main(argv):
          if "IO" in mode:
              title='IO benchmark with %d fio results' % len(fio_data_file)

+    print
      #We need to adjust the output filename regarding the pattern 
required by the user
      if (pattern_set_by_user == True):
          gnuplot_output_filename=pattern
@@ -352,14 +439,14 @@ def main(argv):
      if parse_global==True:
      parse_global_files(fio_data_file, global_search)
      else:
-        blk_size=compute_temp_file(fio_data_file,disk_perf)
+ blk_size=compute_temp_file(fio_data_file,disk_perf,gnuplot_output_dir)
          title="%s @ Blocksize = %dK" % (title,blk_size/1024)
-        compute_aggregated_file(fio_data_file, gnuplot_output_filename)
- compute_math(fio_data_file,title,gnuplot_output_filename,mode,disk_perf)
- 
generate_gnuplot_script(fio_data_file,title,gnuplot_output_filename,mode,disk_perf)
+        compute_aggregated_file(fio_data_file, gnuplot_output_filename, 
gnuplot_output_dir)
+ 
compute_math(fio_data_file,title,gnuplot_output_filename,gnuplot_output_dir,mode,disk_perf,gpm_dir)
+ 
generate_gnuplot_script(fio_data_file,title,gnuplot_output_filename,gnuplot_output_dir,mode,disk_perf,gpm_dir)

          if (run_gnuplot==True):
-            render_gnuplot()
+            render_gnuplot(fio_data_file, gnuplot_output_dir)

      # Cleaning temporary files
      try:


[-- Attachment #2: compare-vm1-1-4m-vdb-read-para.results_-_bw-2Dsmooth.png --]
[-- Type: image/png, Size: 11792 bytes --]

[-- Attachment #3: compare-vm1-1-4m-vdb-read-para.results_-_bw-2Draw.png --]
[-- Type: image/png, Size: 22335 bytes --]

[-- Attachment #4: compare-vm1-1-4m-vdb-read-para.results_-_bw-2Dtrend.png --]
[-- Type: image/png, Size: 8676 bytes --]

  reply	other threads:[~2013-07-31 10:36 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-30 12:08 [Pull Request] Updating tools Erwan Velu
2013-07-31 10:36 ` Erwan Velu [this message]
2013-07-31 18:35   ` Jens Axboe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51F8E89E.4060208@enovance.com \
    --to=erwan@enovance.com \
    --cc=fio@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.