From: James Van Buskirk on 3 Dec 2007 01:21 I am trying to use cray pointers to work around the limitations of certain compilers regarding procedure pointers. I read the documentation at http://gcc.gnu.org/onlinedocs/gfortran/Cray-pointers.html#Cray-pointers and came up with the following example: C:\gfortran\clf\sizes>type sizes1.f90 ! sizes1.f90 program sizes1 use ISO_C_BINDING implicit none integer(C_INT8_T) i1(0) type C_PTR_T type(C_PTR) data end type C_PTR_T type(C_PTR_T) s_C_PTR type F_PTR_S integer(C_INTPTR_T), pointer :: data end type F_PTR_S type(F_PTR_S) s_F_PTR_S type F_PTR_A integer(C_INTPTR_T), pointer :: data(:) end type F_PTR_A type(F_PTR_A) s_F_PTR_A interface function fptr(x) bind(C) use ISO_C_BINDING implicit none integer(C_INTPTR_T), value :: x integer(C_INTPTR_T) fptr end function fptr end interface type C_PTR_F type(C_FUNPTR) data end type C_PTR_F type(C_PTR_F) s_C_PTR_F type F_PTR_F pointer (data, fptr) end type F_PTR_F type(F_PTR_F) s_F_PTR_F integer(C_INTPTR_T) fval(*) type F_PTR_V pointer (data, fval) end type F_PTR_V type(F_PTR_V) s_F_PTR_V integer(C_INTPTR_T) sval type F_PTR_1 pointer (data, sval) end type F_PTR_1 type(F_PTR_1) s_F_PTR_1 write(*,'(a,i0)') 'size(C_PTR) = ', size(transfer(s_C_PTR, i1)) write(*,'(a,i0)') 'size(C_FUNPTR) = ', size(transfer(s_C_PTR_F, i1)) write(*,'(a,i0)') 'size(pointer=>scaler) = ', size(transfer(s_F_PTR_S, i1)) write(*,'(a,i0)') 'size(pointer=>vector) = ', size(transfer(s_F_PTR_A, i1)) write(*,'(a,i0)') 'size(cray=>function) = ', size(transfer(s_F_PTR_F, i1)) write(*,'(a,i0)') 'size(cray=>vector) = ', size(transfer(s_F_PTR_V, i1)) write(*,'(a,i0)') 'size(cray=>scalar) = ', size(transfer(s_F_PTR_1, i1)) end program sizes1 C:\gfortran\clf\sizes>C:\gfortran\win64\bin\x86_64-pc-mingw32-gfortran -std=f200 3 -Wall sizes1.f90 -fcray-pointer -osizes1 sizes1.f90:38.20: pointer (data, fptr) 1 Error: BIND(C) attribute conflicts with CRAY POINTEE attribute at (1) sizes1.f90:44.26: pointer (data, fval) 1 Error: Unexpected attribute declaration statement at (1) sizes1.f90:50.26: pointer (data, sval) 1 Error: Unexpected attribute declaration statement at (1) The last two error statements make sense in that every instance of type F_PTR_V or type F_PTR_1 would vie to define the address of fval or sval respectively. Perhaps the documentation could be tidied up a bit to reflect this. The first error, though, is a showstopper. I was hoping to be able to use cray pointers to work around the absence of procedure pointers, which may take a while to get implemented because the f03 standard gives them more capabilities than cray pointers have. It doesn't make any sense to me that cray pointers can't point at BIND(C) procedures and the documentation doesn't alert the programmer to this restriction. It leaves the programmer with no syntax for directly invoking a procedure obtained as a C_FUNPTR type. I tried a similar example with ifort and got errors like sizes2.f90(26) : Error: This statement is not permitted as a statement within a derived-type-def pointer (data, fptr) ------^ A little better error statement but again I couldn't find anything about this issue in ifort documentation. -- write(*,*) transfer([3.9435632276541913d180,6.013470016999177d-154], & ['x']);end
From: Steve Lionel on 3 Dec 2007 13:01 On Dec 3, 1:21 am, "James Van Buskirk" <not_va...(a)comcast.net> wrote: > I am trying to use cray pointers to work around the limitations of > certain compilers regarding procedure pointers. Cray pointers are not allowed as components of a derived type. The Cray-style POINTER declaration is not a type declaration, you can think of it as similar in concept to EQUIVALENCE - it establishes a relationship between a variable and an entity. If you want to store integer pointers in a derived type, you will have to declare it as an INTEGER of the size of an address (you can use ISO_C_BINDING's C_INTPTR_T for this.) To use it, you'll then assign the value stored in the component to a variable you have named in a POINTER statement. Steve
From: James Van Buskirk on 4 Dec 2007 06:47 "Steve Lionel" <steve.lionel(a)intel.com> wrote in message news:8b8597ba-55bf-4ac1-b01a-efeba687856e(a)j44g2000hsj.googlegroups.com... > Cray pointers are not allowed as components of a derived type. The > Cray-style POINTER declaration is not a type declaration, you can > think of it as similar in concept to EQUIVALENCE - it establishes a > relationship between a variable and an entity. As I said, it's possible to see this after reflection, it's just not stated as such in the documentation. Here's another thing I have been trying to achieve with cray pointers: from all I can tell from reading the documentation, it seems reasonable to put the pointee in a generic interface block (it can't be the name of a generic interface block, it's only going to be a specific function) so that I can change what the generic name does by pointing the pointer at different functions. Also, of course I'm going to put the pointer in a common block (the pointee can't be in a common block, but it's a function anyhow) so that I can have the pointer in different threads point to different functions because the common block will be declared THREADPRIVATE. C:\Program Files\Microsoft Visual Studio 8\James\clf\var_comp>type qsort.i90 ! File: qsort.i90 ! Public domain 2007 James Van Buskirk recursive subroutine qsort(x,N) integer, intent(in) :: N type(T) x(N) real harvest integer ipiv type(T) temp integer lo integer hi if(N <= 1) return call random_number(harvest) ipiv = min(int(harvest*N+1),N) temp = x(ipiv) x(ipiv) = x(1) x(1) = temp lo = 2 hi = N do while(lo <= hi) do lo = lo, hi if(.NOT. x(lo) <= x(1)) exit end do do hi = hi, lo, -1 if(x(hi) <= x(1)) exit end do if(lo < hi) then temp = x(lo) x(lo) = x(hi) x(hi) = temp lo = lo+1 hi = hi-1 end if end do temp = x(lo-1) x(lo-1) = x(1) x(1) = temp call qsort(x(1), lo-2) if(lo < N) call qsort(x(lo), N-lo+1) end subroutine qsort ! End of file: qsort.i90 C:\Program Files\Microsoft Visual Studio 8\James\clf\var_comp>type var_comp.f90 ! File: var_comp.f90 ! Public domain 2007 James Van Buskirk module mytype_mod implicit none type mytype integer x real y end type mytype interface assignment(=) module procedure assign_mytype end interface assignment(=) contains subroutine assign_mytype(x,y) type(mytype), intent(out) :: x type(mytype), intent(in) :: y x%x = y%x x%y = y%y end subroutine assign_mytype end module mytype_mod module compare_mytype_mod use mytype_mod implicit none private public operator(<=) interface operator(<=) function lessorequal(x,y) import mytype type(mytype), intent(in) :: x type(mytype), intent(in) :: y logical lessorequal end function lessorequal end interface operator(<=) pointer(loe, lessorequal) common /loecom/ loe !$OMP THREADPRIVATE( /loecom/ ) public set_cmp contains function cmpx(x,y) type(mytype), intent(in) :: x type(mytype), intent(in) :: y logical cmpx cmpx = x%x <= y%x end function cmpx function cmpy(x,y) type(mytype), intent(in) :: x type(mytype), intent(in) :: y logical cmpy cmpy = x%y <= y%y end function cmpy subroutine set_cmp(x) logical, intent(in) :: x if(x) then loe = loc(cmpx) else loe = loc(cmpy) end if end subroutine set_cmp end module compare_mytype_mod module mytype_qsort_mod use mytype_mod, T => mytype use compare_mytype_mod, only: operator(<=) implicit none contains include 'qsort.i90' end module mytype_qsort_mod module generic_recombination use qsort_mod, only: qsort_mytype => qsort end module generic_recombination program test use mytype_mod use compare_mytype_mod, only: set_cmp use generic_recombination implicit none type(mytype) x(10) real harvest integer i call random_seed() do i = 1, size(x) call random_number(harvest) x(i)%x = harvest*100 call random_number(harvest) x(i)%y = harvest end do write(*,*) 'Original array:' do i = 1, size(x) write(*,*) x(i) end do call set_cmp(.TRUE.) call qsort_mytype(x,size(x)) write(*,*) write(*,*) 'Array sorted by x:' do i = 1, size(x) write(*,*) x(i) end do call set_cmp(.FALSE.) call qsort_mytype(x,size(x)) write(*,*) write(*,*) 'Array sorted by y:' do i = 1, size(x) write(*,*) x(i) end do end program test ! End of file: var_comp.f90 C:\Program Files\Microsoft Visual Studio 8\James\clf\var_comp>ifort /Qopenmp var _comp.f90 Intel(R) Fortran Compiler for Intel(R) EM64T-based applications, Version 9.1 Build 20061104 Copyright (C) 1985-2006 Intel Corporation. All rights reserved. fortcom: Fatal: There has been an internal compiler error (C0000005). compilation aborted for var_comp.f90 (code 1) Oooh, yummy! Runs great! I still must not understand cray pointers... -- write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, & 6.0134700243160014d-154/),(/'x'/)); end
From: Richard Maine on 4 Dec 2007 11:21 James Van Buskirk <not_valid(a)comcast.net> wrote: > As I said, it's possible to see this after reflection, it's just not > stated as such in the documentation. Here's another thing I have > been trying to achieve with cray pointers: from all I can tell from > reading the documentation, it seems reasonable to put the pointee in > a generic interface block... The trouble here is that you are looking for extensions to an old feature that was never standard or particularly portable. There weren't any such things as interface blocks when Cray pointers were first developed. Heck, Cray pointers in most implementations can't point at procedures at all. I'd say that there isn't much payoff in a vendor implementing this kind of extension. It isn't as though there is any existing code at all that uses such an extension. There is probably a lot bigger payoff in getting the f2003 features in place. As for the documentation, well, of course in an ideal world I'm sure that the documentation should be better than whatever state it is in (that's pretty much true no matter what state it is in). But mostly, I recommend against using Cray pointers in new code except as a last resort interim expediency. And I double lthat disrecommendation for Cray pointers to procedures. I suspect you will find that the documentation of Cray pointers isn't going to keep expanding, just as the features of them aren't going to keep expanding. It is probably safer to assume that a Cray pointer can *NOT* be used anywhere except where the documentation explicitly says that it can. Otherwise, the documentation of each new feature would have to mention that you can't use Cray pointers there (which is usually going to be the case). For Cray pointers in interface blocks, the syntax should pretty much document that you can't use Cray pointers there because they don't fit in the syntax. The only things you can have in an interface block in f90/f95 are interface bodies and module procedure statements. Cray pointers aren't either of those. (F2003 also allows procedure statements, which is at least a little easier to see as potentially fitting). I'll not comment on the internal compiler error. -- Richard Maine | Good judgement comes from experience; email: last name at domain . net | experience comes from bad judgement. domain: summertriangle | -- Mark Twain
From: James Van Buskirk on 4 Dec 2007 12:51 "Richard Maine" <nospam(a)see.signature> wrote in message news:1i8l7w2.1ciwl9j13dmg4uN%nospam(a)see.signature... > For Cray pointers in interface blocks, the syntax should pretty much > document that you can't use Cray pointers there because they don't fit > in the syntax. The only things you can have in an interface block in > f90/f95 are interface bodies and module procedure statements. Cray > pointers aren't either of those. (F2003 also allows procedure > statements, which is at least a little easier to see as potentially > fitting). C:\gfortran\clf\alloc_cray>type alloc_cray.f90 ! File: alloc_cray.f90 ! Public domain 2007 James Van Buskirk module mod1 implicit none interface zarp subroutine can_alloc(x) implicit none integer, allocatable :: x(:) end subroutine can_alloc end interface zarp pointer(ptr, can_alloc) end module mod1 module mod2 implicit none integer N contains subroutine alloc_me(x) integer, allocatable :: x(:) allocate(x(N)) end subroutine alloc_me subroutine dealloc_me(x) integer, allocatable :: x(:) deallocate(x) end subroutine dealloc_me end module mod2 program test use mod1 use mod2 integer i integer, allocatable :: x(:) N = 10 ptr = loc(alloc_me) call zarp(x) x = [(2*i-1, i = 1, size(x))] do i = 1, size(x) write(*,'(2(a,i0))') 'x(',i,') = ',x(i) end do ptr = loc(dealloc_me) write(*,*) allocated(x) call zarp(x) write(*,*) allocated(x) end program test ! End of file: alloc_cray.f90 C:\gfortran\clf\alloc_cray>C:\gfortran\win64\bin\x86_64-pc-mingw32-gfortran -Wal l -fcray-pointer alloc_cray.f90 -oalloc_cray C:\gfortran\clf\alloc_cray>alloc_cray x(1) = 1 x(2) = 3 x(3) = 5 x(4) = 7 x(5) = 9 x(6) = 11 x(7) = 13 x(8) = 15 x(9) = 17 x(10) = 19 T F C:\gfortran\clf\alloc_cray>ifort alloc_cray.f90 Intel(R) Fortran Compiler for Intel(R) EM64T-based applications, Version 9.1 Build 20061104 Copyright (C) 1985-2006 Intel Corporation. All rights reserved. Microsoft (R) Incremental Linker Version 8.00.40310.39 Copyright (C) Microsoft Corporation. All rights reserved. -out:alloc_cray.exe -subsystem:console alloc_cray.obj C:\gfortran\clf\alloc_cray>alloc_cray x(1) = 1 x(2) = 3 x(3) = 5 x(4) = 7 x(5) = 9 x(6) = 11 x(7) = 13 x(8) = 15 x(9) = 17 x(10) = 19 T F -- write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, & 6.0134700243160014d-154/),(/'x'/)); end
|
Next
|
Last
Pages: 1 2 Prev: Formatted stream I/O Next: multi-threaded FFTW segmentation fault with gfortran |