The C and Fortran77 interfaces, as they are not object-capable, need to use
specific calling sequences that are more involved than the ones
used from Matlab or Mathematica.
In the Section called *NetSolve Problem Specification* in Chapter 4, we described the input and output
arguments of a NetSolve problem as lists of
*objects*. The Matlab and Mathematica interfaces
to NetSolve can
manipulate objects directly and it is therefore very easy to call NetSolve
from their interfaces once problem descriptions are known. From interfaces
that are not object-oriented (C and Fortran), it is necessary to use a
*calling sequence* that describes the objects' features individually.
For complete details, the user should refer to Chapter 5
and the Section called *Sparse Matrix Representation in NetSolve* in Chapter 17.

Let us take a very simple example: the user wants to perform a dense linear system solve. The first thing to know, as stated in earlier chapters, is the name or IP address of a host running a NetSolve agent. The default NetSolve agent running at the University of Tennessee is aware of many servers that can perform the computation. In fact, a dense linear system solve is provided with the NetSolve distribution as default numerical software for the server. The user has now two possible courses of action to find out about the problem. Let us assume that the user chooses to use the UNIX command line management tools (see Chapter 16 for a complete description of these tools). The alternative would be to use the CGI scripts on the NetSolve homepage.

the Section called *Expanding the Server Capabilities* in Chapter 13 shows how the servers specify
the calling sequence to a given problem. It is usual for servers
to enforce the same calling sequence as the original numerical software and
to give a problem the name of the original library function. In the example,
`dgesv()` is the name of an LAPACK subroutine and the user can therefore
expect the calling sequence for the problem `dgesv` to match the
one of the subroutine. One can see in the problem list returned by **NS_problems**
a problem called `linsol`. In this example, `linsol` is a simplified
version of `dgesv` and has a simplified calling sequence chosen by whomever
started the first server that provides access to that problem. Since `linsol` is
not the name of an LAPACK subroutine, its calling sequence can be arbitrary.

UNIX> NS_problems netsolve.cs.utk.edu /LAPACK/LinearSystems/dgesv /LAPACK/LinearSystems/linsol |

Next, two situations are possible. First, the user already knows the numerical
software (e.g., LAPACK) and may even
have code already written in terms of this software. In this case, the
*switching* to NetSolve is immediate. The second possibility
is that the user does not know the software. If this is the case, he needs
to pay close attention to the output given by **NS_probdesc**.
The output from this command first gives the calling sequence as it would
be invoked from Matlab, and then gives the calling sequence from C/Fortran.

UNIX> NS_probdesc netsolve.cs.utk.edu dgesv -- dgesv -- From LAPACK - Compute the solution to a real system of linear equations A * X = b where A is an N-by-B matrix and X and B are N-by-NRHS matrices. Matlab Example : [x y z info ] = netsolve('dgesv',a,b) http://www.netlib.org/lapack/index.html * 2 objects in INPUT - input 0: Matrix Double Precision Real. Matrix A - input 1: Matrix Double Precision Real. Right hand side * 4 objects in OUTPUT - output 0: Matrix Double Precision Real. LU factors ( A = P*L*U) - output 1: Vector Integer. Vector of pivots (defines the P matrix) - output 2: Matrix Double Precision Real. Solution - output 3: Scalar Integer. INFO 0 successful <0 error on calling ? >0 QR algorithm failed * Calling sequence from C or Fortran 8 arguments - Argument #0: - number of rows of input object #0 (A) - number of columns of input object #0 (A) - number of rows of input object #1 (RHS) - Argument #1: - number of columns of input object #1 (RHS) - Argument #2: - pointer to input object #0 (A) - pointer to output object #0 (LU) - pointer to output object #0 (LU) - Argument #3: - leading dimension of input object #0 (A) - Argument #4: - pointer to output object #1 (PIVOT) - Argument #5: - pointer to input object #1 (RHS) - pointer to output object #1 (PIVOT) - pointer to output object #2 (SOLUTION) - Argument #6: - leading dimension of input object #1 (RHS) - Argument #7: - pointer to output object #3 (INFO) |

This output can appear rather cryptic at first. Let us work through it step by step. First, the number of arguments in the calling sequence is 8. This means that the call from C will look like:

status = netsl('dgesv()',X0,X1,X2,X3,X4,X5,X6,X7); |

CALL FNETSL('dgesv()',STATUS,X0,X1,X2,X3,X4,X5,X6,X7) |