Supported Fortran Directives
BiSheng compiler supports some of the Fortran directives. These directives instruct the compiler to perform optimization.
!$mem prefetch
This directive instructs the compiler to load specific data from the main memory to the L1/L2 cache. The method of using this directive is as follows:
1 2 3 4 | !$mem prefetch array1, array2, array2(i + 4) DO i=1,100 array1(i - 1) = array2(i - 1) + array2(i + 1) END DO |
In addition, prefetch with the specified cache level and cyclic iteration advance is supported. The usage is as follows:
prefetch: variable indicates the prefetch variable, locality indicates the cache level (1, 2, and 3 indicate L1, L2, and L3 respectively, and 4 indicates HBM cache), and distance indicates the cyclic iteration advance.
!$mem prefetch(variable, locality, distance)
noprefetch:
!$mem noprefetch(variable)
1 2 3 4 5 | !$mem prefetch(array1,4,5) !$mem noprefetch(array2) DO i=1,100 array1(i - 1) = array2(i - 1) + array2(i + 1) END DO |
!dir$ ivdep
This directive instructs the compiler to ignore the memory dependency of an iterative loop and to perform vectorization. The method of using this directive is as follows:
1 2 3 4 | !dir$ ivdep DO i=1, ub array1(i) = array1(i) + array2(i) END DO |
!$omp simd
This directive instructs the compiler to convert a loop to SIMD format. This is an OpenMP instruction that takes effect only after the -fopenmp option is specified. The method of using this directive is as follows:
1 2 3 4 | !$omp simd DO i=1, ub array1(i) = array1(i) + array2(i) END DO |
This directive does not support any clause.
!dir$ vector always
This directive forces the compiler to perform loop vectorization by ignoring cost-based dependencies. This operation takes effect immediately on the following loop. This directive requires the keyword "always" and cannot contain the keyword "never". The method of using this directive is as follows:
1 2 3 4 | !dir$ vector always DO i=1, ub array3(i) = array1(i) - array2(i) END DO |
!dir$ novector
This directive instructs the compiler not to perform loop vectorization, regardless of the optimization level. This operation takes effect immediately on the following loop. The method of using this directive is as follows:
1 2 3 4 | !dir$ novector DO i=1, ub array3(i) = array1(i) - array2(i) END DO |
!dir$ inline
This directive instructs the compiler to perform inlining for functions, regardless of the optimization level. This operation takes effect immediately on the following functions. The method of using this directive is as follows:
1 2 3 4 5 6 7 | !dir$ inline real function inline_func (num) implicit none real :: num inline_func = num + 1234 return end function |
!dir$ noinline
This directive instructs the compiler not to perform inlining for functions, regardless of the optimization level. This operation takes effect immediately on the following functions. The method of using this directive is as follows:
1 2 3 4 5 6 7 8 9 | !dir$ noinline subroutine noinline_func (a, b) integer, parameter :: m = 10 integer :: a(m), b(m) integer :: i do i = 1, m b(i) = a(i) + 1 end do end subroutine noinline_func |
!dir$ unroll
This directive instructs the compiler to perform loop unrolling, regardless of the optimization level. This operation takes effect immediately on the following loop. There are three methods of using this directive:
1 2 3 4 | !dir$ unroll -- Unroll all DO i=1, ub array3(i) = array1(i) - array2(i) END DO |
1 2 3 4 | !dir$ unroll (4) -- Unroll four times DO i=1, ub array3(i) = array1(i) - array2(i) END DO |
1 2 3 4 | !dir$ unroll = 2 -- Unroll twice DO i=1, ub array3(i) = array1(i) - array2(i) END DO |
!dir$ nounroll
This directive instructs the compiler to block the loop unrolling operation, immediately acting on the following loop. The method of using this directive is as follows:
1 2 3 4 | !dir$ nounroll DO i=1, 100 array1(i) = 5 END DO |