- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My problem is that i want to have an array that it's size is determined at compilation time. I do not want to use allocate (speed issues). I have use the technique in the following code for years:
program main1
implicit none
integer, parameter :: i1_max = 2000
integer, parameter :: i2_max = 2000
call main2(i1_max,i2_max)
end program main1
subroutine main2(i1_max,i2_max)
implicit none
integer, intent(in) :: i1_max, i2_max
integer, dimension(i1_max,i2_max) :: N_1
N_1(1,1) = 1;
end subroutine main2
With the above code, I have no error at compilation time.
However at execution time, I get a segmentation fault if i1_max = i2_max = 2000. However I do not get any error if i1_max = i2_max = 20. (this are just test values, I did not amussed myselfs to try more)
It is not a problem of memory, the machine has plenty of it (12Gb).
On top of that, if I declare the size explicitly in the subroutine:
integer, dimension(2000,2000):: N_1
Then there is no problem either!!! Showing again that is no problem of memory.
Just for information, I am using ubuntu11.04 in an intel xeon W3690, ifort2011.
Final note: if I compile the same code with gfortran I have no problems. However i would like to stay with ifort as it generates faster code...
I really have no idea of what is going on. If somebody could help me out I would really appreciated.
Jofre
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
But your statement that you're doing this because of a speed advantage over ALLOCATE may only hold water if your data is pointer based. A plain, allocatable array without the pointer attribute will have zero performance penalty over what you're doing here.
ron
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't see you using interfaces or modules. Your other subroutines and functions are in modules or have interface statements, correct? The reason I ask is you seem very performance concious. With old F77 external procedures you can get a lot of data copies for arguments. Creating interfaces or putting procedures in modules that are USEd can help the compiler with optimizations on call boundaries and in data disambiquity analysis.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As Ron said, ALLOCATE in principle is the same, except that you could check explicitly for errors, which is advisable for an allocation this large.
Automatic array was not standard until Fortran 90, although certain f77 compilers supported it as an extension.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It is not a problem of memory, the machine has plenty of it (12Gb).
On top of that, if I declare the size explicitly in the subroutine:
integer, dimension(2000,2000):: N_1
Then there is no problem either!!! Showing again that is no problem of memory.
Together, these statements establish that you do not have an adequate comprehension of the different ways in which memory is allocated and shared between programs on a modern multitasking operating system. You need to do some reading to understand the issues and make an intelligent selection that suits your purposes.
By trying to avoid dynamic allocation without thinking about the consequences you have invited failure.
A local array, as in your program, is usually allocated on the stack. Stack allocation for local variables, subprogram arguments and small arrays is convenient and efficient. That is why it is so commonly used. However, your array is not small.
The default stack size is operating system dependent, but is usually set to be a small fraction of the total virtually memory available, so that there is adequate stack for all the running processes under OS control. Your array requires 16 megabytes, which may be more than the default stack size on your OS.
A static declaration such as
integer, dimension(2000,2000):: N_1
allocates the array for duration of your program, so other subroutines and other tasks do not "own" and possibly cannot access that memory until your task completes. Such tying up of a resource is often undesirable.
Heap allocation, by using ALLOCATE, is the best fit for your requirements to the extent that your description defines them. It does require a few more lines of code but, as TimP has pointed out, you can check for successful allocation before attempting to use the array.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Now that you guys have give me the key words, "heap allocation", I will try to find more information about it, and I will try to do some speed tests for my particular case about allocatable large arrays.
Also, do you know how can affect a linux system a change on the stack size?
However, there is still the mysteri that gfortran produced a code that executed without problems...
Thanks again for your help,
Jofre
- 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
Judiciously used, ALLOCATE/DEALLOCATE will have an effect on performance that is probably too small to measure easily.
That is, if the numbers of executions of ALLOCATE/DEALLOCATE statements (and, in Fortran 2003, automatic allocation, and deallocation of local ALLOCATEd variables) are kept down to reasonable levels -- for example, by not doing premature deallocation of a variable/array before a subprogram RETURN when it is known that the next call to the subroutine will result in the same variable/array being reallocated -- these statements will be serving their intended purpose in the language, and quite efficiently so.
As with other newly introduced language features, ALLOCATE/DEALLOCATE may have been somewhat inefficient when they were first implemented. Perhaps, the reports that colored your opinion were based on those early compiler versions.
> Also, do you know how can affect a linux system a change on the stack size?
Try man ulimit .
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Depending on the OS's age and the user's shell, man ulimit might point to somewhere else (e.g., the unimplemented or the ulimit.h man page). If bash is the user's default shell, ulimit is probably a built-in (like e.g., cd or pwd), so info --index-search=ulimit bash is a better option.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
However, I have a vague recollection of at least some releases of Ubuntu using not bash but dash as the default shell.
A user of any version of Linux/Unix will need to be able to access the documentation for the shell and OS commands.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
On Ubuntu, dash is the default for sh (so it affects any script for which the shebang line is #!/bin/sh), but scripts that use #!/bin/bash explicitly are not affected ---and the default shell for user accounts is still bash.
dash is supposed to be lighter an stricter than bash, so installing software is much faster ---one drawback, is that system() is usually implemented in terms of /bin/sh, so Fortran's EXECUTE_COMMAND_LINE will probably be affected by it as well.
![](/skins/images/872293744008A34B36F8ABF94A46CC66/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