Prev: NEQNF/DNEQNF
Next: SLATEC
From: pieterprovoost on 26 Jan 2007 12:44 Hi, I'm trying to use pointers and allocatable arrays for the first time, but I just can't get it right. The program first calls a subroutine which generates a matrix of which the size is given as a dummy argument. The matrix itself is declared as allocatable. The allocation itself happens in the subroutine I just mentioned. Then the program calls another subroutine named run_model. I'm not sure if this is correct but I think I can only pass a pointer to the matrix instead of the matrix itself, because the dimensions of the matrix are only known at run time. This subroutine calls another one which performs some calculations with the matrix, and again, I try to pass the pointer. So, I hope someone can tell me what's wrong with my understanding of pointers and memory allocation... This is the code: program testmodel2 use model implicit none double precision, target, dimension(:,:), allocatable :: matrix double precision, pointer, dimension(:,:) :: pmatrix double precision, dimension(10) :: initial_profile initial_profile = (/100.,0.,0.,0.,0.,0.,0.,0.,0.,0./) call generate_matrix (matrix, 10) write (*,*) matrix pmatrix => matrix call run_model (pmatrix, initial_profile, 50) end program testmodel2 module model contains !*************************************** ! subroutine run_model !*************************************** subroutine run_model (pmatrix, initial_profile, iterations) implicit none integer :: iterations, iteration double precision, dimension(10) :: profile double precision, pointer, dimension(:,:) :: pmatrix double precision, dimension(10) :: initial_profile profile = initial_profile open(unit=1,file='profiles.txt',status='replace') write (1,'(10F8.3)') profile do iteration = 1,iterations call transition (pmatrix, profile) write (1,'(10F8.3)') profile end do close(1) end subroutine run_model !*************************************** ! subroutine transition !*************************************** subroutine transition (pmatrix, profile) implicit none integer :: slices, slice, column double precision, pointer, dimension(:,:) :: pmatrix double precision, dimension(10) :: profile, old_profile slices = size(profile) old_profile = profile do slice = 1,slices profile(slice) = 0. do column = 1,slices profile(slice) = profile(slice) + pmatrix(slice,column) * old_profile(column) end do end do end subroutine transition !*************************************** ! subroutine generate_matrix !*************************************** subroutine generate_matrix (matrix, size) implicit none integer :: size, n double precision, dimension(:,:), allocatable :: matrix allocate(matrix(size,size)) matrix(:,:) = 0. do n = 1,size matrix(n,n) = .9 end do end subroutine generate_matrix end module model These are the errors I get: forrtl: severe (161): Program Exception - array bounds exceeded Image PC Routine Line Source model.exe 0040128A MODEL_mp_TRANSITI 49 model.f90 model.exe 0040110E MODEL_mp_RUN_MODE 23 model.f90 model.exe 004018E7 TESTMODEL2 18 testmodel2.f90 model.exe 00441089 Unknown Unknown Unknown model.exe 0042A489 Unknown Unknown Unknown kernel32.dll 7C816FD7 Unknown Unknown Unknown Press any key to continue Many thanks in advance, Piet
From: Richard E Maine on 26 Jan 2007 13:11 pieterprovoost(a)gmail.com <pieterprovoost(a)gmail.com> wrote: > I'm trying to use pointers and allocatable arrays for the first time, > but I just can't get it right. Actually, it looks more or less ok to me, at least at a quick glance. > The program first calls a subroutine > which generates a matrix of which the size is given as a dummy > argument. The matrix itself is declared as allocatable. The allocation > itself happens in the subroutine I just mentioned. Be aware that allocatable dummy arguments are a feature of either f2003 or the f95 TR (which amounts to an officially standardized extension to f95). They are also a feature that has been tricky for compiler vendors to get correct. It would not surprise me at all to find that you have just found a compiler bug in this regard. I don't see that you mentioned the exact compiler and version; it might matter in this case. > I'm not sure if this is > correct but I think I can only pass a pointer to the matrix instead of > the matrix itself, because the dimensions of the matrix are only known > at run time. No, that is not correct. That wasn't even correct in Fortran 77. The pointer business is just unnecessary complication here. It looks like what you have done with it is valid, but it just adds complication (and extra places for bugs to happen) without adding anything useful. I'd recommend getting rid of all the pointer stuff. Note also that you don't need the allocatable attribute (and I'd recommend not adding it) in any of the subroutines except for generate_matrix. You only need the dummy to be allocatable when you are doing something related to the allocation in the subroutine. You need it in generate_matrix because of the allocate there. For the other subroutines, you just use the array without changing its allocation in any way. It is perfectly fine and normal to pass an allocatable (or pointer, for that matter) array as an actual argument, while the dummy is a non-allocatable, non-pointer, assumed shape array. I just compiled and ran your code as is with the NAG compiler, with all warnings tuned on. Other than the one line that wrapped in posting, and a warning about allocatable dummies being an extension to f95, there were no complaints. It ran "normally". I didn't check that the numbers were actually correct, but they were at least "normal" numbers. -- 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
From: pieterprovoost on 26 Jan 2007 13:36 Thank you for your comments, Richard. Of course I should have mentioned that I'm using Compaq Visual Fortran Professional Edition 6.6.0. I got rid of the pointers and declared matrix like this for all the subroutines except generate_matrix: double precision, dimension(:,:) :: matrix I'm not getting any errors, now, but the numbers in the matrix are a bit strange: 0.000000000000000E+000 0.000000000000000E+000 0.000000000000000E+000 0.000000000000000E+000 0.000000000000000E+000 1.009553927772605E-307 1.009626074980000E-307 1.623744768794673E-317 0.000000000000000E+000 1.009397748882363E-307 1.620989858753463E-317 6.150978952342684E-318 0.000000000000000E+000 0.000000000000000E+000 0.000000000000000E+000 ....
From: Michael Metcalf on 26 Jan 2007 13:50 <pieterprovoost(a)gmail.com> wrote in message news:1169836575.436238.98700(a)v33g2000cwv.googlegroups.com... > Thank you for your comments, Richard. Of course I should have mentioned > that I'm using Compaq Visual Fortran Professional Edition 6.6.0. I got > rid of the pointers and declared matrix like this for all the > subroutines except generate_matrix: > I ran your code without change using CVF version 6.6C, and it appears to work perfectly. Perhaps you should apply the appropriate patch(es) to your compiler. Regards, Mike Metcalf
From: pieterprovoost on 26 Jan 2007 14:20
Thanks everyone. I couldn't find any updates for my version of CVF (I did find the pages but not the files), but it works fine with G95... Cheers, Piet |