Number: 1230
Title: Neato Maps in 2.16 on Sparc Solaris Not Layed out correctly
Submitter: Michael Mueller
Date: Mon Nov 12 22:10:49 2007
Subsys: Neato
Version: 2.16
System: Sparc-Solaris-2.8
Severity: major
Problem:
I have an issue with the layout from Neato when I compile it on our Sparc machine.

When it draws even a simple test dot file it lays out the graph in a seemingly haphazard way. See examples below, When I try it under cygwin (graphviz 2.8) it seems OK, Not sure what I can check, I am using the latest PNG and JPG libraries and freetype2 I'm outputting in svg but the problem persists in any output format.

command used for example /opt/graphviz/bin/neato -Tpng test.dot -o ONE.png

Only thing I can think of is if a default setting has changed in Neato with this version?

BTW I did try the 2.8 version it draws the smaller graphs like the one in the example OK but on larger graphs with some Orphaned nodes and branches it seems to place them around the circumference of the diagram in a circular fashion. Again this was only an issue on the Sun Machine and it laid out OK under cygwin.

Thanks for you assistance.
Input:

graph G{
run--intr;
intr--runbl;
runbl--run;
run--kernel;
kernel--zombie;
kernel--sleep;
kernel--runmem;
sleep--swap;
swap--runswap;
runswap--new;
runswap--runmem;
new--runmem;
sleep--runmem;
}
Output file: b1230.png
Comments:
[erg] Unfortunately, neato runs fine on your graph using our Solaris machine, so it is going to be hard for us to determine what is going wrong. You might try running neato -v on your file and sending out the log. Also, it may be helpful to know how you built Graphviz, i.e., what options did you use when you ran

[michael] Here is the configure I ran (the /opt/imagelibs directory contains the latest versions of png jpeg and freetype libraries.)


./configure --with-jpeglibdir=/opt/imagelibs/lib
--with-jpegincludedir=/opt/imagelibs/include
--with-pngincludedir=/opt/imagelibs/include
--with-pnglibdir=/opt/imagelibs/lib  --with-mylibgd=no
--with-freetype2=/opt/imagelibs/lib/ --prefix=/opt/graphviz

neato -v shows


 /opt/graphviz/bin/neato -v
Activated plugin library: libgvplugin_neato_layout.so.5
Using layout: neato:neato_layout
Activated plugin library: libgvplugin_core.so.5
Using render: dot:core
Using device: dot:dot:core
The plugin configuration file:
        /opt/graphviz/lib/graphviz/config
                was successfully loaded.
    render      :  dot fig gd map ps svg vml vrml xdot
    layout      :  circo dot fdp neato nop nop1 nop2 twopi
    textlayout  :
    device      :  canon cmap cmapx cmapx_np dia dot fig gd gd2 gif hpgl
imap imap_np ismap jpe jpeg jpg mif mp pcl pic plain plain-ext png ps ps2
svg svgz vml vmlz vrml vtx wbmp xdot
    loadimage   :  (lib) gd gd2 gif jpe jpeg jpg png ps

it didn't exit by itself after quite some time so not sure if it is complete.

[north] I wonder if the layout is OK but there are scaling issues (font problems?)

The layout is obviously not "totally random" as was suggested. This is crucial to understanding what actually went wrong.

[michael] What steps could I take to determine if it is a Font issue.

I didn't specifically use fontconfig in the configure params, I am not really sure how fontconfig fits in with the standard Solaris font handling.

[north] run dot -v


> I didn't specifically use fontconfig in the configure params, I am not
> really sure how fontconfig fits in with the standard Solaris font handling.
>
>

I doubt you have fontconfig unless you installed it.

That being said, I wonder if we have a scaling error (e.g. 96/72) when we fall back to internal font sizing.

[ellson] There are no textlayout plugins, so it is using some internal font metrics. I'm not sure if this is actually the cause of the problem you are seeing, but you will get better layouts if you install: fontconfig, cairo, pango.


   http://fontconfig.org/
   http://cairographics.org/
   http://www.pango.org/   Your version of gd has not been built with fontconfig either, so you should rebuild it too.

BTW. You would save yourself a lot of configure options if you installed graphviz in a common prefix with all the other packages, e.g. /opt/imagelibs <prefix>/lib and <prefix>/include are automatically searched for all libs/headers.


> it didn't exit by itself after quite some time so not sure if it is
> complete.

If there is no input file on the command line, dot reads input from stdin, so it is just waiting for input. Use <ctrl>D to provide an EOF.

[erg] As John noted, neato is waiting for some input. Please try running neato -v on your graph file and sending us that log.

[michael] Here is the result of using -v option

I recompiled again using some different options as I had been playing around trying to compile fontconfig etc with out luck and had it stopped graphviz building

./configure --with-freetype2=no --with-fontconfig=no --prefix=/opt/imagelibs --with-gdk-pixbuf=no

The output is the same as before.


/opt/imagelibs/bin/neato -v -Tsvg test.dot -o ONE.svg

Activated plugin library: libgvplugin_neato_layout.so.5 Using layout: neato:neato_layout Activated plugin library: libgvplugin_core.so.5 Using render: svg:core Using device: svg:svg:core The plugin configuration file: /opt/imagelibs/lib/graphviz/config was successfully loaded. render : dot fig gd map ps svg vml vrml xdot layout : circo dot fdp neato nop nop1 nop2 twopi textlayout : device : canon cmap cmapx cmapx_np dia dot fig gd gd2 gif hpgl imap imap_np ismap jpe jpeg jpg mif mp pcl pic plain plain-ext png ps ps2 svg svgz vml vmlz vrml vtx wbmp xdot loadimage : (lib) gd gd2 gif jpe jpeg jpg png ps neato: fontname "Times-Roman" resolved to: [internal times] Scanning graph _neato_cc0, 10 nodes model 0 smart_init 0 iterations 200 tol 0.000100 convert graph: 10 nodes 0.00 sec Calculating shortest paths: 0.00 sec Setting initial positions: 0.00 sec: 0.00 sec Setting up stress function: 0.00 sec Solving model: 22.611 final e = 12.222097 1 iterations 0.00 sec Creating edges using line segments Using render: svg:core Using device: svg:svg:core

[michael] Stephen, here is the result of using the KK option.

Command /opt/imagelibs/bin/neato -Gmode=KK -v -Tpng test.dot -o ONE.png


Activated plugin library: libgvplugin_neato_layout.so.5
Using layout: neato:neato_layout
Activated plugin library: libgvplugin_gd.so.5
Using render: gd:gd
Using device: png:gd:gd
The plugin configuration file:
        /opt/imagelibs/lib/graphviz/config
                was successfully loaded.
    render      :  dot fig gd map ps svg vml vrml xdot
    layout      :  circo dot fdp neato nop nop1 nop2 twopi
    textlayout  :
    device      :  canon cmap cmapx cmapx_np dia dot fig gd gd2 gif hpgl
imap imap_np ismap jpe jpeg jpg mif mp pcl pic plain plain-ext png ps ps2
svg svgz vml vmlz vrml vtx wbmp xdot
    loadimage   :  (lib) gd gd2 gif jpe jpeg jpg png ps
neato: fontname "Times-Roman" resolved to: [internal times]
Scanning graph G, 10 nodes
Calculating shortest paths: 0.00 sec
Setting initial positions
Setting up spring model: 0.00 sec
Solving model 0 iterations 1000 tol 0.001000
 energy tolerance

final e = 22.610892 0 iterations 0.00 sec Creating edges using line segments Using render: gd:gd Using device: png:gd:gd neato: allocating a 27K PaletteColor GD image

[erg] Well, the immediate cause of the bad layout is obvious:


mmuell24@csc.com.au wrote:
>
>
> /opt/imagelibs/bin/neato -v -Tsvg test.dot -o ONE.svg
>
> Activated plugin library: libgvplugin_neato_layout.so.5
>
....
> neato: fontname "Times-Roman" resolved to: [internal times]
> Scanning graph _neato_cc0, 10 nodes
> model 0 smart_init 0 iterations 200 tol 0.000100
> convert graph: 10 nodes 0.00 sec
> Calculating shortest paths: 0.00 sec
> Setting initial positions: 0.00 sec: 0.00 sec
> Setting up stress function: 0.00 sec
> Solving model: 22.611
> final e = 12.222097 1 iterations 0.00 sec
With just 1 iteration, the nodes have been placed randomly, jiggled a tad, and then the program stops.

Also, in response to Stephen's request to try mode=KK, you got


> final e = 22.610892 0 iterations 0.00 sec

So, now the question is, why is neato stopping prematurely?

A separate issue is the fact that dot is not finding a Times-Roman font, but since you are building without freetype, you will necessarily get the libgd default fonts.

[michael] I am running gnu make and gcc

I did as you suggested and ran doit which contained this command

gcc -DHAVE_CONFIG_H -I. -I../.. -I../.. -I../../lib/common -I../../lib/gvc -I../../lib/pack -I../../lib/pathplan -I../../lib/graph -I../../lib/cdt -I../../lib/vpsc -I/opt/imagelibs/in clude -g -O2 -Wno-unused-parameter -Wno-unknown-pragmas -Wstrict-prototypes -Wpointer-arith -Wall -ffast-math -MT stuff.o -MD -MP -MF .deps/stuff.Tpo -E -o stuff.o stuff.c mv -f .deps/stuff.Tpo .deps/stuff.Po

however it only created/update the stuff.o file ls -ltr .... -rw-r--r-- 1 mmuell24 nmsadms 761 Nov 16 13:38 libneatogen_C.la -rw-r--r-- 1 mmuell24 nmsadms 394 Nov 19 07:49 doit~ -rwxr-xr-x 1 mmuell24 nmsadms 394 Nov 19 07:50 doit -rw-r--r-- 1 mmuell24 nmsadms 115249 Nov 19 07:50 stuff.o

A search of the entire source tree did not show a stuff.i file? maybe that is cc specific.

I have attatched the stuff.o file in anycase.

[erg] Okay, that shot down my theory, though I still think I'm on the right track.

Please, when you get time, would you add the line

fprintf (stderr, "%f %f %fn", e, save_e, fabs((e - save_e) / save_e));

after line 554 in lib/neatogen/stuff.c

[michael] Here is the ouput,


/opt/imagelibs/bin/neato -Gmode=KK -v -Tpng test.dot -o ONE.png
Activated plugin library: libgvplugin_neato_layout.so.5
Using layout: neato:neato_layout
Activated plugin library: libgvplugin_gd.so.5
Using render: gd:gd
Using device: png:gd:gd
The plugin configuration file:
        /opt/imagelibs/lib/graphviz/config
                was successfully loaded.
    render      :  dot fig gd map ps svg vml vrml xdot
    layout      :  circo dot fdp neato nop nop1 nop2 twopi
    textlayout  :
    device      :  canon cmap cmapx cmapx_np dia dot fig gd gd2 gif hpgl
imap im                         ap_np ismap jpe jpeg jpg mif mp pcl pic
plain plain-ext png ps ps2 svg svgz vml                          vmlz vrml
vtx wbmp xdot
    loadimage   :  (lib) gd gd2 gif jpe jpeg jpg png ps
neato: fontname "Times-Roman" resolved to: [internal times]
Scanning graph G, 10 nodes
Calculating shortest paths: 0.00 sec
Setting initial positions
Setting up spring model: 0.00 sec
Solving model 0 iterations 1000 tol 0.001000
22.610892
1797693134862315708145274237317043567980705675258449965989174768031572
60780028538760589558632766878171540458953514382464234321326889464182768467546703

53751698604991057655128207624549009038932894407586850845513394230458323690322294

8165808559332123348274797826204144723168738177180919299881250404026184124858368. 000000 0.000000 energy tolerance

final e = 22.610892 0 iterations 0.00 sec Creating edges using line segments Using render: gd:gd Using device: png:gd:gd neato: allocating a 27K PaletteColor GD image

[erg] So what this shows is that we have e = 22.610892, save_e = MAXDOUBLE, but fabs((e - save_e)/save_e) = 0, hence neato stops. A similar situation is must be occurring with stress majorization. The obvious bug is that fabs is not declared to be returning a double, but the output of cc -E on stuff.c show that fabs() is properly declared.

On the surface, this appears to be compiler/linker bug. As a simple test, Michael should try compiling and running


#include <math.h>

main () { static double save_e = 1.7976931348623157e+308; double e = 22.610892;

if (fabs((e - save_e) / save_e) < 1e-5) printf ("badn"); else printf ("goodn"); }

to see if this triggers the bug.

[michael] Thanks Emden, it gives me something to work with, the GCC version is 3.2 and it was not generating any errors. I will try a later version of GCC and see how I go. I will tell you the results.

[michael]


nmsadmin@cscsydhnms56 ~> gcc -v  test.c
Reading specs from /usr/local/lib/gcc/sparc-sun-solaris2.8/3.4.6/specs
Configured with: ../configure --with-as=/usr/ccs/bin/as
--with-ld=/usr/ccs/bin/ld --enable-shared --enable-languages=c,c++,f77
Thread model: posix
gcc version 3.4.6
 /usr/local/libexec/gcc/sparc-sun-solaris2.8/3.4.6/cc1 -quiet -v test.c
-quiet -dumpbase test.c -mcpu=v7 -auxbase test -version -o
/var/tmp//ccAcC4TD.s
ignoring nonexistent directory "NONE/include"
ignoring nonexistent directory
"/usr/local/lib/gcc/sparc-sun-solaris2.8/3.4.6
/../../../../sparc-sun-solaris2.8/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/local/lib/gcc/sparc-sun-solaris2.8/3.4.6/include
 /usr/include
End of search list.
GNU C version 3.4.6 (sparc-sun-solaris2.8)
        compiled by GNU C version 3.3.2.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
 /usr/ccs/bin/as -V -Qy -s -xarch=v8 -o /var/tmp//ccgjetYj.o
/var/tmp//ccAcC4TD.s
/usr/ccs/bin/as: Sun WorkShop 6 2003/12/18 Compiler Common 6.0 Patch
114802-02
 /usr/local/libexec/gcc/sparc-sun-solaris2.8/3.4.6/collect2 -V -Y
P,/usr/ccs/lib:/usr/lib -Qy /usr/local/lib/gcc/sparc-sun-solaris2.8/3.4.6
/crt1.o /usr/local/lib/gcc/sparc-sun-solaris2.8/3.4.6/crti.o
/usr/ccs/lib/values-Xa.o /usr/local/lib/gcc/sparc-sun-solaris2.8/3.4.6
/crtbegin.o -L/usr/local/lib/gcc/sparc-sun-solaris2.8/3.4.6 -L/usr/ccs/bin
-L/usr/ccs/lib -L/usr/local/lib/gcc/sparc-sun-solaris2.8/3.4.6/../../..
/var/tmp//ccgjetYj.o -lgcc -lgcc_eh -lc -lgcc -lgcc_eh -lc
/usr/local/lib/gcc/sparc-sun-solaris2.8/3.4.6/crtend.o
/usr/local/lib/gcc/sparc-sun-solaris2.8/3.4.6/crtn.o
ld: Software Generation Utilities - Solaris Link Editors: 5.8-1.301
nmsadmin@cscsydhnms56 ~> ./a.out
good

then

/doit Reading specs from /usr/local/lib/gcc/sparc-sun-solaris2.8/3.4.6/specs Configured with: ../configure --with-as=/usr/ccs/bin/as --with-ld=/usr/ccs/bin/ld --enable-shared --enable-languages=c,c++,f77 Thread model: posix gcc version 3.4.6 /usr/local/libexec/gcc/sparc-sun-solaris2.8/3.4.6/cc1 -quiet -v -I. -I../.. -I../.. -I../../lib/common -I../../lib/gvc -I../../lib/pack -I../../lib/pathplan -I../../lib/graph -I../../lib/cdt -I../../lib/vpsc -I/opt/graphviz/include -MD stuff.d -MF .deps/stuff.Tpo -MP -MT stuff.o -MQ stuff.o -DHAVE_CONFIG_H stuff.c -quiet -dumpbase stuff.c -mcpu=v7 -auxbase-strip stuff.o -g -O2 -Wno-unused-parameter -Wno-unknown-pragmas -Wstrict-prototypes -Wpointer-arith -Wall -version -ffast-math -o /var/tmp//ccbZN0H9.s ignoring nonexistent directory "NONE/include" ignoring nonexistent directory "/usr/local/lib/gcc/sparc-sun-solaris2.8/3.4.6 /../../../../sparc-sun-solaris2.8/include" ignoring duplicate directory "../.." #include "..." search starts here: #include <...> search starts here: . ../.. ../../lib/common ../../lib/gvc ../../lib/pack ../../lib/pathplan ../../lib/graph ../../lib/cdt ../../lib/vpsc /opt/graphviz/include /usr/local/include /usr/local/lib/gcc/sparc-sun-solaris2.8/3.4.6/include /usr/include End of search list. GNU C version 3.4.6 (sparc-sun-solaris2.8) compiled by GNU C version 3.3.2. GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 /usr/ccs/bin/as -V -Qy -s -xarch=v8 -o stuff.o /var/tmp//ccbZN0H9.s /usr/ccs/bin/as: Sun WorkShop 6 2003/12/18 Compiler Common 6.0 Patch 114802-02

[michael] Hi Emden, I tried the fno-inline flag and compiled and it worked ok, though it was layed out slightly differently to how it is in windows. The thing is I realised that I compiled it with out the JPEG or png libraries, When I recompiled it and added those libraries it stopped working again . However since the png and jpg library paths are now a bit polluted by all the other installs I have done I will attempt to reinstall them from fresh and compile again with the fno-inline flag. here is the test.s file from the first install

(See attached file: b1230.s).


Owner: *
Status: *