0

I recently read (here) that pure subroutines can allow better parallization optimizations. Assuming this is true, is there a way that I can make the following routine pure?

 subroutine diff_stag(operator,dfdh,f,T,dir,pad,gt)
   implicit none
   procedure(stencils_stag) :: operator
   type(realField),intent(inout) :: dfdh
   type(realField),intent(in) :: f
   type(triDiag),intent(in) :: T
   integer,intent(in) :: dir,pad,gt
   integer :: i,j,k
   select case (dir)
   case (1)
   !$OMP PARALLEL DO SHARED(T,f,gt)
   do k=1+pad,f%s(3)-pad; do j=1+pad,f%s(2)-pad
     call operator(dfdh%f(:,j,k),f%f(:,j,k),T,f%s(dir),dfdh%s(dir),gt)
   enddo; enddo
   !$OMP END PARALLEL DO
   case (2)
   !$OMP PARALLEL DO SHARED(T,f,gt)
   do k=1+pad,f%s(3)-pad; do i=1+pad,f%s(1)-pad
     call operator(dfdh%f(i,:,k),f%f(i,:,k),T,f%s(dir),dfdh%s(dir),gt)
   enddo; enddo
   !$OMP END PARALLEL DO
   case (3)
   !$OMP PARALLEL DO SHARED(T,f,gt)
   do j=1+pad,f%s(2)-pad; do i=1+pad,f%s(1)-pad
     call operator(dfdh%f(i,j,:),f%f(i,j,:),T,f%s(dir),dfdh%s(dir),gt)
   enddo; enddo
   !$OMP END PARALLEL DO
   case default
   stop 'Error: dir must = 1,2,3 in delGen_T in ops_del.f90.'
   end select
 end subroutine

The problem, I believe, is that the select case introduces a side effect, which is unallowed.

Is there a way that I can slice the fields f%f(i,j,k) and dfdh%f(i,j,k) so that the select case is not needed?

Any help is greatly appreciated!

Community
  • 1
  • 1
Charles
  • 947
  • 1
  • 15
  • 39

1 Answers1

3

The given subroutine cannot be made pure, as it contains a STOP statement.

Beyond that, whether the subroutine could be made pure would depend on whether the operator subroutine was pure (or could be made pure), and perhaps whether the derived types had pointer components.

I don't think "dynamic slicing" is relevant.

IanH
  • 21,026
  • 2
  • 37
  • 59
  • I see, I'm not actually getting compiler complaints removing the stop, but I *am* getting complaints about the compiler flags. I assume that what's important is that `call operator` is pure, rather than `diff_stag`. I guess my question was a bit hasty. I'll accept this answer if you can comment / confirm my conclusion in this comment. – Charles Sep 06 '16 at 17:47
  • I don't understand the comment. What "compiler flags"? When you say "what's important", important for what? – IanH Sep 06 '16 at 22:54
  • Sorry, I meant the `!$OMP PARALLEL DO SHARED(T,f,gt)` statements, not "compiler flags". Also, what I meant by 'what's important' is that, I believe, the `operator` subroutine should be pure for the compiler to optimize the parallelized loops, not the `diff_stag` subroutine. – Charles Sep 06 '16 at 23:15
  • If you are using the OpenMP parallel directives, the compiler is likely just going to do what those directives explicitly tell it to do, rather than any clever parallel optimisations. Whether the procedure being called is pure or not is probably a distraction. A procedure being pure won't hurt optimisation though. – IanH Sep 07 '16 at 01:44