From: Tobias Burnus on 16 Oct 2009 04:48 On 10/16/2009 07:01 AM, James Van Buskirk wrote: > elemental function my_dcos(x) > [...] > call test(my_dcos) > 1 > Error: ELEMENTAL non-INTRINSIC procedure 'my_dcos' is not allowed as an > actual argument at (1) That error is correct per: "C1228 (R1221) A nonintrinsic elemental procedure shall not be used as an actual argument." (F2003) Same wording is in F2008 (C1233) and F95 (in Section 12.4). (I find it interesting that NAG f95 allows it as "Extension: ...", I always thought that it is an extremely strict compiler with almost no legacy extensions. [ifort allows it a well (it prints a warning with -stand f03).]) > So we can fix this: > > function my_dcos(x) > [...] > subroutine test(fun) > interface > elemental function fun(x) > > dcos.f90(33) : Error: The ELEMENTAL attribute of the associated actual > procedure differs from the ELEMENTAL attribute of the dummy procedure. [MY_DCOS] Even without looking at the standard, it makes sense that passing a non-PURE, non-ELEMENTAL procedure to a PURE and ELEMENTAL dummy is not a good idea. The standard has (F2003, in 12.4.1.3 Actual arguments associated with dummy procedure entities): "If the interface of the dummy argument is explicit, the characteristics listed in 12.2 shall be the same for the associated actual argument and the corresponding dummy argument, except that a pure actual argument may be associated with a dummy argument that is not pure and an elemental intrinsic actual procedure may be associated with a dummy procedure" Thus that "ifort" rejects it is OK. I filled a bug report (PR41724) for gfortran which does not detect this. > Now with DCOS, all this just works: > > C:\gfortran\clf\dcos>type dcos.f90 > subroutine test(fun) > interface > elemental function fun(x) > [...] > intrinsic dcos > call test(dcos) Is this actually valid or not? If I quote again from "12.4.1.3" but include the trailing parentheses: "an elemental intrinsic actual procedure may be associated with a dummy procedure (which is prohibited from being elemental)." The "which is prohibited" or as F2008 has it "(which cannot be elemental).", implies that "interface; elemental function fun" is already invalid. Actually, I failed to find this restriction elsewhere in the standard. As the parenthesis is normative, it should be enough, still - especially the "cannot" somehow implies that this restriction is listed elsewhere explicitly. Tobias
From: James Van Buskirk on 16 Oct 2009 11:38 "Tobias Burnus" <burnus(a)net-b.de> wrote in message news:4AD8335E.2030401(a)net-b.de... > On 10/16/2009 07:01 AM, James Van Buskirk wrote: >> Now with DCOS, all this just works: >> C:\gfortran\clf\dcos>type dcos.f90 >> subroutine test(fun) >> interface >> elemental function fun(x) >> [...] >> intrinsic dcos >> call test(dcos) > Is this actually valid or not? If I quote again from "12.4.1.3" but > include the trailing parentheses: > "an elemental intrinsic actual procedure may be associated with a dummy > procedure (which is prohibited from being elemental)." > The "which is prohibited" or as F2008 has it "(which cannot be > elemental).", implies that "interface; elemental function fun" is > already invalid. > Actually, I failed to find this restriction elsewhere in the standard. > As the parenthesis is normative, it should be enough, still - especially > the "cannot" somehow implies that this restriction is listed elsewhere > explicitly. I read this as some sort of problem with the standard. At least it says that it lets you pass DCOS as an actual argument without having to declare the dummy argument as elemental, which would break codes dating back to at least f77. It could be that whoever wrote the quoted paragraph assumed that for a dummy argument to be elemental was generally prohibited without actually checking, or that the prohibition existed in a previous draft but was dropped but not fixed in the quoted paragraph. I can't see why the prohibition against passing a nonintrinsic elemental procedure as an actual argument exists anyhow. It seems to me that elemental procedures are deprecated at birth as a result, and they seem more useful to me than to deserve such a fate. You know, there is a similar restriction regarding procedure pointers: C:\gfortran\clf\dcos>type ptr.f90 module funcs implicit none integer, parameter :: dp = kind(1.0d0) abstract interface elemental function fun(x) import implicit none real(dp), intent(in) :: x real(dp) fun end function fun end interface contains ! function my_dcos(x) elemental function my_dcos(x) ! integer :: dp = kind(1.0d0) !-- Or USE an appropriate module integer, parameter :: dp = kind(1.0d0) !-- Or USE an appropriate module real(dp), intent(in) :: x real(dp) :: my_dcos my_dcos = cos(x) return ! end end function end module funcs program start use funcs implicit none procedure(fun), pointer :: f real(dp) x(3) ! intrinsic dcos x = [1,2,3] f => my_dcos ! f => dcos write(*,*) f(x) end program start C:\gfortran\clf\dcos>gfortran -Wall ptr.f90 -optr C:\gfortran\clf\dcos>ptr 0.54030230586813976 -0.41614683654714241 -0.98999249660044542 Whoops, gfortran let this one slide! OK, how about the other versions: C:\gfortran\clf\dcos>type ptr.f90 module funcs implicit none integer, parameter :: dp = kind(1.0d0) abstract interface elemental function fun(x) import implicit none real(dp), intent(in) :: x real(dp) fun end function fun end interface contains function my_dcos(x) ! elemental function my_dcos(x) ! integer :: dp = kind(1.0d0) !-- Or USE an appropriate module integer, parameter :: dp = kind(1.0d0) !-- Or USE an appropriate module real(dp), intent(in) :: x real(dp) :: my_dcos my_dcos = cos(x) return ! end end function end module funcs program start use funcs implicit none procedure(fun), pointer :: f real(dp) x(3) ! intrinsic dcos x = [1,2,3] f => my_dcos ! f => dcos write(*,*) f(x) end program start C:\gfortran\clf\dcos>gfortran -Wall ptr.f90 -optr C:\gfortran\clf\dcos>ptr 0.54030230586813976 -0.41614683654714241 -0.98999249660044542 Now, we agree I think that gfortran should have caught that one as we shouldn't be able to change non-elemental procedures to syntactically elemental ones merely by pointing at them. The last version: C:\gfortran\clf\dcos>type ptr.f90 module funcs implicit none integer, parameter :: dp = kind(1.0d0) abstract interface elemental function fun(x) import implicit none real(dp), intent(in) :: x real(dp) fun end function fun end interface contains function my_dcos(x) ! elemental function my_dcos(x) ! integer :: dp = kind(1.0d0) !-- Or USE an appropriate module integer, parameter :: dp = kind(1.0d0) !-- Or USE an appropriate module real(dp), intent(in) :: x real(dp) :: my_dcos my_dcos = cos(x) return ! end end function end module funcs program start use funcs implicit none procedure(fun), pointer :: f real(dp) x(3) intrinsic dcos x = [1,2,3] ! f => my_dcos f => dcos write(*,*) f(x) end program start C:\gfortran\clf\dcos>gfortran -Wall ptr.f90 -optr C:\gfortran\clf\dcos>ptr 0.54030230586813976 -0.41614683654714241 -0.98999249660044542 Is there a parenthetical normative clause that appears to forbid this, too? -- write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, & 6.0134700243160014d-154/),(/'x'/)); end
From: Tobias Burnus on 16 Oct 2009 16:52 On 16 October 2009 James Van Buskirk wrote: > > I read this as some sort of problem with the standard. At least it > > says that it lets you pass DCOS as an actual argument without having > > to declare the dummy argument as elemental, which would break codes > > dating back to at least f77. It is not completely clear to me why there is/would be a problem. > > It could be that whoever wrote the quoted paragraph assumed that for > > a dummy argument to be elemental was generally prohibited without > > actually checking, or that the prohibition existed in a previous > > draft but was dropped but not fixed in the quoted paragraph. Maybe - or I have simply missed to find the right spot. > > I can't see why the prohibition against passing a nonintrinsic > > elemental procedure as an actual argument exists anyhow. Me neither; I think the way elemental procedures are commonly implemented, it should just work - as ifort and NAG f95 show. (And gfortran would likely show if the error check were removed.) However, someone might have had a different implementation in mind (hypothetically or really existing) were allowing would have lead to problems. > > You know, there is a similar restriction regarding procedure > > pointers: > > > > abstract interface > > elemental function fun(x) > > [...] > > elemental function my_dcos(x) > > [...] > > procedure(fun), pointer :: f > > f => my_dcos > > write(*,*) f(x) > > > > Whoops, gfortran let this one slide! Actually, this program looks OK to me. Do you see anything in the standard which does not allow this one? (Note, the proc-pointer is not passed as actual argument but the procedure to which it is associated is just called.) > > OK, how about the other versions: > > > > abstract interface > > elemental function fun(x) > > [...] > > function my_dcos(x) > > [...] > > procedure(fun), pointer :: f > > f => my_dcos > > > > Now, we agree I think that gfortran should have caught that one as > > we shouldn't be able to change non-elemental procedures to > > syntactically elemental ones merely by pointing at them. I agree that it is invalid and that gfortran should have caught it. (As it is not a constraint, the compiler is not required to check this, however.) From the F2003 standard (7.4.2.2 Procedure pointer assignment) "If proc-pointer-object has an explicit interface, its characteristics shall be the same as proc-target except that proc-target may be pure even if proc-pointer-object is not pure and proc-target may be an elemental intrinsic procedure even if proc-pointer-object is not elemental." > > The last version: > > > > abstract interface > > elemental function fun(x) > > > > procedure(fun), pointer :: f > > intrinsic dcos > > f => dcos Looks OK to me - assuming that "fun" has the same interface as "dcos" (which seems to be the case). Again, you do not use the proc-pointer as actual argument thus there should be no problem. Tobias
From: Carlie Coats on 16 Oct 2009 17:05 analyst41(a)hotmail.com wrote: > (1) Using Double Precision for latitude and longitude and using double > precision for degrees to radians and radius of the earth (by the way, > I have seen values that differ by about 4 miles) > > (2) checking argument of acos to be between -1 and 1 > > Seems to be working OK. > > Are the generic sin,cos and acos functions sufficient? > > Have functions such as DCOS become unnecessary in f95? > > Thanks for any responses. Single precision arithmetic is normally not adequate for geo-transformations (i.e.., except on a few platforms like Cray vector machines). The Earth is a spheroid, and modeling distances on it requires elliptic integrals (something that I'd like to avoid, even though I'm a mathematician myself). Not doing so can lead to errors on the order of 12KM over distances of 3000 KM, according to an evaluation I did myself a decade or so ago. (North American continental scale meteorology plots had easily observable placement errors.) If you want accurate terrestrial distances, you are better off either using a package (e.g., "proj4" or "gctp") developed by by serious geography-programmers, or doing the work "by hand" in a geographic information system like GRASS. FWIW -- Carlie Coats
From: Richard Maine on 16 Oct 2009 17:21 Tobias Burnus <burnus(a)net-b.de> wrote: > On 16 October 2009 James Van Buskirk wrote: > > > I read this as some sort of problem with the standard. At least it > > > says that it lets you pass DCOS as an actual argument without having > > > to declare the dummy argument as elemental, which would break codes > > > dating back to at least f77. > > It is not completely clear to me why there is/would be a problem. I briefly wondered what this was saying also, but then I concluded that it was probably just worded a bit hastily. I think he is saying that it would break codes if it was not allowed to pass dcos as an actual argument to a nonelemental dummy. That would certainly be true, insomuch as it was allowed to pass dcos as an actual argument and... well... the dummy arguments certainly were not elemental as there was no elemental anything then. > > > It could be that whoever wrote the quoted paragraph assumed that for > > > a dummy argument to be elemental was generally prohibited without > > > actually checking, or that the prohibition existed in a previous > > > draft but was dropped but not fixed in the quoted paragraph. > > Maybe - or I have simply missed to find the right spot. Yeah. I could have sworn there was such a prohibition, but I can't find it in a quick skim. I can't say whether my skim missed the prohibition, that parenthetical mention was intended to be the prohibition (which I'd sure agree would be a strange way to express it), the prohibition was in an earlier version of the standard as suggested above, or I am just plain wrong in thinking there was such a prohibition. Ah. Don't feel like looking further. It is still bugging me though. Maybe eventually it will bug me enough that I'll go look a bit more thoroughly (or maybe I'll get lucky and someone else will find it first). > > > I can't see why the prohibition against passing a nonintrinsic > > > elemental procedure as an actual argument exists anyhow. > > Me neither; I think the way elemental procedures are commonly > implemented, it should just work - as ifort and NAG f95 show. (And > gfortran would likely show if the error check were removed.) However, > someone might have had a different implementation in mind > (hypothetically or really existing) were allowing would have lead to > problems. I do recall discussion of multiple possibilities for implementation of elemental procedures. I don't recall the details, but I do recall that bits of the standard were drafted so as to allow for multiple possibilities. In particular, I was pretty sure that allowance for various implementation strategies went into the restrictions on passing elementals as arguments... the restrictions that I'm currently having trouble finding. Seems to me that one set of possible implementation differences involved whether an elemental procedure looked just like a non-elemental one, with the calling procedure implicitly putting loops around the scalar call, or whether the loops were inside of the called procedure. To my knowledge and recollection (very much second hand, if not third hand), most or all current compilers put the loops around the call, but the standard was supposed to accomodate either approach. -- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: Integer return values in interfaces Next: Cannot mex with gfortran on Snow Leopard (64bit) |