[Octopus-devel] [Octopus-notify] svn commit: r8566 - trunk/src/states by joseba

Tobias Burnus tobias.burnus at physik.fu-berlin.de
Wed Nov 16 16:59:47 WET 2011


On Wed, Nov 16, 2011 at 05:07:41PM +0100, Joseba Alberdi wrote:
>     I know it is not the most important part of the code, in fact is
>     only a memcpy. By the way, there is any implementation of C memcpy
>     in fortran? If so it would be much faster than any OpenMP
>     implementation. Otherwise we could also to wrap it form C.

Well, Fortran has TRANSFER which can be used as following:

integer, allocatable :: A(:), B(:)
allocate(A(10),B(10))
B(:)=[(i,i=1,10)]
A(:) = transfer(B,mold=A)
print *, A
end

Note: I used "A(:)" instead of "A = " to avoid the reallocation on
assignment check of Fortran 2003. Note further that there also a
size= argument exists.

Whether TRANSFER uses a loop or a memmove or memcopy internally, is
implementation dependent. And it also depends whether the compiler
knows that the memory is contiguous or not.

Actually, the same is true for a normal array assignment: The compiler
can replace it by a memcpy (or memmove) if it source and destination
are simply contiguous. In that sense, a TRANSFER might just obfuscate
the code and also disable type checking and part of the bounds checking.


Regarding memcpy: One can also call it without a C wrapper such as:

use iso_c_binding
implicit none
integer, allocatable, target :: A(:), B(:)
integer :: i

interface
  ! Note: Memory may not overlap
  ! Note: Return value ignored
  subroutine memcpy (dest, src, n) bind(C)
    import
    type(C_ptr), value :: dest, src
    integer(c_size_t), value :: n
  end subroutine memcpy
end interface

allocate(A(10),B(10))
B(:)=[(i,i=1,10)]
call memcpy (c_loc(A), c_loc(B), int(storage_size(A)/8*10,kind=c_size_t))
print *, A
end

Note: "storage_size" is a Fortran 2008 (!) intrinsic which returns the
size expressed in bits for an element of an array of type A. Except for
the storage_size() intrinsic, it should be valid Fortran 2003, though I
do not know which compilers support it. [GCC/gfortran supports
storage_size since 4.6 and C binding since 4.3] Given that full
Fortran 95 plus Technical Report 15581 seems to cause problems with
some Octopus compilers using F2003 features requires a configure check
and a fall-back implementation. Thus, a wrapper might easier if one
indeed want to use memcpy.

Note further that the TARGET attribute might hamper the alias analysis
of the compiler. (If one has a pointer from the beginning, it does not
really matter as the alias analysis is already hampered.)

Tobias


More information about the Octopus-devel mailing list