Description
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 versionfortran::sin(array(i))
)