Skip to content

Fortran/C++ compatibility library #325

Open
@ivan-pi

Description

@ivan-pi

With the introduction of Fortran 2018 enhancements to interoperability with C it is possible to write C (and C++) code which interoperates with

  • optional dummy arguments
  • assumed-length character dummy arguments
  • assumed-shape arrays
  • allocatable dummy arguments
  • pointer dummy arguments

To handle such objects the standard introduced the concept of C descriptors which are defined in the header "ISO_Fortran_binding.h" header provided by the Fortran processor.

While very powerful, using these low-level tools to access Fortran objects feels clunky and error-prone. It would be nice to provide some higher level tools in the form of templated C++ wrapper classes. A similar concept is followed by the popular and fast-growing Rcpp library for R and C++ integration.

Here is a minimal example of such a wrapper class (kudos to @LKedward for helping me overcome a problem with C descriptor lifetimes in the Discourse thread) :

// fortran_array.cpp

#include "ISO_Fortran_binding.h"
#include <iostream>

template<typename T>
struct FortranArray {
  typedef T real_t;
 
  const void *base_addr;
  const CFI_dim_t *dim;

    const CFI_cdesc_t *obj; // A const reference to rank 2 Fortran array (can be discontiguous with regular strides).

    FortranArray(const CFI_cdesc_t *obj_) : : base_addr(obj_->base_addr), dim(obj_->dim) {}

    // Returns the i'th component of the j'th column in the array:
    inline T operator()(const size_t i, const size_t j) const {
        char *elt = (char *) base_addr;
        elt += (i*dim[0].sm + j*dim[1].sm);
        return *(T *) elt;
    }

    size_t size(const size_t d) {
        return obj->dim[d].extent;
    }

};

extern "C" {

void print_array(CFI_cdesc_t *array) {

    // View into a Fortran array
    FortranArray<double> a(array);

    for (size_t i = 0; i < a.size(0); i++) {
        for (size_t j = 0; j < a.size(1); j++) {
            std::cout << a(i,j) << " ";
        }
        std::cout << "\n";
    }
}

}

Given the popularity of C++ and it's strong presence in scientific computing, I think these tools would go a long way to increase adoption of Fortran as a viable co-language. Ideally, one would implement an STL-compatible container interface, allowing to use C++ algorithms directly on Fortran arrays.

A few questions:

  • Do you see benefit in tighter integration between Fortran and C++?
  • Do you think we can find support from the C++ community?
  • Should this go into a repository separate from stdlib?
  • Does it make sense to port the Fortran run-time library routines? (e.g. for a Fortran array living in C++, do we just call std::sin(array(i)) or a Fortran version fortran::sin(array(i)))

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestideaProposition of an idea and opening an issue to discuss ittopic: interfaceInterfacing with other libraries or languages

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions