hp2ps [flags] [<file>[.hp]]
The program hp2ps converts a heap profile as produced by the -h<break-down> runtime option into a PostScript graph of the heap profile. By convention, the file to be processed by hp2ps has a .hp extension. The PostScript output is written to <file>@.ps. If <file> is omitted entirely, then the program behaves as a filter.
hp2ps is distributed in ghc/utils/hp2ps in a GHC source distribution. It was originally developed by Dave Wakeling as part of the HBC/LML heap profiler.
The flags are:
In order to make graphs more readable, hp2ps sorts the shaded bands for each identifier. The default sort ordering is for the bands with the largest area to be stacked on top of the smaller ones. The -d option causes rougher bands (those representing series of values with the largest standard deviations) to be stacked on top of smoother ones.
Normally, hp2ps puts the title of the graph in a small box at the top of the page. However, if the JOB string is too long to fit in a small box (more than 35 characters), then hp2ps will choose to use a big box instead. The -b option forces hp2ps to use a big box.
Generate encapsulated PostScript suitable for inclusion in LaTeX documents. Usually, the PostScript graph is drawn in landscape mode in an area 9 inches wide by 6 inches high, and hp2ps arranges for this area to be approximately centred on a sheet of a4 paper. This format is convenient of studying the graph in detail, but it is unsuitable for inclusion in LaTeX documents. The -e option causes the graph to be drawn in portrait mode, with float specifying the width in inches, millimetres or points (the default). The resulting PostScript file conforms to the Encapsulated PostScript (EPS) convention, and it can be included in a LaTeX document using Rokicki's dvi-to-PostScript converter dvips.
Create output suitable for the gs PostScript previewer (or similar). In this case the graph is printed in portrait mode without scaling. The output is unsuitable for a laser printer.
Normally a profile is limited to 20 bands with additional identifiers being grouped into an OTHER band. The -l flag removes this 20 band and limit, producing as many bands as necessary. No key is produced as it won't fit!. It is useful for creation time profiles with many bands.
Normally a profile is limited to 20 bands with additional identifiers being grouped into an OTHER band. The -m flag specifies an alternative band limit (the maximum is 20).
-m0 requests the band limit to be removed. As many bands as necessary are produced. However no key is produced as it won't fit! It is useful for displaying creation time profiles with many bands.
Use previous parameters. By default, the PostScript graph is automatically scaled both horizontally and vertically so that it fills the page. However, when preparing a series of graphs for use in a presentation, it is often useful to draw a new graph using the same scale, shading and ordering as a previous one. The -p flag causes the graph to be drawn using the parameters determined by a previous run of hp2ps on file. These are extracted from file@.aux.
Use a small box for the title.
Normally trace elements which sum to a total of less than 1% of the profile are removed from the profile. The -t option allows this percentage to be modified (maximum 5%).
-t0 requests no trace elements to be removed from the profile, ensuring that all the data will be displayed.
Generate colour output.
Print out usage information.
(Notes kindly offered by Jan-Willhem Maessen.)
The FOO.hp file produced when you ask for the heap profile of a program FOO is a text file with a particularly simple structure. Here's a representative example, with much of the actual data omitted:
JOB "FOO -hC" DATE "Thu Dec 26 18:17 2002" SAMPLE_UNIT "seconds" VALUE_UNIT "bytes" BEGIN_SAMPLE 0.00 END_SAMPLE 0.00 BEGIN_SAMPLE 15.07 ... sample data ... END_SAMPLE 15.07 BEGIN_SAMPLE 30.23 ... sample data ... END_SAMPLE 30.23 ... etc. BEGIN_SAMPLE 11695.47 END_SAMPLE 11695.47
You can look at particular regions of your profile simply by loading a copy of the .hp file into a text editor and deleting the unwanted samples. The resulting .hp file can be run through hp2ps and viewed or printed.
The .hp file is generated incrementally as your program runs. In principle, running hp2ps on the incomplete file should produce a snapshot of your program's heap usage. However, the last sample in the file may be incomplete, causing hp2ps to fail. If you are using a machine with UNIX utilities installed, it's not too hard to work around this problem (though the resulting command line looks rather Byzantine):
head -`fgrep -n END_SAMPLE FOO.hp | tail -1 | cut -d : -f 1` FOO.hp \ | hp2ps > FOO.ps
The gv and ghostview programs have a "watch file" option can be used to view an up-to-date heap profile of your program as it runs. Simply generate an incremental heap profile as described in the previous section. Run gv on your profile:
gv -watch -seascape FOO.ps
This can all be encapsulated in a little script:
#!/bin/sh head -`fgrep -n END_SAMPLE FOO.hp | tail -1 | cut -d : -f 1` FOO.hp \ | hp2ps > FOO.ps gv -watch -seascape FOO.ps & while [ 1 ] ; do sleep 10 # We generate a new profile every 10 seconds. head -`fgrep -n END_SAMPLE FOO.hp | tail -1 | cut -d : -f 1` FOO.hp \ | hp2ps > FOO.ps done
#!/bin/sh head -`fgrep -n END_SAMPLE FOO.hp | tail -1 | cut -d : -f 1` FOO.hp \ | hp2ps > FOO.ps gv FOO.ps & gvpsnum=$! while [ 1 ] ; do sleep 10 head -`fgrep -n END_SAMPLE FOO.hp | tail -1 | cut -d : -f 1` FOO.hp \ | hp2ps > FOO.ps kill -HUP $gvpsnum done