<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic OpenMP Reduction on Array in COMMON block being set in non inli in Intel® Fortran Compiler</title>
    <link>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760197#M15684</link>
    <description>Thanks for the answers Patrick, but I would like to minimize the code change - of course I provide here a reproducer from a much bigger old code - and passing the array as an argument to the subroutine would make too much change - path to the subroutine is a bit long and there are many paths to it, and there are many "setvalue" routines.&lt;BR /&gt;I wished there were some other means to tell setvalue that it handles a reduction array...&lt;BR /&gt;The closest thing to what I would like in terms of minimal code change looks like the threadprivate/reduction stuff as in reduc.f90/setval.f90 below, but I found no way to use only one common block. In the real code, setval may be in parallel or non parallel context, as being called from different code sections.&lt;BR /&gt;Oliver.&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;</description>
    <pubDate>Wed, 07 Dec 2011 21:09:44 GMT</pubDate>
    <dc:creator>Olivier_C_</dc:creator>
    <dc:date>2011-12-07T21:09:44Z</dc:date>
    <item>
      <title>OpenMP Reduction on Array in COMMON block being set in non inlined subroutine.</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760194#M15681</link>
      <description>Hello,&lt;BR /&gt;&lt;BR /&gt;I need to perform a reduction on an array that is inside a named COMMON block.&lt;BR /&gt;When the reduction is in the same unit as the one where the parallel reduction is declared, everything goes fine.&lt;BR /&gt;When the reduction has to occur in subroutines that are called from the parallel region, then the result is not predictable.&lt;BR /&gt;&lt;BR /&gt;The problem is rooted in the fact that a reduction induces a per thread array, but when the program reaches a subroutine it sees the global array only. If the array is declared threadprivate in the subroutine, then the output is not gathered.&lt;BR /&gt;&lt;BR /&gt;If I mix-up threadprivate/reduction, then I have to use 2 different names for the common, which I would like to avoid.&lt;BR /&gt;Is there a design pattern or an OpenMP instruction to make as though the subroutines were inlined ?&lt;BR /&gt;&lt;BR /&gt;It can be funny to look at the provided code in redko.f90, and play with the subroutine being in the same file or not as the main program.&lt;BR /&gt;&lt;BR /&gt;Of course, I would be very grateful to any help, since I dearly need to overcome that tricky problem.&lt;BR /&gt;&lt;BR /&gt;Oliver.</description>
      <pubDate>Wed, 07 Dec 2011 18:04:47 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760194#M15681</guid>
      <dc:creator>Olivier_C_</dc:creator>
      <dc:date>2011-12-07T18:04:47Z</dc:date>
    </item>
    <item>
      <title>OpenMP Reduction on Array in COMMON block being set in non inli</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760195#M15682</link>
      <description>If you are storing a reduction into an element of an array in common, I would think you would declare a local scalar reduction variable, rather than naming the entire array in the reduction.  In your example, however, it doesn't look like the context is appropriate for reduction.  Besides, it looks like you have intentionally created a race condition, so no advice we give can make the result "predictable" other than to eliminate the race.</description>
      <pubDate>Wed, 07 Dec 2011 19:38:59 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760195#M15682</guid>
      <dc:creator>TimP</dc:creator>
      <dc:date>2011-12-07T19:38:59Z</dc:date>
    </item>
    <item>
      <title>OpenMP Reduction on Array in COMMON block being set in non inli</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760196#M15683</link>
      <description>When you try to do the reduction on common block array member 'redarray' via the subroutine, there's no way for the compiler to know that redarray is a reduction variable, and so as Tim says, there's a data race on statement 'redarray(j) = redarray(j) + i'&lt;BR /&gt;&lt;BR /&gt;If redarray was not a member of a common block, then you could pass it in the argument list of the subroutine, and the compiler would then know that it's a reduction variable, and the race conditional wouldelminated. &lt;BR /&gt;&lt;BR /&gt;So, make a copy of redarray, pass the copy in the subroutine call argument list, and then update the common block array after the parallel region:&lt;BR /&gt;&lt;BR /&gt;&lt;P&gt;redarray_copy = 0&lt;/P&gt;&lt;P&gt;!$OMP PARALLEL&lt;/P&gt;&lt;P&gt;!$OMP DO REDUCTION(+:redarray_copy)&lt;/P&gt;&lt;P&gt;do i=1, n&lt;/P&gt;&lt;P&gt;call setvalue(i,indir(i),redarray_copy)&lt;/P&gt;&lt;P&gt;enddo&lt;/P&gt;&lt;P&gt;!$OMP END DO&lt;/P&gt;&lt;P&gt;!$OMP END PARALLEL&lt;/P&gt;&lt;P&gt;redarray = redarray_copy&lt;BR /&gt;&lt;BR /&gt;The subroutine would then become&lt;/P&gt;&lt;P&gt;subroutine setvalue(i,j,subarray)&lt;/P&gt;&lt;P&gt;IMPLICIT NONE&lt;/P&gt;&lt;P&gt;integer, intent(inout) :: subarray(2)&lt;/P&gt;&lt;P&gt;integer :: i,j&lt;/P&gt;&lt;P&gt;subarray(j) = subarray(j) + i&lt;/P&gt;&lt;P&gt;end subroutine setvalue&lt;BR /&gt;&lt;BR /&gt;This implementation is kinda ugly, but correct (race-free).&lt;BR /&gt;&lt;BR /&gt;Patrick&lt;/P&gt;</description>
      <pubDate>Wed, 07 Dec 2011 20:33:01 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760196#M15683</guid>
      <dc:creator>pbkenned1</dc:creator>
      <dc:date>2011-12-07T20:33:01Z</dc:date>
    </item>
    <item>
      <title>OpenMP Reduction on Array in COMMON block being set in non inli</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760197#M15684</link>
      <description>Thanks for the answers Patrick, but I would like to minimize the code change - of course I provide here a reproducer from a much bigger old code - and passing the array as an argument to the subroutine would make too much change - path to the subroutine is a bit long and there are many paths to it, and there are many "setvalue" routines.&lt;BR /&gt;I wished there were some other means to tell setvalue that it handles a reduction array...&lt;BR /&gt;The closest thing to what I would like in terms of minimal code change looks like the threadprivate/reduction stuff as in reduc.f90/setval.f90 below, but I found no way to use only one common block. In the real code, setval may be in parallel or non parallel context, as being called from different code sections.&lt;BR /&gt;Oliver.&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;</description>
      <pubDate>Wed, 07 Dec 2011 21:09:44 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760197#M15684</guid>
      <dc:creator>Olivier_C_</dc:creator>
      <dc:date>2011-12-07T21:09:44Z</dc:date>
    </item>
    <item>
      <title>OpenMP Reduction on Array in COMMON block being set in non inli</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760198#M15685</link>
      <description>I can appreciate that you don't want to modify the argument list for a whole bunch of subroutines, although trying to make abig legacy code work with a modern compiler might require that. But anyway, if you can't/won't modify the calls, then I think you're stuck with you're double common block implementation. Of course you couldput a CRITICAL section around the update of the common block array in setvalue(i,j), but that just serializes things.&lt;BR /&gt;&lt;BR /&gt;Patrick</description>
      <pubDate>Thu, 08 Dec 2011 18:16:17 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760198#M15685</guid>
      <dc:creator>pbkenned1</dc:creator>
      <dc:date>2011-12-08T18:16:17Z</dc:date>
    </item>
    <item>
      <title>OpenMP Reduction on Array in COMMON block being set in non inli</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760199#M15686</link>
      <description>Oliver,&lt;BR /&gt;&lt;BR /&gt;After a short look at your code, you really do not have what constitutes a "reduction array".&lt;BR /&gt;&lt;BR /&gt;The fly in your ointment is your indir(n) array containing 1,2,1,2,1,2,...&lt;BR /&gt;&lt;BR /&gt;Resulting in a parallel loop, using x threads, xnot equal2, stomping on each others redarray(indir(i))&lt;BR /&gt;&lt;BR /&gt;Consider something along the line of:&lt;BR /&gt;&lt;BR /&gt;!$OMP PARALLEL&lt;BR /&gt;numThreads = omp_get_num_threads()&lt;BR /&gt;myThread = omp_get_thread_num()&lt;BR /&gt;if(myThread .lt. n-1) then&lt;BR /&gt;do i=1, n&lt;BR /&gt; if(mod(indir(i), numThreads) .eq. myThread) then&lt;BR /&gt; redarray(indir(i)) = redarray(indir(i))+ 1&lt;BR /&gt; endif&lt;BR /&gt;end do&lt;BR /&gt;endif&lt;BR /&gt;!$OMP END PARALLEL&lt;BR /&gt;&lt;BR /&gt;Jim Dempsey</description>
      <pubDate>Thu, 08 Dec 2011 19:55:13 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760199#M15686</guid>
      <dc:creator>jimdempseyatthecove</dc:creator>
      <dc:date>2011-12-08T19:55:13Z</dc:date>
    </item>
    <item>
      <title>OpenMP Reduction on Array in COMMON block being set in non inli</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760200#M15687</link>
      <description>&lt;P&gt;I took a closer look at making the common block 'reduction' array threadprivate:&lt;/P&gt;&lt;P&gt;subroutine setvalue(i,j)&lt;/P&gt;&lt;P&gt;IMPLICIT NONE&lt;/P&gt;&lt;P&gt;integer :: redarray(2)&lt;/P&gt;&lt;P&gt;common /comarray/ redarray&lt;/P&gt;&lt;P&gt;!$OMP threadprivate(/comarray/)&lt;/P&gt;&lt;P&gt;integer :: i,j&lt;/P&gt;&lt;P&gt;redarray(j) = redarray(j) + i&lt;/P&gt;&lt;P&gt;end subroutine setvalue&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;That works fine, you just need to add up the partial sums after the OpenMP loop calling the subroutine (similar to what Jim suggested). Something like:&lt;/P&gt;&lt;P&gt;integer :: redarray(2), redarray_copy(2)&lt;/P&gt;&lt;P&gt;common /comarray/ redarray&lt;/P&gt;&lt;P&gt;!$OMP threadprivate(/comarray/)&lt;/P&gt;&lt;P&gt;....&lt;/P&gt;&lt;P&gt;redarray = 0&lt;/P&gt;&lt;P&gt;!$OMP PARALLEL COPYIN(redarray)&lt;/P&gt;&lt;P&gt;!$OMP DO&lt;/P&gt;&lt;P&gt;do i=1, n&lt;/P&gt;&lt;P&gt;call setvalue(i,indir(i))&lt;/P&gt;&lt;P&gt;enddo&lt;/P&gt;&lt;P&gt;!$OMP END DO&lt;/P&gt;&lt;P&gt;!$OMP SINGLE&lt;/P&gt;&lt;P&gt;j = omp_get_num_threads()&lt;/P&gt;&lt;P&gt;redarray_copy = 0&lt;/P&gt;&lt;P&gt;!$OMP END SINGLE&lt;/P&gt;&lt;P&gt;!$OMP DO REDUCTION(+:redarray_copy)&lt;/P&gt;&lt;P&gt;do i=1,j&lt;/P&gt;&lt;P&gt;do k=1,2&lt;/P&gt;&lt;P&gt;redarray_copy(k) = redarray_copy(k) + redarray(k)&lt;/P&gt;&lt;P&gt;enddo&lt;/P&gt;&lt;P&gt;enddo&lt;/P&gt;&lt;P&gt;!$OMP END DO&lt;/P&gt;&lt;P&gt;!$OMP END PARALLEL&lt;/P&gt;&lt;P&gt;redarray = redarray_copy&lt;/P&gt;&lt;BR /&gt;Patrick</description>
      <pubDate>Thu, 08 Dec 2011 21:01:53 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760200#M15687</guid>
      <dc:creator>pbkenned1</dc:creator>
      <dc:date>2011-12-08T21:01:53Z</dc:date>
    </item>
    <item>
      <title>OpenMP Reduction on Array in COMMON block being set in non inli</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760201#M15688</link>
      <description>That's great ! I wish I could have thought doing so before !&lt;BR /&gt;&lt;BR /&gt;To initialize, do you reckon a COPYIN or a mere:&lt;BR /&gt;!$OMP DO&lt;BR /&gt;do i=1,j&lt;BR /&gt;redarray = 0&lt;BR /&gt;enddo&lt;BR /&gt;&lt;BR /&gt;To finalize, do you reckon a REDUCTION or a&lt;BR /&gt;!$OMP DO&lt;BR /&gt;do i=1, j&lt;BR /&gt;!$OMP CRITICAL&lt;BR /&gt;redarray_copy = redarray_copy + redarray&lt;BR /&gt;!$OMP END CRITICAL&lt;BR /&gt;enddo&lt;BR /&gt;&lt;BR /&gt;Thansk a lot</description>
      <pubDate>Fri, 09 Dec 2011 17:49:05 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760201#M15688</guid>
      <dc:creator>Olivier_C_</dc:creator>
      <dc:date>2011-12-09T17:49:05Z</dc:date>
    </item>
    <item>
      <title>OpenMP Reduction on Array in COMMON block being set in non inli</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760202#M15689</link>
      <description>Thanks Jim, but indir is in fact not initialized this way: it 'is a cell to material non injective mapping.&lt;BR /&gt;Sorry, I should have pointed it out before. Cheers.</description>
      <pubDate>Fri, 09 Dec 2011 17:52:18 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760202#M15689</guid>
      <dc:creator>Olivier_C_</dc:creator>
      <dc:date>2011-12-09T17:52:18Z</dc:date>
    </item>
    <item>
      <title>OpenMP Reduction on Array in COMMON block being set in non inli</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760203#M15690</link>
      <description>Hello Oliver,&lt;BR /&gt;I'd recommend both COPYIN and REDUCTION over loop-based initialization/finalization, sincethey might be a little bit more efficient, especially the REDUCTION. REDUCTIONs are optimised for the target machine and don't have the global overhead of unnamed CRITICAL sections. If you prefer a CRITICAL section, I suggest using a named CRITICAL section...but don't use the same name you've given to the COMMON block (comarray). That's because CRITICAL section namesare in the same namespace as COMMON block names, and conflicts can result in undefined behaviour.&lt;BR /&gt;&lt;BR /&gt;Patrick Kennedy</description>
      <pubDate>Fri, 09 Dec 2011 18:26:47 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760203#M15690</guid>
      <dc:creator>pbkenned1</dc:creator>
      <dc:date>2011-12-09T18:26:47Z</dc:date>
    </item>
    <item>
      <title>OpenMP Reduction on Array in COMMON block being set in non inli</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760204#M15691</link>
      <description>Clear.&lt;BR /&gt;Thanks !&lt;BR /&gt;Oliver.</description>
      <pubDate>Sat, 10 Dec 2011 10:21:49 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/OpenMP-Reduction-on-Array-in-COMMON-block-being-set-in-non/m-p/760204#M15691</guid>
      <dc:creator>Olivier_C_</dc:creator>
      <dc:date>2011-12-10T10:21:49Z</dc:date>
    </item>
  </channel>
</rss>

