[GRASS-dev] [GRASS GIS] #2033: Moving g.pnmcomp to lib/display to improve render performance of wxGUI

GRASS GIS trac at osgeo.org
Tue Jul 23 15:27:16 PDT 2013


#2033: Moving g.pnmcomp to lib/display to improve render performance of wxGUI
----------------------------------------------+-----------------------------
 Reporter:  huhabla                           |       Owner:  grass-dev@…              
     Type:  enhancement                       |      Status:  new                      
 Priority:  major                             |   Milestone:  7.0.0                    
Component:  wxGUI                             |     Version:  svn-trunk                
 Keywords:  display, Python, multiprocessing  |    Platform:  All                      
      Cpu:  All                               |  
----------------------------------------------+-----------------------------

Comment(by huhabla):

 I have improved the benchmark script and implemented PIL based and
 g.pnmcomp image composition (without transparency). Now png, bmp and ppm
 images are created and mmap is enabled for bmp images. Time is measured
 for the whole rendering/composition process and separately for the
 composition.
 My test system is a core-i5 2410M with 8GB RAM and 320Gig HD running
 Ubuntu 12.04 LTS.

 It seems to me that creating raw bmp images without mmap enabled shows the
 best performance for the PNG and Cairo driver. Maybe i did something
 wrong, but the use of mmap shows no obvious benefit?
 The png compression slows the rendering significantly down and is IMHO not
 well suited as image exchange format in the rendering/composition process.

 Running the render processes in parallel shows only for the 4096x4096
 pixel size images a significant benefit.

 Any suggestions to improve the benchmark? Does my setup produce reasonable
 results?

 Here the script:

 {{{
 # -*- coding: utf-8 -*-
 import os
 import time
 import Image
 import wx
 from grass.pygrass import modules

 parallel = [True, False]
 drivers = ["png", "cairo"]
 bitmaps = ["png", "bmp", "ppm"]
 mmap_modes = ["FALSE", "TRUE"]
 sizes = [1024, 4096]

 ############################################################################

 def render_image(module, driver="png", pngfile="test.png",
                  size=4096, mapped="TRUE"):
     os.putenv("GRASS_RENDER_IMMEDIATE", "%s"%driver)
     os.putenv("GRASS_PNGFILE", "%s"%pngfile)
     os.putenv("GRASS_WIDTH", "%i"%size)
     os.putenv("GRASS_HEIGHT", "%i"%size)
     os.putenv("GRASS_PNG_MAPPED", "%s"%mapped)
     module.run()

 ############################################################################

 def composite_images(files, bitmap, mode, size):
     start = time.time()
     if bitmap == "ppm":
         filename = "output"
         filename += ".ppm"
         modules.Module("g.pnmcomp", input=files, width=size, height=size,
                        output=filename)
         # Load the image as wx image for visualization
         img = wx.Image(filename, wx.BITMAP_TYPE_ANY)
         os.remove(filename)
     else:
         images = []
         size = None
         for m in files:
             im = Image.open(m)
             images.append(im)
             size = im.size
         comp = Image.new('RGB', size)
         for im in images:
             comp.paste(im)
         wxImage = wx.EmptyImage(*comp.size)
         wxImage.SetData(comp.convert('RGB').tostring())

     return (time.time() - start)

 ############################################################################

 def main():
     # Set the region
     modules.Module("g.region", rast="elevation", flags="p")

     for finish in parallel:
         if finish:
             print("*** Serial runs")
         else:
             print("*** Parallel runs")

         print("Run\tSize\tDriver\tBitmap\tmmap\trender\tcomposite")

         # Setup the modules
         rast   = modules.Module("d.rast", map="elevation", run_=False,
                                 quiet=True, finish_=False)
         vectB = modules.Module("d.vect", map="streams", width=1,
 color="blue",
                                 fcolor="aqua", type=["area","line"],
                                 run_=False, quiet=True, finish_=finish)
         vectA = modules.Module("d.vect", map="roadsmajor", width=2,
                                run_=False, quiet=True, finish_=finish)

         count = 0
         for size in sizes:
             for driver in drivers:
                 for bitmap in bitmaps:
                     for mode in mmap_modes:
                         # Skip mmap for non-bmp files
                         if mode == "TRUE" and bitmap != "bmp":
                             continue

                         start = time.time()
                         count += 1
                         files = []

                         rast_file = "rast.%s"%(bitmap)
                         vectA_file="vectA.%s"%(bitmap)
                         vectB_file="vectB.%s"%(bitmap)

                         files.append(rast_file)
                         files.append(vectA_file)
                         files.append(vectB_file)

                         render_image(rast, driver=driver,
                                      pngfile=rast_file,
                                      size=size, mapped=mode)

                         render_image(vectA, driver=driver,
                                      pngfile=vectA_file,
                                      size=size, mapped=mode)

                         render_image(vectB, driver=driver,
                                      pngfile=vectB_file,
                                      size=size, mapped=mode)

                         # Wait for processes
                         rast.popen.wait()
                         vectA.popen.wait()
                         vectB.popen.wait()

                         # Composite the images
                         comptime = composite_images(files, bitmap, mode,
                                                     size)

                         for file in files:
                             os.remove(file)

                         elapsed = (time.time() - start)
                         print("%i\t%i\t%s\t%s\t%s\t%.2f\t%.2f"%(count,
 size,
                                                                 driver,
 bitmap,
                                                                 mode,
 elapsed,
                                                                 comptime))

 ############################################################################

 main()
 }}}

 Here the benchmark results:

 {{{
 GRASS 7.0.svn (nc_spm_08_grass7):~/src > python display_bench.py
 projection: 99 (Lambert Conformal Conic)
 zone:       0
 datum:      nad83
 ellipsoid:  a=6378137 es=0.006694380022900787
 north:      228500
 south:      215000
 west:       630000
 east:       645000
 nsres:      10
 ewres:      10
 rows:       1350
 cols:       1500
 cells:      2025000
 *** Serial runs
 Run     Size    Driver  Bitmap  mmap    render  composite
 1       1024    png     png     FALSE   0.87    0.11
 2       1024    png     bmp     FALSE   0.45    0.03
 3       1024    png     bmp     TRUE    0.48    0.03
 4       1024    png     ppm     FALSE   0.47    0.07
 5       1024    cairo   png     FALSE   0.93    0.09
 6       1024    cairo   bmp     FALSE   0.52    0.03
 7       1024    cairo   bmp     TRUE    0.56    0.03
 8       1024    cairo   ppm     FALSE   0.61    0.06
 9       4096    png     png     FALSE   4.74    1.29
 10      4096    png     bmp     FALSE   3.43    0.38
 11      4096    png     bmp     TRUE    4.15    0.38
 12      4096    png     ppm     FALSE   3.04    0.55
 13      4096    cairo   png     FALSE   3.68    0.99
 14      4096    cairo   bmp     FALSE   1.95    0.37
 15      4096    cairo   bmp     TRUE    2.65    0.37
 16      4096    cairo   ppm     FALSE   3.44    0.55
 *** Parallel runs
 Run     Size    Driver  Bitmap  mmap    render  composite
 1       1024    png     png     FALSE   0.92    0.11
 2       1024    png     bmp     FALSE   0.50    0.03
 3       1024    png     bmp     TRUE    0.48    0.03
 4       1024    png     ppm     FALSE   0.51    0.07
 5       1024    cairo   png     FALSE   0.98    0.08
 6       1024    cairo   bmp     FALSE   0.53    0.03
 7       1024    cairo   bmp     TRUE    0.60    0.03
 8       1024    cairo   ppm     FALSE   0.67    0.07
 9       4096    png     png     FALSE   4.77    1.33
 10      4096    png     bmp     FALSE   3.08    0.37
 11      4096    png     bmp     TRUE    3.74    0.38
 12      4096    png     ppm     FALSE   2.84    0.55
 13      4096    cairo   png     FALSE   3.38    1.01
 14      4096    cairo   bmp     FALSE   1.82    0.37
 15      4096    cairo   bmp     TRUE    2.44    0.37
 16      4096    cairo   ppm     FALSE   2.93    0.55
 }}}

-- 
Ticket URL: <http://trac.osgeo.org/grass/ticket/2033#comment:6>
GRASS GIS <http://grass.osgeo.org>



More information about the grass-dev mailing list