[Scilab-Dev] What is the Fortran function maxvol ?

bernard.hugueney at scilab.org bernard.hugueney at scilab.org
Wed Jun 3 09:14:29 CEST 2009


On Tue, 2 Jun 2009 16:27:34 +0200, Vincent Lejeune
<vincent.lejeune at institutoptique.fr> wrote:
> Hi,
> 
> In SciLabs Fortran part of code, there is a "maxvol" function that come 
> several time, for instance in intdgesv3.f, intdgecon.f, sci_f_mucomp.f
...
> The function is typically called this way :
> LWORK=maxvol(10,'d')
> 
> (when the function is acting on complex, 'd' is replaced by 'z')
> I am no Fortran expert, but I'd like to know what this function does. I 
> dont find its definition in scilab's git repository (I used nepomuk...),
> and I 
> didnt catch any results on any google search. I suspect this function has

> to deal with some parallel activities, as it is frequently summoned 
> besides Lapack call...
> 
> Thanks for the help !
> 

If I am not mistaken, this function returns the max number of elements in
 a matrix of type double ('d') or complex ('z') that can be allocated on 
the Scilab stack. It is called before Lapack functions that require 
a temporary workspace of unbounded size (the more the better).

The Fortran routine can allocates all the size available on the stack
because 
no further allocation will be neded before the temporary workspace is
needed. 

When coding in C, you won't use the Scilab stack for temporary workspace
because
 you can use malloc fir dynamic memory allocation (well, MALLOC in fact,
with #include "MALLOC.h"). 
However, you cannot malloc all the heap memory available like Fortran could

alloc all the scilab stack memory available ! So you have to choose the
best size 
and you can know which size is best by calling the Lapack routine with 
a special query mode by passing a worksize of -1 (but still passing
relevent values
 for nb of rows/cols for exemple because Lapack will use them to compute 
the optimal size). Lapack routines will then return the computed optimal
size at 
the begining of the "workspace" (so you cannont pass NULL, but should
instead 
pass &a_variable_of_type_double ). As small an example is worth a thousand
words :
 " with : 
static int dsyevWorkSizes(int iCols, int* optWorkSize, int* minWorkSize) {
 int info=0, query=-1; 
 double opt; 
 C2F(dsyev)("N", "U", &iCols, NULL, &iCols, NULL, &opt, &query, &info);
 *optWorkSize= (int)opt;
 *minWorkSize= Max(1, 3*iCols -1); /* this is documented in Lapack API
specifications */
 return info;
 }

 you could write : 

int optWs, minWs; 
if(!dsyevWorkSizes(cols, &optWs, &minWs) {
 double* workspace= NULL;
 int wsSize= 0;

 workspace=MALLOC(optWs);
 if(workspace) { wsSize= optWs; } 
 else { 
   workspace= MALLOC(minWs);
   if(workspace){ wsSize= minWs; }
 }
 if(workspace) {
 /* now you can call Lapack routine with dynamicaly allocated workspace of
size wsSize */
 } 
[...]


 HTH. (feel free to ask again if I was not clear).

Regards,

Bernard 



More information about the dev mailing list