{"id":2132,"date":"2015-01-26T23:02:16","date_gmt":"2015-01-26T22:02:16","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=2132"},"modified":"2015-01-26T23:04:27","modified_gmt":"2015-01-26T22:04:27","slug":"fortran-save-data-static-global-parameter-wtf","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=2132","title":{"rendered":"Fortran save, data, static, global, parameter WTF?"},"content":{"rendered":"<p>Whats the difference between between save, static, global, local and parameter variables?<\/p>\n<p><strong>Save and static are two words for the same thing<\/strong>.<br \/>\nI found a nice definition of what save do in the Fortran 77 Standard [1] <\/p>\n<blockquote><p> Within a function or subroutine subprogram, an entity specified by a SAVE statement does not become undefined as a result of the execution of a RETURN or END statement in the subprogram<\/p><\/blockquote>\n<pre><code>\r\nsubroutine func()\r\n  implicit none\r\n  real, <strong>save<\/strong> :: time\r\n  time = time + 1\r\n  write(*,*) time\r\nend subroutine\r\n\r\nprogram test\r\n  implicit none\r\n  integer :: i\r\n  do i = 1, 10\r\n    call func()\r\n  end do\r\nend\r\n<\/code><\/pre>\n<blockquote><p>   1.00000000<br \/>\n   2.00000000<br \/>\n   3.00000000<br \/>\n   4.00000000<br \/>\n   5.00000000<br \/>\n   6.00000000<br \/>\n   7.00000000<br \/>\n   8.00000000<br \/>\n   9.00000000<br \/>\n   10.0000000  <\/p><\/blockquote>\n<p>You can count how often a subroutine is called. If you ever want to do this... I can not recommend to do it in this way.<br \/>\nAs you may have noticed, I have not initialized the time variable with an start value.<br \/>\nYou can do this with the <strong>data<\/strong> instruction.<\/p>\n<pre><code>\r\nsubroutine func()\r\n  implicit none\r\n  real :: time\r\n  <strong>data<\/strong> time\/100\/  \r\n  time = time + 1\r\n  write(*,*) time\r\nend subroutine\r\n<\/code><\/pre>\n<blockquote><p> 101.000000<br \/>\n   102.000000<br \/>\n   103.000000<br \/>\n   104.000000<br \/>\n   105.000000<br \/>\n   106.000000<br \/>\n   107.000000<br \/>\n   108.000000<br \/>\n   109.000000<br \/>\n   110.000000   <\/p><\/blockquote>\n<p>The <strong>save<\/strong> specifier is not needed by using the <strong>data<\/strong> keyword.<br \/>\nThis may result in confusion, because not everybody knows exactly what the <strong>data<\/strong> specifier does.<br \/>\nAgain: do not use it.<\/p>\n<p>The greatest pitfall with <strong>static<\/strong> variables is this:<\/p>\n<pre><code>\r\nreal :: time = 0\r\n<\/code><\/pre>\n<p>If you initialize a variable by the declaration, it become a <strong>static<\/strong> variable! That really really hurts. You want be a good programer and always zero your variables and then you crash the hole program :D<\/p>\n<p>Lets talk about <strong>parameters<\/strong>. Many programmers declare they constans with the <strong>save<\/strong> attribute.<br \/>\nI can not recommend this.<br \/>\nFirst: Constants does not change. Variables with <strong>save<\/strong> attribute can change. <\/p>\n<pre><code>\r\nreal, <strong>save<\/strong> :: PI = 3.14...\r\nPI = 4\r\n<\/code><\/pre>\n<p>All fine ;)<\/p>\n<p>If you use <strong>parameter<\/strong> instead of <strong>save<\/strong> the compiler can detect this issue.<\/p>\n<pre><code>\r\nreal, <strong>parameter<\/strong> :: PI = 3.14...\r\nPI = 4\r\n<\/code><\/pre>\n<blockquote><p>    PI = 4<br \/>\n    1<br \/>\nError: Named constant 'pi' in variable definition context (assignment) at (1)<\/p><\/blockquote>\n<p>Second: Fortran is a high performance language. You can easily <strong>vectorize<\/strong> assigments using the <strong>forall<\/strong> constrcut.<br \/>\nAll functions called from the forall constrcut must be declared as <strong>pure<\/strong>. to ensure that they have no side effects.<\/p>\n<pre><code>\r\n  function func() result(val)\r\n    implicit none\r\n    real, <strong>save<\/strong> :: PI = 3.14\r\n    real :: val\r\n    val = PI\r\n  end function\r\n\r\nforall( i = 1:100 ) A(i) = func()\r\n<\/code><\/pre>\n<blockquote><p>    <strong>forall<\/strong>( i = 1:100 ) A(i) = func()<br \/>\n                               1<br \/>\nError: Reference to non-PURE function 'func' at (1) inside a FORALL block\n<\/p><\/blockquote>\n<p>And a <strong>pure<\/strong> function can not have static variables<\/p>\n<pre><code>\r\n  <strong>pure<\/strong> function func() result(val)\r\n    implicit none\r\n    real, <strong>save<\/strong> :: PI = 3.14\r\n    real :: val\r\n    val = PI\r\n  end function\r\n<\/code><\/pre>\n<blockquote><p>    real, save :: PI = 3.14<br \/>\n              1<br \/>\nError: SAVE attribute at (1) cannot be specified in a PURE procedure\n<\/p><\/blockquote>\n<p>Using <strong>parameter<\/strong> solves the issue<\/p>\n<pre><code>\r\n  <strong>pure<\/strong> function func() result(val)\r\n    implicit none\r\n    real, <strong>parameter<\/strong> :: PI = 3.14\r\n    real :: val\r\n    val = PI\r\n  end function\r\n\r\n<strong>forall<\/strong>( i = 1:100 ) A(i) = func()\r\n<\/code><\/pre>\n<blockquote><p>$ ifort -O2 -c save.f90  -vec-report3<br \/>\nsave.f90(19): (col. 25) remark: LOOP WAS <strong>VECTORIZED<\/strong>\n<\/p><\/blockquote>\n<p>The last thing I talk about are global variables.<br \/>\nThey can be accessed and overwritten from everywhere by everyone anytime. Happy bug chasing...<br \/>\nOne way to create global variables in Fortran is using the COMMON keyword. <a href=\"http:\/\/roboblog.fatal-fury.de\/?p=2024\" title=\"Fortran COMMON is deadly\">I allready wrote about that..<\/a><\/p>\n<p>[1] http:\/\/www.fortran.com\/fortran\/F77_std\/rjcnf-8.html#sh-8.9 <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Whats the difference between between save, static, global, local and parameter variables? Save and static are two words for the same thing. I found a nice definition of what save do in the Fortran 77 Standard [1] Within a function or subroutine subprogram, an entity specified by a SAVE statement does not become undefined as [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[30],"class_list":["post-2132","post","type-post","status-publish","format-standard","hentry","category-allgemein","tag-fortran"],"_links":{"self":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/2132","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2132"}],"version-history":[{"count":21,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/2132\/revisions"}],"predecessor-version":[{"id":2153,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/2132\/revisions\/2153"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2132"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2132"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2132"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}