Coder Social home page Coder Social logo

fcpp's Introduction

Fcpp

Seamless interoperability between C++ containers and Fortran arrays

We provides two classes: cdesc and cdesc_ptr. These classes act as adaptors between C++ containers and Fortran arrays, helping to re-establish type, rank and attribute safety when moving between languages.

The classes also offer some of the friendlier C++ semantics for manipulating collections of items, including:

  • iterators
  • range-based for loops
  • subscript operators

This way you can use algorithms from the C++ Standard Template Library.

โš ๏ธ This library is currently at prototype stage. We are working on a making a first release soon.

cdesc

The purpose of this class is to pass native C++ containers such as std::vector, std::array, and std::span to routines implemented in Fortran that use assumed-shape arrays as dummy arguments. The cdesc class manages the descriptor which is used for interoperation, however the actual data or storage remains under the ownership of some native C++ object.

Use the cdesc class when you have a (contiguous) C++ container that you need to pass to Fortran routine marked with bind(c). An example of what this may look like is:

#include "Fcpp.h"
using namespace Fcpp;

extern "C" void process_floats_in_fortran(CFI_cdesc_t * /* a */ );
// ...
std::vector<float> a(21);
// ...
{
   cdesc f_a(a); // CTAD
   process_floats_in_fortran(f_a);
}

cdesc_ptr

The purpose of this class is to help implement procedures in C++, which are designed to be called from Fortran. In such cases you will be passing a pointer to a C descriptor across the language barrier.

When you need to perform some operations on Fortran arrays, but the implementation would be easier to perform in C++, use the cdesc_ptr class.

interface
   subroutine process_ints(b) bind(c,name="process_ints")
      use, intrinsic :: iso_c_binding, only: c_int
      integer(c_int) :: b(:) ! <- could be non-contiguous
   end subroutine
end interface

integer :: b(21)
call process_ints(b)

Calling a Fortran routine from C++

! A wrapper of the Fortran dot_product routine
function dot(a,b) bind(c,name='f_dot')
real(c_double), intent(in) :: a(:), b(:)
real(c_double) :: dot
intrinsic :: dot_product
dot = dot_product(a,b)
end function
#include <array>
#include <iostream>

#include "Fcpp.h"
using namespace Fcpp;

extern "C" [[nodiscard]]
double f_dot(CFI_cdesc_t *fa, CFI_cdesc_t *fb);

int main() {
    
   std::array<double,3> a{1.,2.,3.}; 
   std::vector<double> b;

   b.emplace_back(1.0);
   b.emplace_back(2.0);
   b.emplace_back(3.0);

   double d;
   
   {
      const cdesc_t fa(a); // CTAD
      const cdesc_t fb(b); // CTAD

      // 1^2 + 2^2 + 3^2 = 1 + 4 + 9 = 14
      d = f_dot(fa,fb);
   }

   std::cout << "dot(a,b) = " << d << '\n';
   
   return 0;
}

Calling a C++ routine from Fortran

Purposes of the adapter class template:

  • re-establish type, rank and attributes (interface checking)
  • conversions to C++ reference classes such as std::span
  • easily modify the allocation status
#include <numeric>

#include "Fcpp.h"
using namespace Fcpp;

extern "C" {
    
void fill_increasing(CFI_cdesc_t* fa, int start) {
   cdesc_ptr<int,1> a(fa);
   std::iota(a.begin(),a.end(),start);
}

}
program fill
implicit none
interface
   subroutine fill_increasing(vec,start) bind(c)
      use, intrinsic :: iso_c_binding, only: c_int
      integer(c_int), intent(inout), contiguous :: vec(:)
      integer(c_int), value :: start
   end subroutine
end interface

integer(c_int) :: a(5), b(6)

call fill_increasing(a,-2)
call fill_increasing(b(1::2),0)

write(*,*) a

end program

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.