Monday, 26 November 2007

NAG library- getting the thing to work!

So, I receive my license key, and I've installed the library that I needed (FLL3A21DFL, x86-32, Linux, gfortran compiler, Double Precision) and followed the installers instructions on this page. It installed in:
/opt/NAG/fll3a21dfl/
It's now time to run a test! The User's Note suggests to run an example, like thus:
nag_example e04ucf
...for which I moved to my own directory where I had write permission. However, then I need to tell it where the nag_example script is, so I actually had to run:
/opt/NAG/fll3a21dfl/scripts/nag_example e04ucf
The computer said:
Copying e04ucfe.f to current directory
cp /opt/NAG/fll3a21dfl/examples/source/e04ucfe.f .
Compiling and linking e04ucfe.f to produce executable e04ucfe.exe
gfortran -m32 e04ucfe.f /opt/NAG/fll3a21dfl/lib/libnag_nag.a -o e04ucfe.exe
Copying e04ucfe.d to current directory
cp /opt/NAG/fll3a21dfl/examples/data/e04ucfe.d .
Running e04ucfe.exe with data from e04ucfe.d
./e04ucfe.exe < e04ucfe.d > e04ucfe.r
/opt/NAG/fll3a21dfl/scripts/nag_example: line 58: 12681 Segmentation fault ./${example}.exe <${example}.d >${example}.r
...as it happily seg-faulted. I guessed this is because it called "gfortran" which still refers to the old version of the compiler on my machine (I still haven't worked out how to change that!) But now I guess the correct commands to re-compile it:
/etc/irun/bin/gfortran -m32 e04ucfe.f /opt/NAG/fll3a21dfl/lib/libnag_nag.a -o e04ucfe.exe
Then to run it:
./e04ucfe.exe < e04ucfe.d > e04ucfe.r
And it cried:
./e04ucfe.exe: error while loading shared libraries: libgfortran.so.3: cannot open shared object file: No such file or directory
No matter, I had forgotten to type
export LD_LIBRARY_FLAG=/etc/irun/lib
export LD_LIBRARY_PATH=/etc/irun/lib
...because I still haven't managed to sort this problem out a better way. Perhaps making a symbolic link to the missing libraries as suggested in the NAG Installer's notes might work:
To simplify access to the libraries you may wish to create symbolic links in a system location such as /usr/lib pointing at the installed libraries. They would then be in the default search path of the linker during the link phase, and be available for execution at run time (in the case of shareable libraries).
Anyway, re-compiling and running now works fine. Time to call a routine from my program. Since this is the NAG library (and not the NAG f90 library), I must call functions with strange names like S14AAF. After adding the compilers own libraries to LD_LIBRARY_PATH (see above!), I additionally added the NAG libraries:
LD_LIBRARY_PATH=/opt/NAG/fll3a21dfl/lib:/opt/NAG/fll3a21dfl/acml:
${LD_LIBRARY_PATH}

but really all on one line, and with no spaces. Then...
export LD_LIBRARY_PATH
Such that typing:
echo $LD_LIBRARY_PATH
Gives me:
/opt/NAG/fll3a21dfl/lib:/opt/NAG/fll3a21dfl/acml:/etc/irun/lib
I've no idea if that was strictly necessary. (Edit- it doesn't seem to be!) In my fortran code, I must declare the types of the NAG functions I call, as well as the fact that they are external:
real(kind = 10) :: factorial, S14AAF, S14BAF
external S14AAF, S14BAF
Where factorial is an internal function I wrote myself. Functions are then called as you would expect...
gam = S14AAF(n+1.0,ifail)
or somesuch line. The program is compiled using:
/etc/irun/bin/gfortran -m32 gammatest.f90 /opt/NAG/fll3a21dfl/lib/libnag_nag.a -o gammatest
...since I had to tell the compiler where to find the external functions.

2 comments:

Michael said...

I guessed this is because it called "gfortran" which still refers to the old version of the compiler on my machine (I still haven't worked out how to change that!)

Isn't it simply a case of adjusting the order of things in your $PATH? or set up ~/bin/ to include a few symlinks to preferred version of things. Though that's rather insecure as any process can bung stuff in there.

Ali said...

Wow! I didn't know anyone else but me ever found this blog! Thanks very much for your advice, I'll try it out.