Skip to content

Instantly share code, notes, and snippets.

@Guymer
Created January 9, 2019 17:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Guymer/f689504f47c983f8acf7aee214e7c94e to your computer and use it in GitHub Desktop.
Save Guymer/f689504f47c983f8acf7aee214e7c94e to your computer and use it in GitHub Desktop.
a demonstration of linearizing nested do-loop indexes (for use with MPI)
MODULE foo
USE ISO_FORTRAN_ENV
IMPLICIT NONE
INTERFACE func_overall_index
MODULE PROCEDURE func_overall_index_2loops
MODULE PROCEDURE func_overall_index_3loops
MODULE PROCEDURE func_overall_index_4loops
MODULE PROCEDURE func_overall_index_5loops
MODULE PROCEDURE func_overall_index_6loops
MODULE PROCEDURE func_overall_index_7loops
END INTERFACE func_overall_index
CONTAINS
ELEMENTAL FUNCTION func_overall_index_2loops(i1, i2, n1, n2) RESULT(ans)
! NOTE: Assume all indexes go from 1 to n (inclusive).
! NOTE: Assume i1 to i2 goes from the outer loop to the inner loop.
USE ISO_FORTRAN_ENV
IMPLICIT NONE
INTEGER(kind = INT64), INTENT(in) :: i1
INTEGER(kind = INT64), INTENT(in) :: i2
INTEGER(kind = INT64), INTENT(in) :: n1
INTEGER(kind = INT64), INTENT(in) :: n2
INTEGER(kind = INT64) :: ans
ans = i2 + n2 * (i1 - 1_INT64)
END FUNCTION
ELEMENTAL FUNCTION func_overall_index_3loops(i1, i2, i3, n1, n2, n3) RESULT(ans)
! NOTE: Assume all indexes go from 1 to n (inclusive).
! NOTE: Assume i1 to i3 goes from the outer loop to the inner loop.
USE ISO_FORTRAN_ENV
IMPLICIT NONE
INTEGER(kind = INT64), INTENT(in) :: i1
INTEGER(kind = INT64), INTENT(in) :: i2
INTEGER(kind = INT64), INTENT(in) :: i3
INTEGER(kind = INT64), INTENT(in) :: n1
INTEGER(kind = INT64), INTENT(in) :: n2
INTEGER(kind = INT64), INTENT(in) :: n3
INTEGER(kind = INT64) :: ans
ans = i3 + n3 * ((i2 - 1_INT64) + n2 * (i1 - 1_INT64))
END FUNCTION
ELEMENTAL FUNCTION func_overall_index_4loops(i1, i2, i3, i4, n1, n2, n3, n4) RESULT(ans)
! NOTE: Assume all indexes go from 1 to n (inclusive).
! NOTE: Assume i1 to i4 goes from the outer loop to the inner loop.
USE ISO_FORTRAN_ENV
IMPLICIT NONE
INTEGER(kind = INT64), INTENT(in) :: i1
INTEGER(kind = INT64), INTENT(in) :: i2
INTEGER(kind = INT64), INTENT(in) :: i3
INTEGER(kind = INT64), INTENT(in) :: i4
INTEGER(kind = INT64), INTENT(in) :: n1
INTEGER(kind = INT64), INTENT(in) :: n2
INTEGER(kind = INT64), INTENT(in) :: n3
INTEGER(kind = INT64), INTENT(in) :: n4
INTEGER(kind = INT64) :: ans
ans = i4 + n4 * ((i3 - 1_INT64) + n3 * ((i2 - 1_INT64) + n2 * (i1 - 1_INT64)))
END FUNCTION
ELEMENTAL FUNCTION func_overall_index_5loops(i1, i2, i3, i4, i5, n1, n2, n3, n4, n5) RESULT(ans)
! NOTE: Assume all indexes go from 1 to n (inclusive).
! NOTE: Assume i1 to i5 goes from the outer loop to the inner loop.
USE ISO_FORTRAN_ENV
IMPLICIT NONE
INTEGER(kind = INT64), INTENT(in) :: i1
INTEGER(kind = INT64), INTENT(in) :: i2
INTEGER(kind = INT64), INTENT(in) :: i3
INTEGER(kind = INT64), INTENT(in) :: i4
INTEGER(kind = INT64), INTENT(in) :: i5
INTEGER(kind = INT64), INTENT(in) :: n1
INTEGER(kind = INT64), INTENT(in) :: n2
INTEGER(kind = INT64), INTENT(in) :: n3
INTEGER(kind = INT64), INTENT(in) :: n4
INTEGER(kind = INT64), INTENT(in) :: n5
INTEGER(kind = INT64) :: ans
ans = i5 + n5 * ((i4 - 1_INT64) + n4 * ((i3 - 1_INT64) + n3 * ((i2 - 1_INT64) + n2 * (i1 - 1_INT64))))
END FUNCTION
ELEMENTAL FUNCTION func_overall_index_6loops(i1, i2, i3, i4, i5, i6, n1, n2, n3, n4, n5, n6) RESULT(ans)
! NOTE: Assume all indexes go from 1 to n (inclusive).
! NOTE: Assume i1 to i6 goes from the outer loop to the inner loop.
USE ISO_FORTRAN_ENV
IMPLICIT NONE
INTEGER(kind = INT64), INTENT(in) :: i1
INTEGER(kind = INT64), INTENT(in) :: i2
INTEGER(kind = INT64), INTENT(in) :: i3
INTEGER(kind = INT64), INTENT(in) :: i4
INTEGER(kind = INT64), INTENT(in) :: i5
INTEGER(kind = INT64), INTENT(in) :: i6
INTEGER(kind = INT64), INTENT(in) :: n1
INTEGER(kind = INT64), INTENT(in) :: n2
INTEGER(kind = INT64), INTENT(in) :: n3
INTEGER(kind = INT64), INTENT(in) :: n4
INTEGER(kind = INT64), INTENT(in) :: n5
INTEGER(kind = INT64), INTENT(in) :: n6
INTEGER(kind = INT64) :: ans
ans = i6 + n6 * ((i5 - 1_INT64) + n5 * ((i4 - 1_INT64) + n4 * ((i3 - 1_INT64) + n3 * ((i2 - 1_INT64) + n2 * (i1 - 1_INT64)))))
END FUNCTION
ELEMENTAL FUNCTION func_overall_index_7loops(i1, i2, i3, i4, i5, i6, i7, n1, n2, n3, n4, n5, n6, n7) RESULT(ans)
! NOTE: Assume all indexes go from 1 to n (inclusive).
! NOTE: Assume i1 to i7 goes from the outer loop to the inner loop.
USE ISO_FORTRAN_ENV
IMPLICIT NONE
INTEGER(kind = INT64), INTENT(in) :: i1
INTEGER(kind = INT64), INTENT(in) :: i2
INTEGER(kind = INT64), INTENT(in) :: i3
INTEGER(kind = INT64), INTENT(in) :: i4
INTEGER(kind = INT64), INTENT(in) :: i5
INTEGER(kind = INT64), INTENT(in) :: i6
INTEGER(kind = INT64), INTENT(in) :: i7
INTEGER(kind = INT64), INTENT(in) :: n1
INTEGER(kind = INT64), INTENT(in) :: n2
INTEGER(kind = INT64), INTENT(in) :: n3
INTEGER(kind = INT64), INTENT(in) :: n4
INTEGER(kind = INT64), INTENT(in) :: n5
INTEGER(kind = INT64), INTENT(in) :: n6
INTEGER(kind = INT64), INTENT(in) :: n7
INTEGER(kind = INT64) :: ans
ans = i7 + n7 * ((i6 - 1_INT64) + n6 * ((i5 - 1_INT64) + n5 * ((i4 - 1_INT64) + n4 * ((i3 - 1_INT64) + n3 * ((i2 - 1_INT64) + n2 * (i1 - 1_INT64))))))
END FUNCTION
END MODULE foo
PROGRAM bar
USE ISO_FORTRAN_ENV
USE foo
IMPLICIT NONE
INTEGER(kind = INT64), PARAMETER :: n1 = 2
INTEGER(kind = INT64), PARAMETER :: n2 = 4
INTEGER(kind = INT64), PARAMETER :: n3 = 6
INTEGER(kind = INT64), PARAMETER :: n4 = 8
INTEGER(kind = INT64), PARAMETER :: n5 = 10
INTEGER(kind = INT64), PARAMETER :: n6 = 12
INTEGER(kind = INT64), PARAMETER :: n7 = 14
INTEGER(kind = INT64) :: i1
INTEGER(kind = INT64) :: i2
INTEGER(kind = INT64) :: i3
INTEGER(kind = INT64) :: i4
INTEGER(kind = INT64) :: i5
INTEGER(kind = INT64) :: i6
INTEGER(kind = INT64) :: i7
DO i1 = 1_INT64, n1
DO i2 = 1_INT64, n2
DO i3 = 1_INT64, n3
WRITE(fmt = '(3(1x, i2, "/", i2), i9)', unit = OUTPUT_UNIT) i1, n1, i2, n2, i3, n3, func_overall_index(i1, i2, i3, n1, n2, n3)
END DO
END DO
END DO
DO i1 = 1_INT64, n1
DO i2 = 1_INT64, n2
DO i3 = 1_INT64, n3
DO i4 = 1_INT64, n4
DO i5 = 1_INT64, n5
DO i6 = 1_INT64, n6
DO i7 = 1_INT64, n7
WRITE(fmt = '(7(1x, i2, "/", i2), i9)', unit = OUTPUT_UNIT) i1, n1, i2, n2, i3, n3, i4, n4, i5, n5, i6, n6, i7, n7, func_overall_index(i1, i2, i3, i4, i5, i6, i7, n1, n2, n3, n4, n5, n6, n7)
END DO
END DO
END DO
END DO
END DO
END DO
END DO
END PROGRAM bar
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment