Silverfrost Forums

Welcome to our forums

problem with ALLOCATE?

12 May 2011 3:57 #8218

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

12 May 2011 5:15 #8219

Are you sure your syntax is correct? Here's a small example:

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

13 May 2011 1:11 #8223

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

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
13 May 2011 8:16 #8234

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))

13 May 2011 11:42 #8236

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

13 May 2011 1:59 #8242

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.

14 May 2011 12:48 #8251

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(npsnpt)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

16 May 2011 9:44 #8257

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...

16 May 2011 11:42 #8266

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 INTEGER8. Unfortunately INTEGER8 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

Please login to reply.