Prev: C++ / Fortran interoperability
Next: Problem with automatic reallocation of allocatable scalar on assignment
From: James on 5 Aug 2010 19:16 Hi, Using c_f_pointer I can use memory allocated in C routines within fortran. For instance: program malloc_example use, intrinsic :: iso_c_binding implicit none interface type(c_ptr) function malloc(ksize) bind(c) use, intrinsic :: iso_c_binding implicit none integer(c_size_t), value :: ksize end function malloc subroutine free(p) bind(c) use, intrinsic :: iso_c_binding implicit none type(c_ptr), value, intent(in) :: p end subroutine free end interface real(c_float), pointer :: tmp(:,:) type (c_ptr) :: tmp_ptr integer :: r, c tmp_ptr = malloc(int(4*2*2,kind=c_size_t)) call c_f_pointer(tmp_ptr, tmp, (/ 2, 2 /)) write (6,*) lbound(tmp) write (6,*) ubound(tmp) do r = 1, ubound(tmp, 1) do c = 1, ubound(tmp, 2) tmp(r, c) = r * 10 + c end do end do print '(f10.5)', tmp call free(tmp_ptr) end program malloc_example Is there a (standards-compliant) way to set the fortran pointer to have lower bounds other than 1? I found a discussion from 2 years ago (http://objectmix.com/fortran/632212-pointer-arithmetic- c_f_pointer.html) where Steve Lionel says the pointers can be given alternate bounds, but I can't figure out how to do this... Many thanks, --James
From: Richard Maine on 5 Aug 2010 19:48 James <james.s.spencer(a)gmail.com> wrote: > Using c_f_pointer I can use memory allocated in C routines within > fortran. .... > Is there a (standards-compliant) way to set the fortran pointer to > have lower bounds other than 1? ... > where Steve Lionel says the pointers can be given > alternate bounds, but I can't figure out how to do this... You can't directly in c_f_pointer. I think I recall someone once asking for that as an enhancement to c_f_pointer. On the surface, it seems to me like a reasonable enhancement, so I checked the f2008 FDIS to see if it happened to have been done there. Doesn't look like it. Seems to me like a good example of the kind of question that is bound to pop up after people get some real experience with f2003 - i.e. the kind of thing I wanted f2008 to wait for (but I lost that one). You can use an allocate statement to create pointers with lower bounds other than 1. The syntax for that is obvious enough that I'd expect people to be able to guess it (assuming they knew how to use an allocate statement otherwise), but it won't help with allocaions done in C. You can also get a pointer with lower bounds other than 1 by argument association with or pointer assignment to something with lower bounds other than 1. But again, those don't directly apply to things allocated in C. The one other way I can think of off the top of my head can apply to pointers allocated from C, but you have to do it in 2 steps. First use c_f_pointer to get a Fortran pointer, which wil have lower bounds of 1. Then use a pointer assignment statement with a bounds-spec list, as in new_pointer(0:,0:) => old_pointer That's assuming you might want lower bounds of 0 to match C conventions. Substitute other desired bounds and ranks as desired. Note that this form of pointer assignment syntax is an f2003 feature. An f95 compiler won't necessarily have it, though most f95 compilers today have at least some f2003 features, so you might be lucky. C_f_pointer is also an f2003 feature, so if you are using that, your compiler does have at least some f2003 features and it seems reasonable to hope for the pointer assignment form. As such things go, this doesn't seem a particularly difficult one to implement. (Not that I'm an implementor to know for sure, but that's my guess). -- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain
From: Ron Shepard on 6 Aug 2010 01:14 In article <1jmrf0p.mpqer1azvjnkN%nospam(a)see.signature>, nospam(a)see.signature (Richard Maine) wrote: > The one other way I can think of off the top of my head can apply to > pointers allocated from C, but you have to do it in 2 steps. First use > c_f_pointer to get a Fortran pointer, which wil have lower bounds of 1. > Then use a pointer assignment statement with a bounds-spec list, as in > > new_pointer(0:,0:) => old_pointer > > That's assuming you might want lower bounds of 0 to match C conventions. > Substitute other desired bounds and ranks as desired. > > Note that this form of pointer assignment syntax is an f2003 feature. An > f95 compiler won't necessarily have it, though most f95 compilers today > have at least some f2003 features, so you might be lucky. You did not mention the other option, which does work for f95 (and later). ... call assign2d( old_pointer 0, 0, new_pointer ) ... subroutine assign2d( old_pointer, lb1, lb2, new_pointer ) integer, intent(in) :: lb1, lb2 real, pointer, intent(inout):: new_pointer(:,:) real, intent(in), target :: old_pointer(lb1:,lb2:) new_pointer => old_pointer return I did not compile this, and it is just from memory, but I think I got most of this right. After return, this has the same result as the above f2003 assignment statement. You need a subroutine like this for all of your data types and kinds, and for all ranks that you use. $.02 -Ron Shepard
From: Richard Maine on 6 Aug 2010 01:59 Ron Shepard <ron-shepard(a)NOSPAM.comcast.net> wrote: > In article <1jmrf0p.mpqer1azvjnkN%nospam(a)see.signature>, > nospam(a)see.signature (Richard Maine) wrote: > > Note that this form of pointer assignment syntax is an f2003 feature. An > > f95 compiler won't necessarily have it, though most f95 compilers today > > have at least some f2003 features, so you might be lucky. > > You did not mention the other option, which does work for f95 (and > later). > > ... > call assign2d( old_pointer 0, 0, new_pointer ) > ... Ah. Forgot about that option. Thatks for the reminder. I did think about (and mention) argument association, but I forgot about that kind of trick. I get confused about the fine points of when a pointer to a dummy argument really point sto the actual argument (and thus is guaranteed to persist after the call), but you are probbaly right. -- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain
From: Ron Shepard on 6 Aug 2010 02:25 In article <1jmrx01.ddfd7zs8fs8uN%nospam(a)see.signature>, nospam(a)see.signature (Richard Maine) wrote: > Ron Shepard <ron-shepard(a)NOSPAM.comcast.net> wrote: > > > In article <1jmrf0p.mpqer1azvjnkN%nospam(a)see.signature>, > > nospam(a)see.signature (Richard Maine) wrote: > > > > Note that this form of pointer assignment syntax is an f2003 feature. An > > > f95 compiler won't necessarily have it, though most f95 compilers today > > > have at least some f2003 features, so you might be lucky. > > > > You did not mention the other option, which does work for f95 (and > > later). > > > > ... > > call assign2d( old_pointer 0, 0, new_pointer ) > > ... > > Ah. Forgot about that option. Thatks for the reminder. I did think about > (and mention) argument association, but I forgot about that kind of > trick. I get confused about the fine points of when a pointer to a dummy > argument really point sto the actual argument (and thus is guaranteed to > persist after the call), but you are probbaly right. Yes, that is the part I was unsure of also. That is, should the old_pointer(lb1:,lb2:) dummy declaration have a pointer or a target attribute? I think it is a target, but I'm not 100% sure. It is not possible to simply compile an example because it is most likely to work in either case, but the standard only requires it to work with certain combinations of attributes and intents. The thing that needs to be avoided is the possibility of copy-in/copy-out for the old_pointer(:,:) array. For a particular compiler, you can verify that copy-in/copy-out has not occurred by using either the nonstandard loc() function or the newer c_loc version, the latter of which might make sense since c interoperability is already being used for other aspects of the program. You can also use this trick to assign a 2D pointer to a 1D array. It almost always works "correctly" (and it can be verified with the loc() test), but I'm pretty sure that this version is nonstandard. However, if I remember correctly f2008 does extend pointer assignment to these cases in a standard conforming way. $.02 -Ron Shepard
|
Next
|
Last
Pages: 1 2 Prev: C++ / Fortran interoperability Next: Problem with automatic reallocation of allocatable scalar on assignment |