COLLAPSE

Purpose

Specifying the COLLAPSE clause allows you to parallelize multiple loops in a nest without introducing nested parallelism.

Syntax

Read syntax diagramSkip visual syntax diagram
>>-COLLAPSE--(--n--)-------------------------------------------><

n
is a positive constant integer expression

Rules

Ordered construct
During execution of an iteration of a loop or a loop nested within a loop region, the executing thread must not execute more than one ordered region which binds to the same loop region. As a consequence, if multiple loops are associated to the loop construct by a collapse clause, the ordered construct has to be located inside all associated loops.
LASTPRIVATE clause
When a LASTPRIVATE clause appears on the directive that identifies a work-sharing construct, the value of each new list item from the sequentially last iteration of the associated loops is assigned to the original list item even if a collapse clause is associated with the loop
Other SMP and performance directives
The STREAM_UNROLL, UNROLL, UNROLL_AND_FUSE, and NOUNROLL_AND_FUSE directives cannot be used for any of the loops associated with the COLLAPSE clause loop nest. The INDEPENDENT directive can be used for any of the loops associated with the COLLAPSE clause.

Examples

In Example 1 and Example 2 the loops over k and j are collapsed and their iteration space is executed by all threads of the current team.

Example 1

    !$omp do collapse(2) private(i,j,k) 
       do k = kl, ku, ks 
         do j = jl, ju, js 
           do i = il, iu, is 
             call bar(a,i,j,k) 
           enddo 
         enddo 
       enddo 
    !$omp end do 

Example 2

 program test 
 !$omp parallel  
 !$omp do private(j,k) collapse(2) lastprivate(jlast, klast) 
       do k = 1,2 
         do j = 1,3 
            jlast=j 
            klast=k 
         enddo 
       enddo 
 !$omp end do 
 !$omp single 
     print *, klast, jlast  
 !$omp end single 
 !$omp end parallel 
 end program test 
Output:
2 3

Example 3

As both loops are collapsed into one, the ordered construct has to be inside all loops associated to the for construct. As an iteration may not execute more than one ordered region, this program would be incorrect without the collapse(2) clause.

program test 
!$omp parallel num_threads(2) 
 !$omp do collapse(2) ordered private(j,k) schedule(static,3) 
       do k = 1,3 
         do j = 1,2 
 !$omp ordered 
          print *, k, j 
 !$omp end ordered           
          enddo 
       enddo 
 !$omp end do 
 !$omp end parallel 
 end program test 
Output:
  1 1 
  1 2 
  2 1 
  2 2 
  3 1 
  3 2