Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement automatic converters for ArrayView and ArrayRCP #163

Open
aprokop opened this issue Dec 15, 2017 · 1 comment
Open

Implement automatic converters for ArrayView and ArrayRCP #163

aprokop opened this issue Dec 15, 2017 · 1 comment

Comments

@aprokop
Copy link
Collaborator

aprokop commented Dec 15, 2017

Right now, I put a bunch of manual wrapper functions for those implementing essentially the same thing. Need to alias ArrayView<T> to std::pair<T*,size_t> which should reduce the amount of code.

@aprokop
Copy link
Collaborator Author

aprokop commented Dec 21, 2017

According to @sethrj:

You could write typemaps that convert arrayview to and from fortran array pointers (basically a modification of the std::pair code in typemaps.i), but that would prevent you from being able to use any of the other functionality in the ArrayView class

//---------------------------------*-SWIG-*----------------------------------//
%{
#include "Teuchos_ArrayView.hpp"
%}
namespace Teuchos
{
template<class T>
class ArrayView {
};
}
//---------------------------------------------------------------------------//
// ARRAY TYPES
//
// This maps a return value of pair<T*,size_t> to a small struct (mirrored in
// fortran) that defines the start and size of a contiguous array.
//
//---------------------------------------------------------------------------//
%define FORT_VIEW_TYPEMAP_IMPL(FTYPE, CONST_CTYPE...)
  #define CPP_TYPE Teuchos::ArrayView< CONST_CTYPE*, std::size_t >
  #define AW_TYPE swig::SwigfArrayWrapper< CONST_CTYPE >
  // C wrapper type: pointer to templated array wrapper
  %typemap(ctype, noblock=1, out=%str(swig::SwigfArrayWrapper< CONST_CTYPE >),
           null=%str(swig::SwigfArrayWrapper< CONST_CTYPE >()),
           fragment="SwigfArrayWrapper") CPP_TYPE
    {AW_TYPE*}
  // C input initialization typemaps
  %typemap(arginit, noblock=1) CPP_TYPE
    {$1 = CPP_TYPE();}
  // C input translation typemaps: $1 is CPP_TYPE, $input is AW_TYPE
  %typemap(in) CPP_TYPE
    { $1 = AW_TYPE($input->data, $input->size); }
  // C output initialization
  %typemap(arginit) AW_TYPE
    %{$1.data = NULL;
      $1.size = 0;%}
  // C output translation typemaps: $1 is CPP_TYPE, $input is AW_TYPE
  %typemap(out) CPP_TYPE
    %{$result.data = $1->getRawPtr();
      $result.size = $1->getSize();%}
  // Interface type: fortran equivalent of "ctype"
  // Optional "in" is for when it's an argument of the wrapper declaration; the
  // main typemap `type(SwigfArrayWrapper)` is used as a temporary variable
  // in the fortran proxy code
  %typemap(imtype, in="type(SwigfArrayWrapper)") CPP_TYPE
     "type(SwigfArrayWrapper)"
  // Since the SwigfArrayWrapper type is declared in the module, it's necessary
  // to "import" the variable in the interface declaration.
  %typemap(imimport, fragment="SwigfArrayWrapper") CPP_TYPE
    "SwigfArrayWrapper"
  // Fortran proxy code: "out" is when it's a return value;
  // the main type is when it's an input value
  %typemap(ftype, out=FTYPE ", dimension(:), pointer") CPP_TYPE
    FTYPE ", dimension(:), target, intent(inout)"
  // Fortran proxy translation code: convert from ftype $input to imtype $1
  // Note that we take the address of the first element instead of the array,
  // because nonallocatable deferred-size arrays *cannot* be referenced in
  // standard F2003. This is because they might be slices of other arrays
  // (noncontiguous). It is the caller's responsibility to ensure only
  // contiguous arrays are passed. Conceivably we could improve this to use
  // strided access by also passing c_loc($input(2)) and doing pointer
  // arithmetic.
  %typemap(fin) CPP_TYPE
    %{$1%data = c_loc($input(1))
      $1%size = size($input)%}
  // Instantiate type so that SWIG respects %novaluewrapper
  %template() CPP_TYPE;
  // Fortran proxy translation code: convert from imtype 1 to ftype $result
  %typemap(fout) CPP_TYPE
  %{
      call c_f_pointer($1%data, $result, [$1%size])
  %}
  #undef CPP_TYPE
  #undef AW_TYPE
%enddef
// Declare wrapper functions for Teuchos::ArrayView<T*,size_t> and <const T*, ...>
%define FORT_ARRAY_VIEW_TYPEMAP(FTYPE, CTYPE)
    FORT_VIEW_TYPEMAP_IMPL(FTYPE, CTYPE)
    FORT_VIEW_TYPEMAP_IMPL(FTYPE, const CTYPE)
%enddef
// Macro for defining the typemaps inside a class (e.g. std_vector to allow
// automatic view support), so that the fragments and typemaps are only used as
// needed
%define %fortran_array_view(CTYPE)
    FORT_ARRAY_VIEW_TYPEMAP("$typemap(imtype, " #CTYPE ")", CTYPE)
%enddef

so this won't replace the std::pair typemaps, just supplement them. If you want to reduce the code a little, you can use

%apply std::pair<T*, size_t> { Tpetra::ArrayView<T>

but you'll still have to manually override the C++->Fortran translation code (replacing the .first and .second stuff with size, data, etc)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant