Graphviz Issue Tracker
Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0001199graphvizNeatopublic2007-11-12 22:102011-11-23 16:40
ReporterMichael Mueller 
Assigned Togviz 
PrioritynormalSeveritymajorReproducibilityalways
StatusresolvedResolutionopen 
PlatformOSSparc-Solaris-2.8OS Version
Summary0001199: Neato Maps in 2.16 on Sparc Solaris Not Layed out correctly
Description


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.
Steps To Reproduce
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;
}
Additional Information
[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.)
<CD>
./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
</CD>


neato -v shows

<CD>
 /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
</CD>


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
<CD>
> 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.
>
>
</CD>

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.
<CD>
   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.
</CD>

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.

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

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.
<CD>
/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
</CD>

[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


<CD>
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
</CD>

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

<CD>
[email protected] 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
</CD>
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

<CD>
> final e = 22.610892 0 iterations 0.00 sec
</CD>

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 \<A HREF="b1230.i"\>stuff.o\</A\> 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 %f\n", e, save_e, fabs((e - save_e) / save_e));

after line 554 in lib/neatogen/stuff.c

[michael] Here is the ouput,

<CD>
/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
</CD>

[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

<CD>
#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 ("bad\n");
else
  printf ("good\n");
}
</CD>
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]
<CD>
[email protected] ~> 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
[email protected] ~> ./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: \<A HREF="b1230.s"\>b1230.s\</A\>).
</CD>
TagsNo tags attached.
AUXILLARY-FILEShttp://www.graphviz.org/bugs/b1230.i [^] http://www.graphviz.org/bugs/b1230.s [^]
DATE-FIXED
FIX-COMMENT
FORMER-ID1230
INPUT-FILE
OUTPUT-FILEhttp://www.graphviz.org/bugs/b1230.png [^]
STATUS-COMMENT*
VERSION     2.16
Attached Files

- Relationships

-  Notes
User avatar (0000082)
boblied (reporter)
2011-10-10 13:25

We recently saw the same problem (graphviz version 2.26.3; Solaris 6,8,10; gcc 3.4.6) and worked around it by changing the initializer of old_stress at line 1740 of stress.c in stress_majorization_kD_mkernel() from MAXDOUBLE to MAXFLOAT.

I see that the code in question has changed in 2.28.0, but back-porting that
didn't fix it.

Credit goes to Pete Fales for digging into it. His message to me:

I had some time this morning (while listening to a conference
call :-) and I can't resist a challenge, so I did some debugging
and I now have some more information.

The problem comes from this block in lib/neatogen/stress.c:

1844 converged =
1845 (((fabs(old_stress - new_stress) / old_stress) < Epsilon)
1846 || (new_stress < Epsilon));
1847

The problem does not occur if it gets compiled with "-O2" only
or with "-ffast-math" only, but only when both flags
("-O2 -ffast-math") are used. The first time through the loop,
old_stress is an extremely large value (MAXDOUBLE) and new_stress
is much smaller value (300.2) which essentially disappears from
the calculation. As a result, (old_stress - new_stress)/old_stress
is effectively old_stress/old_stress or 1.0. When "-O2 -ffast-math"
is used, the result of the calculation is 0.0 which is less than
Epsilon. This causes converged to be "true" and terminates the loop.

There are a number of possible solutions for this:

1) Compile with whole package without -O2
2) Compile the whole package without -ffast-math
3) Figure out how to compile only stress.c without those flags
4) Change the initializer on line 1740 of stress.c from MAXDOUBLE
   to MAXFLOAT. The value just needs to be larger than any
   calculated new_stress value, and MAXFLOAT seems plenty large
   enough for that.

Personally, I like option 4 because I think it's easier to do
it with a code change rather than a build change. Also, turning
off fast-math or optimization will impact performance. (Though
we probably aren't *too* worried about performance of this app)
User avatar (0000085)
erg (administrator)
2011-10-18 17:02

I have put in a fix keyed to gcc3 and sparc. (See line 345 in configure.ac and line 1738 in lib/neatogen/stress.c) We have no way of testing this here, so if someone with access to gcc3 on a sparc would check that this solves the problem, please let us know. Thanks.

- Issue History
Date Modified Username Field Change
2011-04-28 04:03 user1 New Issue
2011-04-28 04:03 user1 Assigned To => user1
2011-10-10 13:25 boblied Note Added: 0000082
2011-10-18 17:02 erg Note Added: 0000085
2011-10-19 09:25 erg Status acknowledged => resolved
2011-10-19 09:25 erg Description Updated View Revisions
2011-10-19 09:25 erg Steps to Reproduce Updated View Revisions
2011-10-19 09:25 erg Additional Information Updated View Revisions


MantisBT 1.2.5[^]
Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker