Home > Archive > Fortran > August 2005 > forrtl warning (402)
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
forrtl warning (402)
|
|
| Bart Vandewoestyne 2005-08-23, 7:57 am |
| After compiling some of my code with the `Intel(R) Fortran
Compiler for 32-bit applications, Version 9.0 Build
20050430Z', I am getting quite a lot of these warnings at
runtime:
forrtl: warning (402): fort: (1): In call to SOME_PROCEDURE, an array
temporary was created for argument #some_number
As I did not completely understood what was going on here, i
searched on Google and found the following forum post:
http://softwareforums.intel.com/ids...message.id=1739
So apparently -quoting the article- i get that warning `when I'm
passing a non-contiguous array section to a routine that expects
a contiguous array to be passed.'
A reference is also given to an article in VF Newsletter issue 1
(or maybe 2) for more on the subject.
As I still don't quite understand what this warning exactly
means, can somebody:
* provide me a simple example of a piece of code that will have
this warning when compiled with ifort 9.0, and then show how
the code should be changed in order to make the warning go away
(and -according to the link above- also have better performance).
* give me a reference to Chris Bord's article in VF Newsletter
issue 1 (or maybe 2) so I can read more on this. Or is this a
journal that does not come online and can only be obtained on a
paper hardcopy?
Thanks,
Bart
--
"Share what you know. Learn what you don't."
| |
| John Mansell 2005-08-23, 7:57 am |
| You are calling a routine that has an f77-style array argument (* as the
last array bound - such arrays, being f77-style, are contiguous in
memory), but the actual argument is f90-style assumed-shape (:) array in
the outer, calling routine. Because the caller of this (outer) routine
may have specified an f90-style array section (which is not contiguous),
the compiler has to make a local contiguous copy of the array, send this
to the inner routine, then copy back on return. As Steve says,
programmers may like to know about this on account of the speed penalty.
module mod1
contains
subroutine outer(a)
real :: a(:)
! compiler knows that a must be contiguous because its in the module
! but if inner is external the same assumption must be made
call inner(a,n)
end subroutine
subroutine inner(a,n)
real a(*)
!real a(n) ! also contiguous
end subroutine
end module
In the case of inner being a module procedure, it should be a simple
matter to change the declaration of the array to f90-style assumed
shape, but if inner is external, changing the array declaration in outer
to a(n) or a(*) then moves the copy-in/copy-out burden outwards to the
instances when outer is called. Of course, putting inner in a module and
changing to (:) style may also merely move the copy-in/copy-out burden
further along.
In message <1124780221.535879@seven.kulnet.kuleuven.ac.be>, Bart
Vandewoestyne <MyFirstName.MyLastName@telenet.be> writes
>After compiling some of my code with the `Intel(R) Fortran
>Compiler for 32-bit applications, Version 9.0 Build
>20050430Z', I am getting quite a lot of these warnings at
>runtime:
>
>forrtl: warning (402): fort: (1): In call to SOME_PROCEDURE, an array
>temporary was created for argument #some_number
>
>As I did not completely understood what was going on here, i
>searched on Google and found the following forum post:
>
>http://softwareforums.intel.com/ids...message.id=1739
>
>So apparently -quoting the article- i get that warning `when I'm
>passing a non-contiguous array section to a routine that expects
>a contiguous array to be passed.'
>
>A reference is also given to an article in VF Newsletter issue 1
>(or maybe 2) for more on the subject.
>
>As I still don't quite understand what this warning exactly
>means, can somebody:
>
>* provide me a simple example of a piece of code that will have
> this warning when compiled with ifort 9.0, and then show how
> the code should be changed in order to make the warning go away
> (and -according to the link above- also have better performance).
>
>* give me a reference to Chris Bord's article in VF Newsletter
> issue 1 (or maybe 2) so I can read more on this. Or is this a
> journal that does not come online and can only be obtained on a
> paper hardcopy?
>
>Thanks,
>Bart
>
--
John Mansell john at wcompsys dot co dot uk
| |
| Jugoslav Dujic 2005-08-23, 7:57 am |
| John Mansell wrote:
| You are calling a routine that has an f77-style array argument (* as the
| last array bound - such arrays, being f77-style, are contiguous in
| memory), but the actual argument is f90-style assumed-shape (:) array in
| the outer, calling routine. Because the caller of this (outer) routine
| may have specified an f90-style array section (which is not contiguous),
| the compiler has to make a local contiguous copy of the array, send this
| to the inner routine, then copy back on return. As Steve says,
| programmers may like to know about this on account of the speed penalty.
|
| module mod1
| contains
| subroutine outer(a)
| real :: a(:)
|
| ! compiler knows that a must be contiguous because its in the module
| ! but if inner is external the same assumption must be made
| call inner(a,n)
|
| end subroutine
| subroutine inner(a,n)
| real a(*)
| !real a(n) ! also contiguous
|
| end subroutine
| end module
|
| In the case of inner being a module procedure, it should be a simple
| matter to change the declaration of the array to f90-style assumed
| shape, but if inner is external, changing the array declaration in outer
| to a(n) or a(*) then moves the copy-in/copy-out burden outwards to the
| instances when outer is called. Of course, putting inner in a module and
| changing to (:) style may also merely move the copy-in/copy-out burden
| further along.
A simpler still example is:
program foo
use mod1
real:: a(10)
call inner(a(1:10:2),n)
end program foo
(In your code, compiler doesn't know whether A will be contiguous or not,
but still has a chance to insert a run-time contiguity test before
copy-in/copy-out. I don't know whether IVF9 does that though.
In my code, compiler knows that the actual argument is discontiguous,
so it has to make a copy.)
VFN newsletters seem to have disappeared from HP site.
I have bookmarked another article:
http://h18009.www1.hp.com/fortran/v...fn10/page2.html
which appears briefly and then I get redirected to new location,
which doesn't seem to contain it anymore. Crazy.
--
Jugoslav
___________
www.geocities.com/jdujic
Please reply to the newsgroup.
You can find my real e-mail on my home page above.
| |
| Jan Vorbrüggen 2005-08-23, 7:57 am |
| I believe you get this warning only when you requested this during
compilation - at least, it's the case for CVF 6.6 where this feature
was added.
The basic problem has been explained by others. The point is that you,
as the programmer, never know how smart your compiler is in avoiding
such temporary copies, and having this warning tells you if and when and
where it does occur. Also keep in mind that there are situations when
it is actually beneficial, from a performance point of view, to make
the temporary copy - for various reasons, cache trashing et al. among
them. You can always, of course, make such a copy explicitly and pass
that copy; in certain situations, this may make sense because you might
need to allocate the temporary only once at the beginning of a loop, for
instance, or can use additional information you have on the data that
you cannot communicate to the compiler.
Jan
| |
| Steve Lionel 2005-08-23, 7:00 pm |
| On Tue, 23 Aug 2005 07:57:01 +0000 (UTC), Bart Vandewoestyne
<MyFirstName.MyLastName@telenet.be> wrote:
>* give me a reference to Chris Bord's article in VF Newsletter
> issue 1 (or maybe 2) so I can read more on this. Or is this a
> journal that does not come online and can only be obtained on a
> paper hardcopy?
Why not ask in the Intel Fortran forum where you found the reference? Or ask
there if you have questions about why Intel Fortran does something?
As Jugoslav says, HP removed all of the VF Newsletters from their web site. I
have all the content, and would be glad to post selected articles to our
forum. (I have permission to do so.)
Steve Lionel
Software Products Division
Intel Corporation
Nashua, NH
User communities for Intel Software Development Products
http://softwareforums.intel.com/
Intel Fortran Support
http://developer.intel.com/software/products/support/
| |
| Bart Vandewoestyne 2005-08-23, 7:00 pm |
| On 2005-08-23, Jan Vorbrüggen <jvorbrueggen-not@mediasec.de> wrote:
> I believe you get this warning only when you requested this during
> compilation - at least, it's the case for CVF 6.6 where this feature
> was added.
>
> The basic problem has been explained by others. The point is that you,
> as the programmer, never know how smart your compiler is in avoiding
> such temporary copies, and having this warning tells you if and when and
> where it does occur. Also keep in mind that there are situations when
> it is actually beneficial, from a performance point of view, to make
> the temporary copy - for various reasons, cache trashing et al. among
> them. You can always, of course, make such a copy explicitly and pass
> that copy; in certain situations, this may make sense because you might
> need to allocate the temporary only once at the beginning of a loop, for
> instance, or can use additional information you have on the data that
> you cannot communicate to the compiler.
To everybody who responded: thanks for the explanation. I have
found that my problem was that I did something like the
following:
call my_subroutine(primes(4), foo, bar)
where primes(4) is a function that simply returns the first 4
prime numbers. As I understand it, the primes(4) function
appearing as a dummy argument has as a consequence that a
temporary copy (holding it's result) needs to be made, so it can
be passed as a dummy argument to my_subroutine (am I
understanding things right here?)
I have changed my code to
....some declarations...
myprimes = primes(4)
call my_subroutine(myprimes, foo, bar)
As far as memory is consumed, I have the impression that I'm
using as much memory as before because the allocated memory now
goes to myprimes instead of to the temporary copy, but at least
Intel Fortran doesn't give me warnings anymore and for as far as
I understand there are no other `dangerous' issues involved in
making this change of code and it does exactly the same.
Regards,
Bart
--
"Share what you know. Learn what you don't."
| |
| Bart Vandewoestyne 2005-08-23, 7:00 pm |
| On 2005-08-23, Steve Lionel <Steve.Lionel@REMOVEintelME.com> wrote:
>
> Why not ask in the Intel Fortran forum where you found the reference? Or ask
> there if you have questions about why Intel Fortran does something?
With all my respect Steve, but when i follow the `Post New'
hyperlink on the Forum website, I get to a page asking me for a
Login ID and a Password... and I guess I'm one of those people
that dislikes registering again and again to be able to post
questions at a certain forum. It's nothing personal agains you
or Intel, it's just that I hate registering somewhere before I
can post questions or ask comments. Knowing that there are a lot
of good Fortran folks out here in clf, I feel it much more
comfortable that I can post my questions here without the need to
register. UseNet is just the way I'm used to discuss and ask
questions or comments.
No hard feelings? And who knows... some day I might register ;-)
> As Jugoslav says, HP removed all of the VF Newsletters from their web site. I
> have all the content, and would be glad to post selected articles to our
> forum. (I have permission to do so.)
Feel free to do so. I can read the forum without registering,
so if you post it i can read it... ;-)
Regards,
Bart
--
"Share what you know. Learn what you don't."
| |
| Richard E Maine 2005-08-23, 7:00 pm |
| In article <1124821713.141761@seven.kulnet.kuleuven.ac.be>,
Bart Vandewoestyne <MyFirstName.MyLastName@telenet.be> wrote:
> call my_subroutine(primes(4), foo, bar)
>
> where primes(4) is a function that simply returns the first 4
> prime numbers. As I understand it, the primes(4) function
> appearing as a dummy argument has as a consequence that a
> temporary copy (holding it's result) needs to be made, so it can
> be passed as a dummy argument to my_subroutine (am I
> understanding things right here?)
Woah! You might be understanding some things right, but the terminology
is completely messed up... which does make me suspicious that some of
the understanding is also off a little.
Most importantly, primes(4) is *NOT* a function.... ever. Primes might
be a function, but primes(4) is a result returned by the function (or
more pedantically, it is an expression with a single primary, which is a
function reference). The distinction between a function and a function
result is really, really important. That's mostly because you can pass a
function as an actual argument and it means something completely
different from passing a result.
If you pass a function as an actual argument, then the dummy argument
must be a dummy function. You aren't passing any particular result, but
the function itself. The called subroutine can then invoke the function
as needed with arguments as appropriate.
If you pass a function result as an actual argument, then it has no
properties of functionness (which isn't a word, but it will do anyway;
"functionality" is a word, but doesn't have the right meaning here). It
is just a result and has no indication as to whether or not it came from
a function or not.
Second, you seem to be confusing actual and dummy arguments. You have
nothing but actual arguments here. In particular, primes(4) is an actual
argument, not a dummy. The dummy argument is what is in my_subroutine.
Yes, the dummy argument gets associated with the actual argument, but
that doesn't mean that it is the actual argument - if that were the
case, we wouldn't have the modifiers "dummy" and "actual". In some
contexts, the distinction is uninteresting, but when you are talking
about things like the subject of this thread, it really is important.
Third, if this is actually what is causing the message in question, then
I'd regard the message as misleading. There isn't a copy of the result,
but rather it is the original of the result that is a temporary array
here. That temporary array is created as a consequence of invoking
primes(4) at all and has nothing in particular to do with that
invocation being in an actual argument. If a copy is involved, then
that's just plain silly of the compiler, which doesn't mean it couldn't
happen, but if so you can stop the "explanation" right there and XXXXX
at the vendor.
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
| Bart Vandewoestyne 2005-08-23, 7:00 pm |
| On 2005-08-23, Richard E Maine <nospam@see.signature> wrote:
>
> Woah! You might be understanding some things right, but the terminology
> is completely messed up... which does make me suspicious that some of
> the understanding is also off a little.
OK, sorry for this... I am absolutely aware of the fact that I'm
sometimes probably using the wrong terminology although I try to
use the right one. But as English is not my native language and
I'm not a `fortran standard expert' i guess this is the reason
for my `confusing' choice of words sometimes... I'll try to pay
attention to it... ;-)
> Most importantly, primes(4) is *NOT* a function.... ever. Primes might
> be a function, but primes(4) is a result returned by the function (or
> more pedantically, it is an expression with a single primary, which is a
> function reference). The distinction between a function and a function
> result is really, really important. That's mostly because you can pass a
> function as an actual argument and it means something completely
> different from passing a result.
I absolutely agree.
> If you pass a function as an actual argument, then the dummy argument
> must be a dummy function. You aren't passing any particular result, but
> the function itself. The called subroutine can then invoke the function
> as needed with arguments as appropriate.
True again.
> If you pass a function result as an actual argument, then it has no
> properties of functionness (which isn't a word, but it will do anyway;
> "functionality" is a word, but doesn't have the right meaning here). It
> is just a result and has no indication as to whether or not it came from
> a function or not.
True again.
> Second, you seem to be confusing actual and dummy arguments. You have
> nothing but actual arguments here. In particular, primes(4) is an actual
> argument, not a dummy. The dummy argument is what is in my_subroutine.
> Yes, the dummy argument gets associated with the actual argument, but
> that doesn't mean that it is the actual argument - if that were the
> case, we wouldn't have the modifiers "dummy" and "actual". In some
> contexts, the distinction is uninteresting, but when you are talking
> about things like the subject of this thread, it really is important.
Indeed. I messed up `actual' and `dummy' here. Thanks for
clarifying this!
> Third, if this is actually what is causing the message in question, then
> I'd regard the message as misleading. There isn't a copy of the result,
> but rather it is the original of the result that is a temporary array
> here. That temporary array is created as a consequence of invoking
> primes(4) at all and has nothing in particular to do with that
> invocation being in an actual argument. If a copy is involved, then
> that's just plain silly of the compiler, which doesn't mean it couldn't
> happen, but if so you can stop the "explanation" right there and XXXXX
> at the vendor.
Maybe I (or somebody else? I do not have time right now...) should make a
little testcase demonstrating this behavior. I compiled it with
Intel(R) Fortran Compiler for 32-bit applications, Version 9.0
Build 20050430Z (on a Debian stable box).
If this trimmed down testcase appears to generate the same
warning, and we all agree that the warning is not necessary, then
this maybe is something for Steve? :-)
Regards,
Bart
--
"Share what you know. Learn what you don't."
| |
| James Van Buskirk 2005-08-23, 7:00 pm |
| "Bart Vandewoestyne" <MyFirstName.MyLastName@telenet.be> wrote in message
news:1124831177.161078@seven.kulnet.kuleuven.ac.be...
> If this trimmed down testcase appears to generate the same
> warning, and we all agree that the warning is not necessary, then
> this maybe is something for Steve? :-)
Actually, the design of f90 array results is such that their
shape can be known at the time of function invocation so that
the calling program can allocate the necessary memory or use
the memory of the array assigned, if simple assignment is
all that is required. It seems from examples posted in this
thread that ifort is using the array on the sinister of an
assignment statement directly -- you should check by examining
a disassembly. In that context its warning seems valid.
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end
| |
| Steve Lionel 2005-08-24, 6:59 pm |
| On Tue, 23 Aug 2005 22:06:17 +0000 (UTC), Bart Vandewoestyne
<MyFirstName.MyLastName@telenet.be> wrote:
>Maybe I (or somebody else? I do not have time right now...) should make a
>little testcase demonstrating this behavior. I compiled it with
>
>Intel(R) Fortran Compiler for 32-bit applications, Version 9.0
>Build 20050430Z (on a Debian stable box).
>
>If this trimmed down testcase appears to generate the same
>warning, and we all agree that the warning is not necessary, then
>this maybe is something for Steve? :-)
This informational message, which is put out only if you ask for it, alerts
you that the compiler has chosen to make a copy of an actual argument to be
passed to a procedure. It never gives the message if it didn't make the copy,
so the message is certainly necessary if the copy was made.
In addition to compile-time tests to avoid unnecessary copies, Intel Fortran
often does a run-time test to see if the argument is contiguous. If it is,
then it skips the copy (and you don't get a message). That part works pretty
well.
However, the compiler may also make copies in other contexts, such as
assignments of array expressions. The compiler tries to avoid these when it
thinks it can, but it does not detect all such cases and is therefore
sometimes more conservative than it should be. These copies don't cause the
message to be emitted.
Since I have not seen an actual example from you, it's impossible for me to
say if there's a problem or not. If you believe that the compiler is
misbehaving, then please submit an example to Intel Premier Support and we'll
be glad to take a look.
Steve Lionel
Software Products Division
Intel Corporation
Nashua, NH
User communities for Intel Software Development Products
http://softwareforums.intel.com/
Intel Fortran Support
http://developer.intel.com/software/products/support/
| |
| Bart Vandewoestyne 2005-08-24, 6:59 pm |
| On 2005-08-24, Steve Lionel <Steve.Lionel@REMOVEintelME.com> wrote:
>
> Since I have not seen an actual example from you, it's impossible for me to
> say if there's a problem or not. If you believe that the compiler is
> misbehaving, then please submit an example to Intel Premier Support and we'll
> be glad to take a look.
The `problem' appeared in a larger code of mine, and i tried to
trim it down to a test example but I didn not succeed yet.
My best attempt is at
http://users.telenet.be/vandewoesty...warning_402.f95
One thing that I can tell for sure is that removing the primes(3)
from the actual arguments of the subroutine, and assigning the
result of primes(3) to another array first, and then passing that
array as an actual argument to the function removed the
warning...
Maybe somebody can change my code so it reproduces the warning?
I haven't succeeded for now and don't have much time now...
Regards,
Bart
--
"Share what you know. Learn what you don't."
|
|
|
|
|