 |
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
Perles75
Joined: 12 May 2011 Posts: 10
|
Posted: Thu May 12, 2011 4:57 pm Post subject: problem with ALLOCATE? |
|
|
Hello,
I am very new both in Fortran and in FTN95, so it's not surprising I have questions; here's the first
My program has several allocate commands scattered through it. When I try to compile, it gives me the errors
error 137 - Operand incompatible with opcode
error 123 - Invalid machine instruction generated
to the lines that correspond to some allocate, but not all.
I noticed that, if I allocate 1D arrays, as for example
allocate(a(n))
there's no problem, but if I allocate 2D arrays, as in allocate(b(n,m)), it gives me that error. I'm pretty sure there are no mistakes in the code itself, so what's happening?
Thank you in advance,
Luca |
|
Back to top |
|
 |
Wilfried Linder
Joined: 14 Nov 2007 Posts: 314 Location: D�sseldorf, Germany
|
Posted: Thu May 12, 2011 6:15 pm Post subject: |
|
|
Are you sure your syntax is correct? Here's a small example:
Code: | WINAPP
OPTIONS(INTL)
PROGRAM TEST
IMPLICIT NONE
INCLUDE <WINDOWS.INS>
integer*4,allocatable::matrix(:,:)
integer*4 i,j,errcode
allocate(matrix(10,10),stat=errcode)
if (errcode .eq. 0) then
matrix = 0
do i = 1,10
do j = 1,10
matrix(i,j) = i*j
end do
end do
do i = 1,10
write(6,'(10I4)')(matrix(i,j),j=1,10)
end do
end if
deallocate(matrix,stat=errcode)
end |
Regards - Wilfried |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Fri May 13, 2011 2:11 am Post subject: |
|
|
Luca & Wilfred,
I recall that I've used ALLOCATE with incorrect syntax, which still ran successfully. I tried to change your program to see if I could reproduce that but did not.
Anyway, I'm sure we'd recomend the correct syntax.
Below is my adaption of Wilfred's code to demonstrate some alternatives for use of ALLOCATE, which I hope are using the correct syntax.
ALLOCATE is a very useful option. REALLOCATE would be even better!
John
Code: | PROGRAM TEST
IMPLICIT NONE
!INCLUDE <WINDOWS.INS>
integer*4,allocatable, dimension(:,:) :: matrix
integer*4 i,j,errcode , n,m
!
allocate (matrix(10,10),stat=errcode)
write (*,*) 'Pass 1',errcode
!
if (errcode == 0) then
matrix = 0
do i = 1,10
do j = 1,10
matrix(i,j) = i*j
end do
end do
!
do i = 1,10
write (*,'(10I4)') (matrix(i,j),j=1,10)
end do
end if
deallocate (matrix,stat=errcode)
!
n = 10
m = 10
!
allocate (matrix(n,m),stat=errcode)
write (*,*) 'Pass 2',errcode
!
if (errcode == 0) then
!
forall (i=1:n, j=1:m) matrix(i,j) = i*j
!
do i = 1,n
write (*,'(10I4)') matrix(i,:)
end do
else
write (*,*) 'error with alllocate',errcode
end if
deallocate (matrix,stat=errcode)
!
end |
|
|
Back to top |
|
 |
Perles75
Joined: 12 May 2011 Posts: 10
|
Posted: Fri May 13, 2011 9:16 am Post subject: |
|
|
well, I'm sure it was not uncorrect because I could compile it when, in my previous computer, I was using a different compiler (the old Compaq Visual Fortran) :)
Could it be something related to the change between 32- and 64-bit system?
Or perhaps the allocate command was changed between ftn95 and the previous versions of fortran (90 and 77)?
Edit: by the way, the program is something like that (in the part that doesn't work):
real, allocatable :: a(:,:)
...
open(1,file...)
read(1) n,m [n and m are declared as integer(4) in a module outside the main program]
allocate(a(n,m)) |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Fri May 13, 2011 12:42 pm Post subject: |
|
|
Your OPEN statement uses unit 1, which is the default screen in FTN95.
Change to unit 11 ( any number > 10 is fairly safe )
{ Long ago, units 1-4 were once reservd for tape drives, 5 input, 6 output and 7 for error unit. The screen input/output numbre varies between compilers with READ(* and WRITE (* being the default }
That may solve your immediate problem.
However, I note you use unformatted I/O. Where did you create the file you are opening, as the format of binary file formats can vary between compilers? If you realy want to use a binary file created by another compiler, you may need to investigate ACCESS='TRANSPARENT' and then decode the binary record headers. Good luck.
It may be easier to recreate the binary file using FTN95 or convert to a text file input. Lots of different factors to weigh up.
John |
|
Back to top |
|
 |
Perles75
Joined: 12 May 2011 Posts: 10
|
Posted: Fri May 13, 2011 2:59 pm Post subject: |
|
|
sorry, I was imprecise *blush*
The actual lines are
open(115,file=filename,status='old',FORM='unformatted') (this was, in the original code, form='binary', but form binary is not allowed anymore, it seems)
read(115) nps,npt
allocate(wl(npt,nps))
etc.
Note that, if I allocate something like a(npt) or a(nps), I don't get the error message. |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Sat May 14, 2011 1:48 am Post subject: |
|
|
I have found the use of ALLOCATE to be very stable. You just have to be sensible in what memory requests you make and recognise how the linker allocates memory. (It could do a better job! You can blame Microsoft for that one)
You didn't indicate the declaration of "wl" lf it is :-
real, allocatable :: wl(:,:) ! 4 bytes per element
Change your code to include the following checks
real mb
read (115) nps,npt ! hopefully both values are +ve and not too big !
mb = real(nps*npt)*4./1.e6 ! limit is about 1200. mb for ALLOCATE
write (*,*) nps,npt, ' size = ',mb,' mb'
allocate (wl(npt,nps), stat=errcode)
if (errcode /= 0) then
write (*,*) 'wl allocate NOT successful : errcode=',errcode
else
write (*,*) 'wl allocate successful'
end if
If your problem is the array size is too big, then ..
The limit of allocate size in win32 is about 1.2gb. The linker puts things through memory which limits the size of continuous available memory for a single array.
You can get a bigger array (up to 1.7gb) by declaring it in common. slink shifts things to cope with this. You also have to be careful how much stack you use.
Interesting if you run FTN95 (which is 32-bit) on XP-64 and do not use /debug then you can get access to 3.7gb of memory and allocate an array just smaller than 2gb.
If you still want more memory then you could try
FTN95 program.f95 /x64
although it may be very slow to compile. I'm still waiting
John |
|
Back to top |
|
 |
Perles75
Joined: 12 May 2011 Posts: 10
|
Posted: Mon May 16, 2011 10:44 am Post subject: |
|
|
Hi,
thanks for the advice, but I think it's another problem... I made a couple of tests and I discovered the following things:
If I put
nps=2
npt=2
allocate(wl(nps,npt))
it gives me error and I cannot compile the routine.
But if I write directly
allocate(wl(2,2))
I have no problems!
Note that in the case I work with a vector, as for example
allocate(wl(nps)), whatever is nps
it is accepted too. (which means it is not directly connected to the definition of the variable nps)
Edit: I discovered the problem. The variables nps and npt are defined as INTEGER(4); if I define them as INTEGER(2), the error disappears. Now I have to see if the change in declaration makes sense!
Edit 2: and actually, if I change INTEGER(4) into INTEGER*4, it gets compiled.
Unfortunately, working with a collection of routines with different provenance and written with different versions of Fortran has many inconveniences... |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Tue May 17, 2011 12:42 am Post subject: |
|
|
Luca,
You have stumbled onto the problem, which is a big deficiency in both FTN95 and the Fortran 90+ standard, which is the value of kind is not defined in the standard. This reduces portability.
My understanding is portability was an initial aim of the Fortran 77, 90 + standards, it is interesting how KIND has evolved and failed this test.
You need to look up the values of kind in the ftn95 help.
INTEGER(4) is different from INTEGER*4
INTEGER*4 is my preferred method of defining integers, as it is well understood by most fortran programmers.
INTEGER(4) says to use kind=4. Infortunately not all compilers have the same value of kind and with FTN95, kind=4 is for an 8-byte integer or INTEGER*8. Unfortunately INTEGER*8 is not fully supported in FTN95, including it's use in an ALLOCATE statement.
Change to INTEGER*4 and your code will work on all compilers, including FTN95 !
John |
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|