- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am testing different ways for some structures and I want to now if its possible to use the interfaces "molding" for change the arguments, like an array of pointers using an array of integer(kind=C_INT_PTR).
I am trying with this code and work well, but I'm not sure if is safe or can produce problems in the optimization process (inlining, perfomance, ...)
!----------------------------------------------------------
! x86_64
#define C_INT_PTR 8
#define REAL_KIND 8
module real_pointer
implicit none
public
type real_t
real(REAL_KIND) :: v1, v2
end type real_t
type real_p
type(real_t), pointer :: p
end type real_p
end module real_pointer
!----------------------------------------------------------
program test_pointer
use real_pointer
integer, parameter :: n = 10
integer(C_INT_PTR), dimension(n) :: p_array
real(REAL_KIND), dimension(2,n) :: r_array
integer :: i
interface
integer(C_INT_PTR) function MyLoc( value )
real(REAL_KIND), dimension(:), intent(in) :: value
end function MyLoc
subroutine print_pointer_array( n, i_array )
integer, intent(in) :: n
integer(C_INT_PTR), intent(in) :: i_array(n)
end subroutine print_pointer_array
end interface
do i = 1, n
call random_number(r_array(:,i))
end do
do i = 1, n
p_array(i) = MyLoc(r_array(:,i))
end do
call print_pointer_array(n,p_array)
end program test_pointer
!----------------------------------------------------------
integer(C_INT_PTR) function MyLoc( address )
integer(C_INT_PTR), intent(in) :: address
MyLoc = address
end function MyLoc
!----------------------------------------------------------
subroutine print_pointer_array( n, parray )
use real_pointer
integer, intent(in) :: n
type(real_p), dimension(n), intent(in) :: parray
integer :: i
do i = 1, n
print*,parray(i)%p
end do
end subroutine print_pointer_array
!----------------------------------------------------------
Thanks!
I am testing different ways for some structures and I want to now if its possible to use the interfaces "molding" for change the arguments, like an array of pointers using an array of integer(kind=C_INT_PTR).
I am trying with this code and work well, but I'm not sure if is safe or can produce problems in the optimization process (inlining, perfomance, ...)
!----------------------------------------------------------
! x86_64
#define C_INT_PTR 8
#define REAL_KIND 8
module real_pointer
implicit none
public
type real_t
real(REAL_KIND) :: v1, v2
end type real_t
type real_p
type(real_t), pointer :: p
end type real_p
end module real_pointer
!----------------------------------------------------------
program test_pointer
use real_pointer
integer, parameter :: n = 10
integer(C_INT_PTR), dimension(n) :: p_array
real(REAL_KIND), dimension(2,n) :: r_array
integer :: i
interface
integer(C_INT_PTR) function MyLoc( value )
real(REAL_KIND), dimension(:), intent(in) :: value
end function MyLoc
subroutine print_pointer_array( n, i_array )
integer, intent(in) :: n
integer(C_INT_PTR), intent(in) :: i_array(n)
end subroutine print_pointer_array
end interface
do i = 1, n
call random_number(r_array(:,i))
end do
do i = 1, n
p_array(i) = MyLoc(r_array(:,i))
end do
call print_pointer_array(n,p_array)
end program test_pointer
!----------------------------------------------------------
integer(C_INT_PTR) function MyLoc( address )
integer(C_INT_PTR), intent(in) :: address
MyLoc = address
end function MyLoc
!----------------------------------------------------------
subroutine print_pointer_array( n, parray )
use real_pointer
integer, intent(in) :: n
type(real_p), dimension(n), intent(in) :: parray
integer :: i
do i = 1, n
print*,parray(i)%p
end do
end subroutine print_pointer_array
!----------------------------------------------------------
Thanks!
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Wow - That is really cool!
So by declaring the interface to be different from the actual function myloc - you can access the actual pointer address - That is fantastic!
Any idea about how robust it is? I see no one else has replied?
I have a much simpler question for you. I am working on a large numerical ocean model, FVCOM. All of the data arrays are declared allocatable, but not target. I can trick fortran (ifort) into letting me assign a pointer if I pass the pointer and the allocatable to a subroutine which 'adds' the target attribute to the allocatable input and then returns the pointer - Is this safe?
This can be particularly useful for arrays which are part of a derived type since you can not give the components of a derived type the target attribute where it is not convienent to make the variable a pointer to begin with.
David
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am waiting for some reply...
For your question, I think you not need this trick with the interfaces. You can pass the allocatable array directly to a function with target attribute and assign a pointer directly.
function assign_pointer(a)
type(mytype), dimension(:), target, intent(in) :: a
type(mytype), dimension(:), pointer :: assign_pointer
assign_pointer => a
end function assign_pointer
I am waiting for some reply...
For your question, I think you not need this trick with the interfaces. You can pass the allocatable array directly to a function with target attribute and assign a pointer directly.
function assign_pointer(a)
type(mytype), dimension(:), target, intent(in) :: a
type(mytype), dimension(:), pointer :: assign_pointer
assign_pointer => a
end function assign_pointer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Take a look at the intrinsic module ISO_C_BINDING and the C_F_POINTER routine it provides, available in 10.0. This has a SHAPE argument that helps do what you're trying for here.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I know the iso_c_binding, but the question is: the type(c_ptr) is equivalent to integer(c_int_ptr) ?? and, can you say something about the performance of this module??
The second question is about the change of interfaces. Is bad for the performance?
I can pass an 2D array A(n,n) like a vector B(n*n), but I don't know if is good or not.
The second question is about the change of interfaces. Is bad for the performance?
I can pass an 2D array A(n,n) like a vector B(n*n), but I don't know if is good or not.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, type c_ptr is a derived type, not a simple integer, though the internal representation is the same. The module is quite simple - you can actually read the source, though some of the routines use undocumented attributes to make things work right.
There's no problem passing a 2D array as a 1D array if the storage is the same, though that's a rank mismatch that will trigger a complaint from the compiler. You can get around it by passing A(1,1) which will be allowed for an array dummy argument of any rank.
There's no problem passing a 2D array as a 1D array if the storage is the same, though that's a rank mismatch that will trigger a complaint from the compiler. You can get around it by passing A(1,1) which will be allowed for an array dummy argument of any rank.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page