This article is a comment on Jeremy Walton's piece on the NAG blog entitled Calling routines from the NAG Fortran and C libraries from within LabVIEW.
Jeremy's article provides an excellent introduction into calling the NAG Fortran and C libraries from within LabVIEW. From my own experiences on using these libraries from LabVIEW I would like to add the following comments and hints.
For me, a key difference between the two libraries is the way in which they handle fail conditions. All NAG routines that have error exits provide an argument —ifail in the case of Fortran and fail for C — which allow for the handling of any warning messages should an error occur. In the case of Fortran library calls the parameter ifail can have the value -1, 0 or 1 on entry. If ifail is set to 0 then execution of the program will terminate if the routine detects an error — the so called "hard fail option". To select a soft fail option ifail is set to -1 or 1 on calling the routine; upon detecting an error, an error number is passed to the output of ifail and the execution of program continues normally. If ifail was set to -1 on input then an error message is printed on stderr (noisy exit), otherwise a silent exit is performed.
Consider the special function S11ACF which evaluates the inverse hyperbolic cosine, arccosh(x), where x>1. In our LabVIEW code we would like to detect the existence of an error and set the output to NaN (not a number), but allow the program to continue to execute unhindered.
In the case of the C library, is either an integer value 0 for the default error handler (hard fail, noisy exit) or the pointer to a C structure which includes a pointer to a custom error handler. This latter option is non-trivial from LabVIEW and so I have a strong preference towards using the Fortran library.
For more details of Error Handling and the fail Argument with C function calls, see here, and for the Fortran functions here.
There are two major differences in the approaches to data storage between C and Fortran which must be taken into consideration when call the NAG routines from LabVIEW. Both C and LabVIEW employ null terminated strings and arrays which are zero based and column major order — Fortran has one based arrays of major row order.
When passing strings to and from Fortran routines, the string parameter is followed by a variable which holds the string length as an I32 integer. The Call Library Function passes the string as aC String Pointer and its length as a Pointer to Value to the dll. When calling the function from LabVIEW the string must be initialized with a string of the correct length, for example nagf_time_date_array_string;
When passing 2D arrays to and from Fortran routines it will be necessary to transpose the array before and after the DLL call; this can be achieved using the LabVIEW Transpose 2D Array.vi
In the Call Function Library (CLF) node it is possible to set Name Format>>Names through the right-click context menu which make the LabVIEW much more readable.
Create clusters (LabVIEW equivalent to structures) of similar input/output terminal, this makes the subVI's connector plane much more manageable.
For NAG routines that are thread safe there are considerable advantages to selecting Run in any thread as opposed to the default Run in UI thread. Below are the results of a timing test run on my laptop (Intel® Core™2 Duo CPU T7300 @ 2.00GHz).
|UI thread||5.3 s|
|any thread||4.2 s|
|any thread — parallel N-loop||2.5 s|
More information on the thread safety of the fourtan routines can be found on the NAG website. The NAG C Library is thread safe by design, however please check the Thread Safety section of the essential guide before continuing.
Compiling LabVIEW code (build executable) containing NAG libraries is very straightforward — no special settings are required.