|
View:
New views
16 Messages
—
Rating Filter:
Alert me
|
|
|
Include Fortran Code which Returns Arrays of Dynamic/Unknown SizeHello!
I would like to use some fortran subroutines from within octave. With the documentation from the octave-homepage it works fine with an example of the form: ... octave_value_list retval; Matrix M1 = Matrix(4,3); F77_XFCN (function, FUNCTION, ( M1.fortran_vec() ) ); retval(0) = M1; ... Here, I the size of the matrix M1 is fixed. But in some cases I do not know before the call of the fortran subroutine what size the return value M1 has because this size is computed inside the fortran subroutine. I tried something like ... octave_value_list retval; Matrix M1; F77_XFCN (function, FUNCTION, ( M1.fortran_vec() ); retval(0) = M1; ... but it does not work. Therefor, I would like to know if and possibly how that can be realized. It should be possible by defining a very large matrix M1 in the c++-wrapper and return additionally the actually needed size from the fortran subroutine by an integer variable. The return value M1 then has to be resized. But I would like to avoid this solution, because you never know what "very large" means. If someone had an idea, I would be very glad. Thanks, Marco |
|
|
Include Fortran Code which Returns Arrays of Dynamic/Unknown SizeOn 8-Oct-2008, Marco2008 wrote:
| | Hello! | | I would like to use some fortran subroutines from within octave. With the | documentation from the octave-homepage it works fine with an example of the | form: | | ... | octave_value_list retval; | Matrix M1 = Matrix(4,3); | F77_XFCN (function, FUNCTION, ( M1.fortran_vec() ) ); | retval(0) = M1; | ... | | Here, I the size of the matrix M1 is fixed. But in some cases I do not know | before the call of the fortran subroutine what size the return value M1 has | because this size is computed inside the fortran subroutine. I tried | something like | | ... | octave_value_list retval; | Matrix M1; | F77_XFCN (function, FUNCTION, ( M1.fortran_vec() ); | retval(0) = M1; | ... | | but it does not work. Therefor, I would like to know if and possibly how | that can be realized. | It should be possible by defining a very large matrix M1 in the c++-wrapper | and return additionally the actually needed size from the fortran subroutine | by an integer variable. The return value M1 then has to be resized. | But I would like to avoid this solution, because you never know what "very | large" means. | | If someone had an idea, I would be very glad. I think we need to know more details about precisely how your function does what you claim it does. Perhaps you could post a simple example that has all the relevant features (i.e., some Fortran function that allocates a matrix and returns it as a parameter). Exactly how does your Fortran function allocate the data? How would you call your fucntion in a program written purely in Fortran? jwe _______________________________________________ Help-octave mailing list Help-octave@... https://www-old.cae.wisc.edu/mailman/listinfo/help-octave |
|
|
Re: Include Fortran Code which Returns Arrays of Dynamic/Unknown SizeSo here is the example that works: c++-wrapper (fun_cpp.cc): #include <octave/oct.h> #include "f77-fcn.h" extern "C" { F77_RET_T F77_FUNC (funfortran, FUNFORTRAN) (double* matrix1); } DEFUN_DLD (fun_cpp, args, ,"...") { octave_value_list retval; Matrix M1 = Matrix(2,2); F77_XFCN (funfortran, FUNFORTRAN, ( M1.fortran_vec() ) ); if (f77_exception_encountered) { error ("Error!"); return retval; } retval(0) = M1; return retval; } Fortran-Subroutine (funfortran.f90): subroutine funfortran(matrix1) implicit none real(8), intent(out) :: matrix1(2,2) matrix1(1,:) = (/1,2/) matrix1(2,:) = (/3,4/) end subroutine funfortran Call in octave: octave:1> fun_cpp ans = 1 2 3 4 octave:2> My problem is the following fortran code: subroutine funfortrantwo(vector1) implicit none integer :: size1 real(8), allocatable :: vector1(:) size1 = 3 ! size1 here is defined by a fixed number only to make the ! example clear. Normally, it is computed inside this fortran ! subroutine and not known before a call of funfortrantwo. allocate( vector1(size1) ) vector1 = 2 end subroutine funfortrantwo I do not know how to write the c++-wrapper for this subroutine. In the first example the size of the matrix is known before the fortran subroutine is called. But this is not the case in the second example. Marco |
|
|
Re: Include Fortran Code which Returns Arrays of Dynamic/Unknown SizeOn 8-Oct-2008, Marco2008 wrote:
| My problem is the following fortran code: | | subroutine funfortrantwo(vector1) | implicit none | integer :: size1 | real(8), allocatable :: vector1(:) | size1 = 3 | ! size1 here is defined by a fixed number only to make the | ! example clear. Normally, it is computed inside this fortran | ! subroutine and not known before a call of funfortrantwo. | allocate( vector1(size1) ) | vector1 = 2 | end subroutine funfortrantwo | | I do not know how to write the c++-wrapper for this subroutine. In the first | example the size of the matrix is known before the fortran subroutine is | called. But this is not the case in the second example. I don't know how to call this function from C/C++. If you had a similar function in C++, for example something like void foo (double **v, int *len) { len = 10; // or some computed value *v = new double [len]; // fill V here ... } then you could call it from an Octave DEFUN like this: double *v; int len; foo (&v, &len); and then copy the values from V to an appropriately sized Matrix object: Matrix m (len, 1); double *pm = m.fortran_vec (); for (int i = 0; i < len; i++) m[i] = v[i]; then you would probably also want to free the memory allocated in FOO to avoid a memory leak: delete [] v; Is an allocatable array in Fortran some kind of object that carries with it the size? If so, then I think you need to know precisely what your compiler does so that you can call a function like this from C++ (probably the details are implementation defined, so will not be portable). Or is it guaranteed to just be a pointer to some data? If it is just a pointer, then I think you will need to modify your function so that it also returns the size. Otherwise, how can a C++ function that calls your Fortran function know how large the allocated array is? jwe _______________________________________________ Help-octave mailing list Help-octave@... https://www-old.cae.wisc.edu/mailman/listinfo/help-octave |
|
|
Re: Include Fortran Code which Returns Arrays of Dynamic/Unknown SizeOn Wed, Oct 8, 2008 at 11:01 PM, Marco2008 <mbk_forum@...> wrote:
> > > John W. Eaton wrote: >> >> I think we need to know more details about precisely how your function >> does what you claim it does. Perhaps you could post a simple example >> that has all the relevant features (i.e., some Fortran function that >> allocates a matrix and returns it as a parameter). Exactly how does >> your Fortran function allocate the data? How would you call your >> fucntion in a program written purely in Fortran? >> >> jwe >> > > So here is the example that works: > > c++-wrapper (fun_cpp.cc): > > #include <octave/oct.h> > #include "f77-fcn.h" > extern "C" > { > F77_RET_T > F77_FUNC (funfortran, FUNFORTRAN) (double* matrix1); > } > DEFUN_DLD (fun_cpp, args, ,"...") > { > octave_value_list retval; > Matrix M1 = Matrix(2,2); > F77_XFCN (funfortran, FUNFORTRAN, > ( M1.fortran_vec() ) ); > if (f77_exception_encountered) > { > error ("Error!"); > return retval; > } > retval(0) = M1; > return retval; > } > > Fortran-Subroutine (funfortran.f90): > > subroutine funfortran(matrix1) > implicit none > real(8), intent(out) :: matrix1(2,2) > matrix1(1,:) = (/1,2/) > matrix1(2,:) = (/3,4/) > end subroutine funfortran > > Call in octave: > > octave:1> fun_cpp > ans = > > 1 2 > 3 4 > > octave:2> > > > My problem is the following fortran code: > > subroutine funfortrantwo(vector1) > implicit none > integer :: size1 > real(8), allocatable :: vector1(:) > size1 = 3 > ! size1 here is defined by a fixed number only to make the > ! example clear. Normally, it is computed inside this fortran > ! subroutine and not known before a call of funfortrantwo. > allocate( vector1(size1) ) > vector1 = 2 > end subroutine funfortrantwo > > I do not know how to write the c++-wrapper for this subroutine. In the first > example the size of the matrix is known before the fortran subroutine is > called. But this is not the case in the second example. > Hi Marco, in terms of Fortran 2003/Interoperability with C, allocatable arrays are not interoperable. These arrays are always passed by array descriptor (allocating descriptor and passing its address), but how exactly the descriptor looks is completely compiler-dependent. Also, note that it is Fortran runtime library that allocates the array, but presumably C++ runtime library should deallocate it, which is almost bound to cause trouble. The easiest portable way to achieve what you need is to first make a special "query" call to the Fortran subroutine that will only return the array size, allocate it in C++, and then invoke a normal call. This is, for instance, how LAPACK works. regards -- RNDr. Jaroslav Hajek computing expert Aeronautical Research and Test Institute (VZLU) Prague, Czech Republic url: www.highegg.matfyz.cz _______________________________________________ Help-octave mailing list Help-octave@... https://www-old.cae.wisc.edu/mailman/listinfo/help-octave |
|
|
Re: Include Fortran Code which Returns Arrays of Dynamic/Unknown SizeThanks a lot for this post. I will try to implement my algorithms in the way you described. Maybe there is one drawback. If the "query" call computes some results for further computations they are lost with the end of the "query" call and have to be recomputed in the second call. This can decrease the performance of the algorithm. By the way, what is a specific example for the use of LAPACK with this approach? Regards Marco |
|
|
Re: Include Fortran Code which Returns Arrays of Dynamic/Unknown SizeHello! Thanks for this idea. I tried a bit with this approach. It brought me to the following code: subroutine funfortrantwo(size1, vector1) implicit none integer :: size1 real(8) :: vector1(size1) vector1 = 2 ! write(6,*) vector1 end subroutine funfortrantwo #include <octave/oct.h> #include <iostream> #include "f77-fcn.h" extern "C" { F77_RET_T F77_FUNC (funfortrantwo, FUNFORTRANTWO) (int& n1, double* m1); } DEFUN_DLD (fun_cpp2, args, ,"...") { octave_value_list retval; double* m1; int n1 = 7; F77_XFCN (funfortrantwo, FUNFORTRANTWO, ( n1, m1 ) ); if (f77_exception_encountered) { error ("Error!"); return retval; } int i1 = n1; Matrix M1 (i1,1); for (int i = 0; i < i1; i++) { double h1 = m1[i]; M1.fill(h1,i,0,i,0); } retval(0) = M1; return retval; } it can be compiled by mkoctfile. But inside octave I get: panic: Segmentation fault -- stopping myself... attempting to save variables to `octave-core'... save to `octave-core' complete Segmentation fault If I replace int int i1 = n1; by int i1 = 7; it works correctly for one time. The second time fails with the above mentioned panic. Maybe the memory management in my c++-file is not correct. |
|
|
Re: Include Fortran Code which Returns Arrays of Dynamic/Unknown SizeOn 10-Oct-2008, Marco2008 wrote:
| | | John W. Eaton wrote: | > | > I don't know how to call this function from C/C++. | > | > If you had a similar function in C++, for example something like | > | > void foo (double **v, int *len) | > { | > len = 10; // or some computed value | > *v = new double [len]; | > | > // fill V here ... | > } | > | > then you could call it from an Octave DEFUN like this: | > | > double *v; | > int len; | > foo (&v, &len); | > | > and then copy the values from V to an appropriately sized Matrix | > object: | > | > Matrix m (len, 1); | > double *pm = m.fortran_vec (); | > for (int i = 0; i < len; i++) | > m[i] = v[i]; | > | > then you would probably also want to free the memory allocated in FOO | > to avoid a memory leak: | > | > delete [] v; | > | > Is an allocatable array in Fortran some kind of object that carries | > with it the size? If so, then I think you need to know precisely what | > your compiler does so that you can call a function like this from C++ | > (probably the details are implementation defined, so will not be | > portable). Or is it guaranteed to just be a pointer to some data? If | > it is just a pointer, then I think you will need to modify your | > function so that it also returns the size. Otherwise, how can a C++ | > function that calls your Fortran function know how large the allocated | > array is? | > | > jwe | > _______________________________________________ | > Help-octave mailing list | > Help-octave@... | > https://www-old.cae.wisc.edu/mailman/listinfo/help-octave | > | | Hello! | Thanks for this idea. | I tried a bit with this approach. It brought me to the following code: | | subroutine funfortrantwo(size1, vector1) | implicit none | integer :: size1 | real(8) :: vector1(size1) | vector1 = 2 | ! write(6,*) vector1 | end subroutine funfortrantwo | | #include <octave/oct.h> | #include <iostream> | #include "f77-fcn.h" | extern "C" | { | F77_RET_T | F77_FUNC (funfortrantwo, FUNFORTRANTWO) (int& n1, double* m1); | } | DEFUN_DLD (fun_cpp2, args, ,"...") | { | octave_value_list retval; | double* m1; | int n1 = 7; | F77_XFCN (funfortrantwo, FUNFORTRANTWO, | ( n1, m1 ) ); | if (f77_exception_encountered) | { | error ("Error!"); | return retval; | } | int i1 = n1; | Matrix M1 (i1,1); | for (int i = 0; i < i1; i++) | { | double h1 = m1[i]; | M1.fill(h1,i,0,i,0); | } | retval(0) = M1; | return retval; | } | | it can be compiled by mkoctfile. But inside octave I get: | | panic: Segmentation fault -- stopping myself... | attempting to save variables to `octave-core'... | save to `octave-core' complete | Segmentation fault | | If I replace int | int i1 = n1; | by | int i1 = 7; | it works correctly for one time. The second time fails with the above | mentioned panic. Maybe the memory management in my c++-file is not correct. | double* m1; | int n1 = 7; | F77_XFCN (funfortrantwo, FUNFORTRANTWO, | ( n1, m1 ) ); No storage is allocated for m1. You have only declared a pointer. Octave crashes because the call to your Fortran function scribbles over some memory. Try int n1 = 7; Matrix mm1 (n1, 1); double *m1 = mm1.fortran_vec (); F77_XFCN (funfortrantwo, FUNFORTRANTWO, (n1, m1)); jwe _______________________________________________ Help-octave mailing list Help-octave@... https://www-old.cae.wisc.edu/mailman/listinfo/help-octave |
|
|
Re: Include Fortran Code which Returns Arrays of Dynamic/Unknown Size> > Thanks a lot for this post. I will try to implement my algorithms in the way > you described. Maybe there is one drawback. If the "query" call computes > some results for further computations they are lost with the end of the > "query" call and have to be recomputed in the second call. This can decrease > the performance of the algorithm. > I've done quite a bit of F77 programming in my time and the declaring a variable with "SAVE" allows its value to be stored between invocations of a function. Can't you arrange that the precalculated values are stored and reused on the second call? D. _______________________________________________ Help-octave mailing list Help-octave@... https://www-old.cae.wisc.edu/mailman/listinfo/help-octave |
|
|
Re: Include Fortran Code which Returns Arrays of Dynamic/Unknown SizeThanks for the hint. I tried it with simple integer and real variables as well as with arrays of fixed size and it has worked well. But the SAVE attribute does not work with arrays of dynamic size: INTEGER, SAVE :: k1(:) ! does not work I am not sure if there is another trick to use SAVE and arrays with unknown size anyway. I tried something with a saved pointer. It compiled but some values of the array had changed in the second call. Marco |
|
|
Re: Include Fortran Code which Returns Arrays of Dynamic/Unknown SizeMarco2008 wrote:
> > Thanks for the hint. I tried it with simple integer and real variables as > well as with arrays of fixed size and it has worked well. But the SAVE > attribute does not work with arrays of dynamic size: > INTEGER, SAVE :: k1(:) ! does not work > I am not sure if there is another trick to use SAVE and arrays with unknown > size anyway. I tried something with a saved pointer. It compiled but some > values of the array had changed in the second call. Well SAVE is an F77 keyword and so this doesn't really surprise me. Isn't there a F90 keyword for static variables? D. -- David Bateman dbateman@... 35 rue Gambetta +33 1 46 04 02 18 (Home) 92100 Boulogne-Billancourt FRANCE +33 6 72 01 06 33 (Mob) _______________________________________________ Help-octave mailing list Help-octave@... https://www-old.cae.wisc.edu/mailman/listinfo/help-octave |
|
|
Re: Include Fortran Code which Returns Arrays of Dynamic/Unknown SizeOn Mon, Oct 13, 2008 at 9:01 PM, Marco2008 <mbk_forum@...> wrote:
> > > dbateman wrote: >> >> I've done quite a bit of F77 programming in my time and the declaring a >> variable with "SAVE" allows its value to be stored between invocations >> of a function. Can't you arrange that the precalculated values are >> stored and reused on the second call? >> >> D. >> > > Thanks for the hint. I tried it with simple integer and real variables as > well as with arrays of fixed size and it has worked well. But the SAVE > attribute does not work with arrays of dynamic size: > INTEGER, SAVE :: k1(:) ! does not work > I am not sure if there is another trick to use SAVE and arrays with unknown > size anyway. I tried something with a saved pointer. It compiled but some > values of the array had changed in the second call. > You can't declare a deferred shape array variable (not a dummy argument) without ALLOCATABLE or POINTER specification, no matter whether it's SAVEd or not. Note that for POINTER arrays (like in C++), there is no automatic deallocation unless you do it. Automatic deallocation of ALLOCATABLE arrays, either SAVEd or module variables, is a delicate issue. The Fortran standard leaves it to be compiler dependent. So it's best to deallocate these, too. Maybe you could describe more closely the problem you are trying to solve? > Marco > -- > View this message in context: http://www.nabble.com/Include-Fortran-Code-which-Returns-Arrays-of-Dynamic-Unknown-Size-tp19845758p19960787.html > Sent from the Octave - General mailing list archive at Nabble.com. > > _______________________________________________ > Help-octave mailing list > Help-octave@... > https://www-old.cae.wisc.edu/mailman/listinfo/help-octave > -- RNDr. Jaroslav Hajek computing expert Aeronautical Research and Test Institute (VZLU) Prague, Czech Republic url: www.highegg.matfyz.cz _______________________________________________ Help-octave mailing list Help-octave@... https://www-old.cae.wisc.edu/mailman/listinfo/help-octave |
|
|
Re: Include Fortran Code which Returns Arrays of Dynamic/Unknown SizeOn Mon, Oct 13, 2008 at 9:37 PM, David Bateman <dbateman@...> wrote:
> Marco2008 wrote: >> >> Thanks for the hint. I tried it with simple integer and real variables as >> well as with arrays of fixed size and it has worked well. But the SAVE >> attribute does not work with arrays of dynamic size: >> INTEGER, SAVE :: k1(:) ! does not work >> I am not sure if there is another trick to use SAVE and arrays with unknown >> size anyway. I tried something with a saved pointer. It compiled but some >> values of the array had changed in the second call. > > Well SAVE is an F77 keyword and so this doesn't really surprise me. F77 is a subset of F90. In F95, some obscure features are deleted, but most F77 will still work, and the same holds for F2003. > Isn't there a F90 keyword for static variables? > Yes, it's SAVE. The above doesn't work for a different reason (deferred shape array must be POINTER or ALLOCATABLE). > D. > > -- > David Bateman dbateman@... > 35 rue Gambetta +33 1 46 04 02 18 (Home) > 92100 Boulogne-Billancourt FRANCE +33 6 72 01 06 33 (Mob) > _______________________________________________ > Help-octave mailing list > Help-octave@... > https://www-old.cae.wisc.edu/mailman/listinfo/help-octave > -- RNDr. Jaroslav Hajek computing expert Aeronautical Research and Test Institute (VZLU) Prague, Czech Republic url: www.highegg.matfyz.cz _______________________________________________ Help-octave mailing list Help-octave@... https://www-old.cae.wisc.edu/mailman/listinfo/help-octave |
|
|
Re: Include Fortran Code which Returns Arrays of Dynamic/Unknown SizeI am trying to write a function that transforms a Spline from pp-form (Representation with polynomial coefficients) into B-Form (B-Form: Representation of Spline with B-Splines). It is not important what happens there exactly but I will try to explain what has brought me to this thread. One input data of this transform function is a strict monotonically increasing sequence (real array) of values, A1. The function takes among other things A1 and one results in a monotone increasing sequence, A2, that consists of the same values but these values can exits more than one time (So A2 is larger than A1). To get the size of A2 you have to compute A2, it is not possible to predict it exactly. So if I use the approach with two calls of the function, in each call A2 will be computed and that is what I want to avoid. Marco |
|
|
Re: Include Fortran Code which Returns Arrays of Dynamic/Unknown SizeOn Mon, Oct 13, 2008 at 11:14 PM, Marco2008 <mbk_forum@...> wrote:
> > > > Jaroslav Hajek-2 wrote: >> >> Maybe you could describe more closely the problem you are trying to solve? >> > > I am trying to write a function that transforms a Spline from pp-form > (Representation with polynomial coefficients) into B-Form (B-Form: > Representation of Spline with B-Splines). It is not important what happens > there exactly but I will try to explain what has brought me to this thread. > > One input data of this transform function is a strict monotonically > increasing sequence (real array) of values, A1. The function takes among > other things A1 and one results in a monotone increasing sequence, A2, that > consists of the same values but these values can exits more than one time > (So A2 is larger than A1). > To get the size of A2 you have to compute A2, it is not possible to predict > it exactly. > So if I use the approach with two calls of the function, in each call A2 > will be computed and that is what I want to avoid. > I see. Is a good upper bound guess for size of A2 available? If so, then you can simply allocate to that size in C++ and let the computational routine return also the actual size. If not, there's still a solution. Some time ago I "invented" a technique to arrange the inter-language calls in such a way that you can allocate memory for a Fortran pointer via C++. For a long time, I wanted to put up an example of this technique on my website, so now is a good time to do it. I'll post a link once it's there. -- RNDr. Jaroslav Hajek computing expert Aeronautical Research and Test Institute (VZLU) Prague, Czech Republic url: www.highegg.matfyz.cz _______________________________________________ Help-octave mailing list Help-octave@... https://www-old.cae.wisc.edu/mailman/listinfo/help-octave |
|
|
Re: Include Fortran Code which Returns Arrays of Dynamic/Unknown SizeHello
An upper bound for the size of A2 can be calculated very easily (K*|A2|, K \in N). I will do it like this for now. That would be very nice. Marco |
| Free embeddable forum powered by Nabble | Forum Help |