Skip to content
New issue

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

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

Already on GitHub? # 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)

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

No branches or pull requests

1 participant