Stl Analogue in Fortran

STL analogue in Fortran

There are no templates in Fortran and hence no STL. You can try FLIBS for some generic libraries. It generally uses transfer() tricks to achieve generic programming.

There is a preprocessor which adds some templates to Fortran and comes with some small STL, you can try that too named PyF95++. If you have access to academic papers through some library, you can read about it here.

I would avoid mixing it with C++ in this specific case although it can be done. You must instantiate each case separately and interface it to Fortran using a wrapper (bind(C) and iso_c_binding). Only if you have a very limited number of types you want to use the algorithms for it could be worth it.

You can also try to implement some poor-man's templates using the C-preprocessors in Fortran, For smaller libraries it works, but can become too difficult to maintain or ugly for complex things. As an example you can see my implementation of a linked list https://github.com/LadaF/fortran-list .

Generally, there is no clearly right approach or answer, you always have to choose from more possibilities.

Writing optimal code in FORTRAN using array expressions

I have scanned many sources (~20 books and dozens of web pages). Hard luck I missed something really important. The question I posted is indeed incorrect and comes from my initial high expectation about array operations in fortran.

The answer I would expect is: there are no tools to write short, readable code in fortran with automatic parallelization (to be more precise: there are, but those are proprietary libraries).

The list of intrinsic functions available in fortran is quite short
(link), and consists only of functions easily mapped to SIMD ops.

There are lots of functions that one will be missing.

  • while this could be resolved by separate library with separate implementation for each platform, fortran doesn't provide such. There are commercial options (see this thread)

Brief examples of missing functions:

  • no built-in array sort or unique. The proposed way is to use this library, which provides single-threaded code (forget threads and CUDA)

  • cumulative sum / running sum. One trivially can implement it, but the resulting code will never work fine on threads/CUDA/Xeon Phi/whatever comes next.

  • bincount, numpy.ufunc.at, numpy.ufunc.reduceat (which is very useful in many applications)

In most cases fortran provides 2x speed up even with simple implementations, but the code written will always be one-threaded, while matlab/numpy functions can be reimplemented for GPU or other parallel platform without any effort from user side (which occasionally happened to MATLAB, also see gnumpy, theano and parakeet)

To conclude, this is bad news for me. Fortran developers really care about having fast programs today, not in the future. I also can't lock my code on proprietary software. And I'm still looking for appropriate tool. (Julia is current candidate)

See also:

  • STL analogue in fortran
    where ready-to-use algorithms are asked.

  • Numerical recipes: the art of parallel programming author implements basic MATLAB-like operations to have more expressive code

  • I also find useful these notes to see recommended ways of code optimizations (to see there is no place for vector operations)

  • numpy, fortran, blitz++: a case study

  • dicussion about implementing unique in fortran, where proprietary tools are recommended.

Fortran: Handling types with different kind in generic procedures

No, it is not possible. Not even with parametrized derived types.

You must manually create each specific procedure. There are many tricks with preprocessors which can assist you to do some poor-man's C++-like tempting. Examples can be found even on StackOverflow. See, among others, STL analogue in Fortran .

Two derived types sharing same subroutine

Error messages are, admittedly, not always helpful. In this case it is a good prompt.

Your derived type Interval has a type-bound procedure with binding name eptset and interface the same as the procedure inrval_set. This is your difficulty.

I imagine you have in mind a call like

type(Interval) range
call range%eptset(1._real32, 15._real32)

which is a reasonable goal.

However, you are relying on a passed-object dummy argument, so that in inrval_set your first dummy argument t is of dynamic type range. This is flawed.

As the error message suggests, the interface for the type-bound procedure in Interval must, because it doesn't have the NOPASS attribute, have a dummy argument of type Interval. A dummy argument of class(*) is not such a thing.

You don't want to do this approach using NOPASS.

You could, of course, have

call inrval_set(range, 1._real32, 15._real32)

as one option. But are there type-bound ways?

Yes.

You could consider templating. Or, have an (abstract) parent class. Or provide type-bound procedures with the appropriate interface - one for each type.

Essentially, you're repeating code in the select type block, so you may as well repeat the code with generic/dynamic resolution instead.



Related Topics



Leave a reply



Submit