- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
the following program throws the following compiler error with IVF Composer XE 2013:
error #6263: This intrinsic function is invalid in constant expressions. [MERGE]
>>
program test
implicit none
integer :: id
id=4
call testsub(id)
end
subroutine testsub(id)
implicit none
integer, parameter :: id1=1
integer :: id
integer, parameter :: idim=merge(1,3,id==id1)
real(8) :: a
real(8) :: stor(100)
equivalence(stor(idim+1),a)
return
end
<<
What I am trying to do is to set the value of a parameter (IDIM) based on the value of another variable (ID) that will be available at runtime. I know from the error that intrinsic functions such as MERGE cannot be used in PARAMETER statements. Does anyone know how I can achieve what I'm trying to do. Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
program test
implicit none
integer :: id
id=4
call testsub(id)
end
subroutine testsub(id)
implicit none
integer, parameter :: id1=1
integer :: id
integer, parameter :: idim=merge(1,3,id==id1)
real(8) :: a
real(8) :: stor(100)
equivalence(stor(idim+1),a)
return
end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Parameters must be declared with constant expressions. The variable id in testsub is not constant (parameter).
Try (untested code):
module params
integer, parameter :: id = 4
end module params
program test
use params
implicit none
call testsub()
end program test
subroutine testsub()
use params
implicit none
integer, parameter :: id1=1
integer, parameter :: idim=merge(1,3,id==id1)
real(8) :: a
real(8) :: stor(100)
equivalence(stor(idim+1),a)
return
end subroutine testsub
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the reply. The above code has the same problem as the original code above - the error is caused by the presence of MERGE function in the PARAMETER statement.
Basically, what I am trying to do is go assign different parameter values to a variable depending on the value of another variable that is read in. This is shown in the following pseudocode):
>>
integer :: id
read() id
If (id.eq.1) then
integer, parameter :: idim=1
else
integer, parameter :: idim=3
end if
<<
Can this be done in Intel FORTRAN?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can't do that - you're attempting to define a named constant based on some run-time value. Unfortunately, the error message is somewhat misleading - it isn't MERGE itself that is the problem. Jim's code compiles OK.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It's good to know that it cant be done.
However, I still get the following error upon compiling Jim's code using IVF Composer XE 2013:
error #6263: This intrinsic function is invalid in constant expressions. [MERGE]
Is there a compiler switch that has to be turned on or off to prevent the error?
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Update to the latest one api Fortran for free from Intel. 2013 is a lot of iterations ago.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Rather than using EQUIVALENCE, why not use a pointer? real(8), pointer, save :: a. Then you can let a point to the right element in the stor array. You cannot do that in a declaration, but it is certainly a possibility.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>> why not use a pointer?
Or, use ASSOCIATE
subroutine testsub()
use params
implicit none
integer, parameter :: id1=1
integer, parameter :: idim=merge(1,3,id==id1)
real(8) :: stor(100)
... ! code
associate (a => stor(idim+1))
... ! code
end associate
... ! code
return
end subroutine testsub
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jim, Thanks for the suggestion. I will try pointers or associate.
Currently, I have data stored in a large array that are copied to local variables, manipulated, and copied back to the original array for storage until the next solution iteration. I am hoping that replacing the 'two copying's' by the use of pointers/associate statements will speed up the code.
Any experience along these lines?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The EQUIVALENCE presents no runtime overhead.
POINTER and ASSOCIATE have very little runtime overhead.
However, should the variable get registerized through optimization, then the cost to register each method would be in effect the same.
POINTER will require you to declare the pointee (your array stor) as having the TARGET attribute.
ASSOCIATE will not require this.
Also, POINTER, being a variable declaration, will have procedure scope. Whereas ASSOCIATE (generally) has a smaller scope that up to the END ASSOCIATE.
POINTER may require the memory location of the pointer variable to be written even when at times it gets regestered, whereas ASSOCIATE in small scopes may keep the reference pointer solely within a register.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jim, thanks for the details. Tried out an example of my issue and looks like using ASSOCIATE will result in some savings in runtime as compared to copying variables.
![](/skins/images/3CECF0550DB8BF54496C114A1FF06FE9/responsive_peak/images/icon_anonymous_message.png)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page