File Coverage

blib/lib/FFI/Platypus/Lang/Fortran.pm
Criterion Covered Total %
statement 10 14 71.4
branch 0 2 0.0
condition n/a
subroutine 4 7 57.1
pod 2 2 100.0
total 16 25 64.0


line stmt bran cond sub pod time code
1             package FFI::Platypus::Lang::Fortran;
2              
3 3     3   140483 use strict;
  3         9  
  3         73  
4 3     3   13 use warnings;
  3         3  
  3         67  
5 3     3   1046 use FFI::Platypus::Lang::Fortran::ConfigData;
  3         6  
  3         495  
6              
7             our $VERSION = '0.10';
8              
9             =head1 NAME
10              
11             FFI::Platypus::Lang::Fortran - Documentation and tools for using Platypus with
12             Fortran
13              
14             =head1 SYNOPSIS
15              
16             Fortran 77:
17              
18             C Fortran function that adds two numbers together
19             C On Linux create a .so with: gfortran -shared -o libadd.so add.f
20             FUNCTION ADD(IA, IB)
21             ADD = IA + IB
22             END
23              
24             Fortran 90/95:
25              
26             ! Fortran function that adds two numbers together
27             ! On Linux create a .so with: gfortran -shared -o libadd.so add.f90
28             function add(a,b) result(ret)
29             implicit none
30             integer :: a
31             integer :: b
32             integer :: ret
33             ret = a + b
34             end function add
35              
36             Perl:
37              
38             use FFI::Platypus;
39             $ffi->lang('Fortran');
40             $ffi->lib('./libadd.so'); # or add.dll on Windows
41            
42             # Fortran is pass by reference, so use pointers
43             $ffi->attach( add => [ 'integer*', 'integer*' ] => 'integer' );
44            
45             # Use a reference to an integer to pass
46             # a pointer to an integer
47             print add(\1,\2), "\n"; # prints 3
48              
49             =head1 DESCRIPTION
50              
51             This module provides native types and demangling for Fortran when
52             used with L.
53              
54             This module is somewhat experimental. It is also available for adoption
55             for anyone either sufficiently knowledgable about Fortran or eager enough to
56             learn enough about Fortran. If you are interested, please send me a pull
57             request or two on the project's GitHub.
58              
59             For types, C<_> is used instead of C<*>, so use C instead of
60             C.
61              
62             =over 4
63              
64             =item byte, character
65              
66             =item integer, integer_1, integer_2, integer_4, integer_8
67              
68             =item unsigned, unsigned_1, unsigned_2, unsigned_4, unsigned_8
69              
70             =item logical, logical_1, logical_2, logical_4, logical_8
71              
72             =item real, real_4, real_8, double precision
73              
74             =back
75              
76             =head1 CAVEATS
77              
78             Fortran is pass by reference, which means that you need to pass pointers.
79             Confusingly Platypus uses a star (C<*>) suffix to indicate a pointer, and
80             Fortran uses a star to indicate the size of types.
81              
82             This module currently uses and is bundled with a fork of L
83             called L. It is used to probe
84             for a Fortran compiler, which can be problematic if you want to bundle
85             Fortran 90 or Fortran 95 code, as it only knows about Fortran 77. On some
86             platforms (such as those using C) the same command is invoked to
87             build all versions of fortran. On some (usually those with a C command)
88             a C or C command is required to build code for newer versions of
89             Fortran. We attempt to work around these limitations.
90              
91             =head1 METHODS
92              
93             Generally you will not use this class directly, instead interacting with
94             the L instance. However, the public methods used by
95             Platypus are documented here.
96              
97             =head2 native_type_map
98              
99             my $hashref = FFI::Platypus::Lang::Fortran->native_type_map;
100              
101             This returns a hash reference containing the native aliases for
102             Fortran. That is the keys are native Fortran types and the values
103             are libffi native types.
104              
105             =cut
106              
107             sub native_type_map
108             {
109 23     23 1 257 FFI::Platypus::Lang::Fortran::ConfigData->config('type');
110             }
111              
112             =head2 mangler
113              
114             my $mangler = FFI::Platypus::Lang::Fortran->mangler($ffi->libs);
115             my $c_name = $mangler->($fortran_name);
116              
117             Returns a subroutine reference that will "mangle" Fortran names.
118              
119             =cut
120              
121             sub mangler
122             {
123 0     0 1   my($class, @libs) = @_;
124            
125             FFI::Platypus::Lang::Fortran::ConfigData->config('f77')->{'trailing_underscore'}
126 0     0     ? sub { return "$_[0]_" }
127 0 0   0     : sub { $_[0] };
  0            
128             }
129              
130             =head1 EXAMPLES
131              
132             =head2 Call a subroutine
133              
134             Fortran:
135              
136             C Compile with gfortran -shared -o libsub.so sub.f
137             SUBROUTINE ADD(IRESULT, IA, IB)
138             IRESULT = IA + IB
139             END
140              
141             Perl:
142              
143             use FFI::Platypus;
144            
145             my $ffi = FFI::Platypus->new;
146             $ffi->lang('Fortran');
147             $ffi->lib('./libsub.so');
148            
149             $ffi->attach( add => ['integer*','integer*','integer*'] => 'void');
150            
151             my $value = 0;
152             add(\$value, \1, \2);
153            
154             print "$value\n";
155              
156             B: A Fortran "subroutine" is just a function that doesn't
157             return a value. In Fortran 77 variables that start wit the letter I are
158             integers unless declared otherwise. Fortran is also pass by reference,
159             which means under the covers Fortran passes its arguments as pointers to
160             the data, and you have to remember to pass in a reference to a value in
161             Perl in cases where you would normally pass in a simple value to a C
162             function.
163              
164             =head2 Call Fortran 90 / 95
165              
166             Fortran:
167              
168             ! on Linux: gfortran -shared -fPIC -o libfib.so fib.f90
169            
170             recursive function fib(x) result(ret)
171             integer, intent(in) :: x
172             integer :: ret
173            
174             if (x == 1 .or. x == 2) then
175             ret = 1
176             else
177             ret = fib(x-1) + fib(x-2)
178             end if
179            
180             end function fib
181              
182             Perl:
183              
184             use FFI::Platypus;
185            
186             my $ffi = FFI::Platypus->new;
187             $ffi->lang('Fortran');
188             $ffi->lib('./libfib.so');
189            
190             $ffi->attach( fib => ['integer*'] => 'integer' );
191            
192             for(1..10)
193             {
194             print fib(\$_), "\n";
195             }
196              
197             B: Fortran 90 has "advanced" features such as recursion and
198             pointers, which can now be used in Perl too.
199              
200             =head2 Complex numbers
201              
202             Fortran:
203              
204             ! on Linux: gfortran -shared -fPIC -o libcomplex.so complex.f90
205            
206             subroutine complex_decompose(c,r,i)
207             implicit none
208             complex*16 :: c
209             real*8 :: r
210             real*8 :: i
211            
212             r = real(c)
213             i = aimag(c)
214            
215             end subroutine complex_decompose
216              
217             Perl:
218              
219             use FFI::Platypus;
220             use Math::Complex;
221            
222             my $ffi->lang('Fortran');
223             my $ffi->lib('./libcomplex.so');
224            
225             $ffi->attach(
226             complex_decompose => ['real_8[2]','real_8*','real_8*'] => 'void',
227             sub {
228             # wrapper around the Fortran function complex_decompose
229             # $decompose is a code ref to the real complex_decompose
230             # and $complex is the first argument passed int othe Perl
231             # function complex_decompose
232             my($decompose, $complex) = @_;
233             my $real;
234             my $imaginary;
235             # decompose the Perl complex number and pass it as a
236             # Fortran complex number
237             $decompose->([Re($complex),Im($complex)], \$real, \$imaginary);
238             # The decomposed real and imaginary parts are returned from
239             # Fortran. We pass them back to the caller as a return value
240             ($real, $imaginary);
241             },
242             );
243            
244             my($r,$i) = complex_decompose(1.5 + 2.5*i);
245            
246             print "${r} + ${i}i\n";
247              
248             B: More recent versions of C and L
249             support complex types, but not pointers to complex types, so they
250             aren't (yet) much use when calling Fortran, which is pass by reference.
251             There is a work around, however, at least for complex types passes as
252             arguments. They are really two just two C or C types
253             joined together like an array or record of two elements. Thus we can
254             pass in a complex type to a Fortran subroutine as an array of two
255             floating points. Take care though, as this technique DOES NOT work
256             for return types.
257              
258             From my research, some Fortran compilers pass in the return address of
259             the return value as the first argument for functions that return a
260             C type. This is not the case for Gnu Fortran, the compiler
261             that I have been testing with, but if your compiler does use this
262             convention you could pass in the "return value" as a two element array,
263             as we did in the above example. I have not been able to test this
264             though.
265              
266             =head2 Fixed length array
267              
268             Fortran:
269              
270             ! on Linux: gfortran -shared -fPIC -o libfixed.so fixed.f90
271            
272             subroutine print_array10(a)
273             implicit none
274             integer, dimension(10) :: a
275             integer :: i
276             do i=1,10
277             print *, a(i)
278             end do
279             end subroutine print_array10
280              
281             Perl:
282              
283             use FFI::Platypus;
284            
285             my $ffi = FFI::Platypus->new;
286             $ffi->lang('Fortran');
287             $ffi->lib('./libfixed.so');
288            
289             $ffi->attach( print_array10 => ['integer[10]'] => 'void' );
290             my $array = [5,10,15,20,25,30,35,40,45,50];
291             print_array10($array);
292              
293             Output:
294              
295             5
296             10
297             15
298             20
299             25
300             30
301             35
302             40
303             45
304             50
305              
306             B: In Fortran arrays are 1 indexed unlike Perl and C where
307             arrays are 0 indexed. Perl arrays are passed in from Perl using
308             Platypus as a array reference.
309              
310             =head2 Multidimensional arrays
311              
312             Fortran:
313              
314             ! On Linux gfortran -shared -fPIC -o libfixed2.so fixed2.f90
315            
316             subroutine print_array2x5(a)
317             implicit none
318             integer, dimension(2,5) :: a
319             integer :: i,n
320            
321             do i=1,5
322             print *, a(1,i), a(2,i)
323             end do
324             end subroutine print_array2x5
325              
326             Perl:
327              
328             use FFI::Platypus;
329            
330             my $ffi = FFI::Platypus->new;
331             $ffi->lang('Fortran');
332             $ffi->lib('./libfixed.so');
333            
334             $ffi->attach( print_array2x5 => ['integer[10]'] => 'void' );
335             my $array = [5,10,15,20,25,30,35,40,45,50];
336             print_array2x5($array);
337              
338             Output:
339              
340             5 10
341             15 20
342             25 30
343             35 40
344             45 50
345              
346             B: Perl does not generally support multi-dimensional arrays
347             (though they can be achieved using lists of references). In Fortran,
348             multidimensional arrays are stored as a contiguous series of bytes, so
349             you can pass in a single dimensional array to a Fortran function or
350             subroutine assuming it has sufficent number of values.
351              
352             Platypus updates any values that have been changed by Fortran when the
353             Fortran code returns.
354              
355             One thing to keep in mind is that Fortran arrays are "column-first",
356             which is the opposite of C/C++, which could be termed "row-first".
357              
358             =head2 Variable-length array
359              
360             Fortran:
361              
362             ! On Linux gfortran -shared -fPIC -o libvar.so var.f90
363            
364             function sum_array(size,a) result(ret)
365             implicit none
366             integer :: size
367             integer, dimension(size) :: a
368             integer :: i
369             integer :: ret
370            
371             ret = 0
372            
373             do i=1,size
374             ret = ret + a(i)
375             end do
376             end function sum_array
377              
378             Perl:
379              
380             use FFI::Platypus;
381            
382             my $ffi = FFI::Platypus->new;
383             $ffi->lang("Fortran");
384             $ffi->lib("./libvar_array.so");
385            
386             $ffi->attach( sum_array => ['integer*','integer[]'] => 'integer',
387             sub {
388             my $f = shift;
389             my $size = scalar @_;
390             $f->(\$size, \@_);
391             },
392             );
393            
394             my @a = (1..10);
395             my @b = (25..30);
396              
397             print sum_array(1..10), "\n";
398             print sum_array(25..30), "\n";
399              
400             Output:
401              
402             55
403             165
404              
405             B: Fortran allows variable-length arrays. To indicate a
406             variable length array use the C<[]> notation without a length. Note
407             that this works for argument types, where Perl knows the length of an
408             array, but it will not work for return types, where Perl has no way of
409             determining the size of the returned array (you can probably fake it
410             with an C type and a wrapper function though).
411              
412             =head1 SUPPORT
413              
414             If something does not work as advertised, or the way that you think it
415             should, or if you have a feature request, please open an issue on this
416             project's GitHub issue tracker:
417              
418             L
419              
420             =head1 CONTRIBUTING
421              
422             If you have implemented a new feature or fixed a bug then you may make a
423             pull reequest on this project's GitHub repository:
424              
425             L
426              
427             Also Feel free to use the issue tracker:
428              
429             L
430              
431             This project's GitHub issue tracker listed above is not Write-Only. If
432             you want to contribute then feel free to browse through the existing
433             issues and see if there is something you feel you might be good at and
434             take a whack at the problem. I frequently open issues myself that I
435             hope will be accomplished by someone in the future but do not have time
436             to immediately implement myself.
437              
438             Another good area to help out in is documentation. I try to make sure
439             that there is good document coverage, that is there should be
440             documentation describing all the public features and warnings about
441             common pitfalls, but an outsider's or alternate view point on such
442             things would be welcome; if you see something confusing or lacks
443             sufficient detail I encourage documentation only pull requests to
444             improve things.
445              
446             Caution: if you do this too frequently I may nominate you as the new
447             maintainer. Extreme caution: if you like that sort of thing.
448              
449             =head1 SEE ALSO
450              
451             =over 4
452              
453             =item L
454              
455             The Core Platypus documentation.
456              
457             =item L
458              
459             Bundle Fortran with your FFI / Perl extension.
460              
461             =back
462              
463             =head1 AUTHOR
464              
465             Graham Ollis Eplicease@cpan.orgE
466              
467             =head1 COPYRIGHT AND LICENSE
468              
469             This software is copyright (c) 2015 by Graham Ollis
470              
471             This is free software; you can redistribute it and/or modify it under
472             the same terms as the Perl 5 programming language system itself.
473              
474             This software comes bundled with a forked version of L
475             called L.
476             L comes with this statement regarding its license:
477              
478             Copyright (c) 2001 by Karl Glazebrook. All rights reserved. This distribution
479             is free software; you can redistribute it and/or modify it under the same
480             terms as Perl itself.
481              
482             THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
483             OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
484             WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
485             ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
486             DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
487             DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
488             OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
489             HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
490             STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
491             IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
492             POSSIBILITY OF SUCH DAMAGE.
493              
494             BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
495             FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
496             OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
497             PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
498             EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
499             WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
500             THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS
501             WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
502             ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
503              
504             IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
505             WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
506             REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
507             DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
508             DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM
509             (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
510             INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
511             THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER
512             OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
513              
514             =cut
515