diff --git a/4-add-test-cases-for-openmp-optimization.patch b/4-add-test-cases-for-openmp-optimization.patch new file mode 100644 index 0000000000000000000000000000000000000000..0ad48aa401d38dca7d95835ce84c371155b283eb --- /dev/null +++ b/4-add-test-cases-for-openmp-optimization.patch @@ -0,0 +1,564 @@ +From 3349f79b289c2e5cbe35bf1fd0b9533a5f54f19b Mon Sep 17 00:00:00 2001 +From: xieyihui +Date: Mon, 26 Sep 2022 16:14:11 +0800 +Subject: [PATCH] add test cases for OpenMP optimazation + +diff --git a/test/openmp_optimization/fortran_main001.f90 b/test/openmp_optimization/fortran_main001.f90 +new file mode 100644 +index 0000000..395f415 +--- /dev/null ++++ b/test/openmp_optimization/fortran_main001.f90 +@@ -0,0 +1,24 @@ ++! Test optimizaton for fortran use openmp about parallel region merge ++! ++program main ++ use omp_lib ++ real(kind = 8) :: starttime, endtime, time ++ integer :: a(100) ++ integer :: b(100) ++ starttime = omp_get_wtime() ++ do n = 1, 100000 ++ !$omp parallel do ++ do i = 1, 100 ++ a(i) = i ++ end do ++ !$omp end parallel do ++ !$omp parallel do ++ do i = 1, 100 ++ b(i) = i ++ end do ++ !$omp end parallel do ++ end do ++ endtime = omp_get_wtime() ++ time = endtime - starttime ++print *, time ++end program main +\ No newline at end of file +diff --git a/test/openmp_optimization/fortran_main002.f90 b/test/openmp_optimization/fortran_main002.f90 +new file mode 100644 +index 0000000..27ed00e +--- /dev/null ++++ b/test/openmp_optimization/fortran_main002.f90 +@@ -0,0 +1,21 @@ ++! Test optimizaton for fortran use openmp about implicit nowait at end ++! of parallel region ++! ++program main ++ use omp_lib ++ real(kind = 8) :: starttime, endtime, time ++ integer :: a(100) ++ starttime = omp_get_wtime() ++ do n = 1, 100000 ++ !$omp parallel ++ !$omp do ++ do i = 1, 100 ++ a(i) = i ++ end do ++ !$omp end do ++ !$omp end parallel ++ end do ++ endtime = omp_get_wtime() ++ time = endtime - starttime ++ print *, time ++end program main +diff --git a/test/openmp_optimization/fortran_main003.f90 b/test/openmp_optimization/fortran_main003.f90 +new file mode 100644 +index 0000000..9f70283 +--- /dev/null ++++ b/test/openmp_optimization/fortran_main003.f90 +@@ -0,0 +1,27 @@ ++! Test help optimize code with the OpenMP directive. OpenMP directives ++! may help the compiler to generate better code because he knows that ++! certain preconditions are fulfilled. Compiler cannot assume that the ++! different iterations of the loop are independent. But there is omp ++! parallel do. The loop also can be optimized by vectorization ++! ++program main ++ use omp_lib ++ real(kind = 8) :: starttime, endtime, time ++ integer :: a(100) ++ integer :: b(100) ++ integer :: index(100) ++ do i = 1, 100 ++ index(i) = i ++ end do ++ starttime = omp_get_wtime() ++ do n = 1, 100000 ++ !$omp parallel do ++ do i = 1, 100 ++ a(index(i)) = a(index(i)) + b(i) ++ end do ++ !$omp end parallel do ++ end do ++ endtime = omp_get_wtime() ++ time = endtime - starttime ++ print *, time ++end program main +\ No newline at end of file +diff --git a/test/openmp_optimization/fortran_main004.f90 b/test/openmp_optimization/fortran_main004.f90 +new file mode 100644 +index 0000000..d3a5f0e +--- /dev/null ++++ b/test/openmp_optimization/fortran_main004.f90 +@@ -0,0 +1,26 @@ ++! Test optimizaton for fortran use openmp about remove the redundant ++! barrier ++! ++program main ++ use omp_lib ++ real(kind = 8) :: starttime, endtime, time ++ integer :: a(100), b(100), c(100), d(100) ++ starttime = omp_get_wtime() ++ do n = 1, 100000 ++ !$omp parallel ++ !$omp do ++ do i = 1, 100 ++ a(i) = d(i) ++ end do ++ !$omp end do ++ !$omp do ++ do i = 1, 100 ++ b(i) = c(i) ++ end do ++ !$omp end do ++ !$omp end parallel ++ end do ++ endtime = omp_get_wtime() ++ time = endtime - starttime ++ print *, time ++end program main +\ No newline at end of file +diff --git a/test/openmp_optimization/fortran_main005.f90 b/test/openmp_optimization/fortran_main005.f90 +new file mode 100644 +index 0000000..e6cff9b +--- /dev/null ++++ b/test/openmp_optimization/fortran_main005.f90 +@@ -0,0 +1,26 @@ ++! Test optimizaton for fortran use openmp about remove the redundant ++! barrier ++! ++program main ++ use omp_lib ++ real(kind = 8) :: starttime, endtime, time ++ integer :: a(100), b(100) ++ starttime = omp_get_wtime() ++ do n = 1, 100000 ++ !$omp parallel ++ !$omp do ++ do i = 1, 99, 2 ++ a(i) = b(i) ++ end do ++ !$omp end do ++ !$omp do ++ do i = 2, 100, 2 ++ a(i) = b(i) ++ end do ++ !$omp end do ++ !$omp end parallel ++ end do ++ endtime = omp_get_wtime() ++ time = endtime - starttime ++ print *, time ++end program main +\ No newline at end of file +diff --git a/test/openmp_optimization/fortran_main006.f90 b/test/openmp_optimization/fortran_main006.f90 +new file mode 100644 +index 0000000..fc06654 +--- /dev/null ++++ b/test/openmp_optimization/fortran_main006.f90 +@@ -0,0 +1,19 @@ ++! Test optimizaton for fortran use openmp about implement of DOACROSS ++! parallelism ++! ++program main ++ use omp_lib ++ real(kind = 8) :: starttime, endtime, time ++ integer :: a(100, 100) ++ starttime = omp_get_wtime() ++ do n = 1, 50000 ++ do i = 2, 100 ++ do j = 2, 100 ++ a(i, j) = a(i - 1, j) + a(i, j-1) ++ end do ++ end do ++ end do ++ endtime = omp_get_wtime() ++ time = endtime - starttime ++ print *, time ++end program main +\ No newline at end of file +diff --git a/test/openmp_optimization/fortran_main007.f90 b/test/openmp_optimization/fortran_main007.f90 +new file mode 100644 +index 0000000..8da7ec6 +--- /dev/null ++++ b/test/openmp_optimization/fortran_main007.f90 +@@ -0,0 +1,21 @@ ++! Test optimizaton for fortran use openmp about orphaned directives ++! ++subroutine add1(s) ++ use omp_lib ++ real :: s ++ !$omp critical ++ s = s + 1 ++ !$omp end critical ++end subroutine add1 ++program main ++ use omp_lib ++ real(kind = 8) :: starttime, endtime, time ++ real :: a ++ starttime = omp_get_wtime() ++ do n = 1, 50000000 ++ call add1(a) ++ end do ++ endtime = omp_get_wtime() ++ time = endtime - starttime ++ print *, time ++end program main +\ No newline at end of file +diff --git a/test/openmp_optimization/fortran_main008.f90 b/test/openmp_optimization/fortran_main008.f90 +new file mode 100644 +index 0000000..aa70d3e +--- /dev/null ++++ b/test/openmp_optimization/fortran_main008.f90 +@@ -0,0 +1,24 @@ ++! Test optimizaton for fortran use openmp about alternative code. The ++! goal is to have the performance of the serial code if it is faster ++! than the parallel ++! ++subroutine add1(s, n) ++ use omp_lib ++ real :: s ++ integer :: n ++ !$omp parallel do ++ do i = 1, n ++ s = s + 1 ++ end do ++ !$omp end parallel do ++end subroutine add1 ++program main ++ use omp_lib ++ real(kind = 8) :: starttime, endtime, time ++ real :: a ++ starttime = omp_get_wtime() ++ call add1(a, 8000) ++ endtime = omp_get_wtime() ++ time = endtime - starttime ++ print *, time ++end program main +\ No newline at end of file +diff --git a/test/openmp_optimization/fortran_main009.f90 b/test/openmp_optimization/fortran_main009.f90 +new file mode 100644 +index 0000000..fffb89b +--- /dev/null ++++ b/test/openmp_optimization/fortran_main009.f90 +@@ -0,0 +1,25 @@ ++! Test optimizaton for fortran use openmp about parallel region merge ++! ++program main ++ use omp_lib ++ real(kind = 8) :: starttime, endtime, time ++ integer :: a(100) ++ integer :: n = 0 ++ starttime = omp_get_wtime() ++ do while (n <= 100000) ++ !$omp parallel do ++ do i = 1, 100 ++ a(i) = i + 1 ++ end do ++ !$omp end parallel do ++ !$omp parallel do ++ do i = 1, 100 ++ a(i) = i + a(i) ++ end do ++ !$omp end parallel do ++ n = n + 1 ++ end do ++ endtime = omp_get_wtime() ++ time = endtime - starttime ++ print *, time ++end program main +\ No newline at end of file +diff --git a/test/openmp_optimization/optimized_main001.f90 b/test/openmp_optimization/optimized_main001.f90 +new file mode 100644 +index 0000000..b131f57 +--- /dev/null ++++ b/test/openmp_optimization/optimized_main001.f90 +@@ -0,0 +1,20 @@ ++! Test optimizaton for fortran use openmp about parallel region merge ++! ++program main ++ use omp_lib ++ real(kind = 8) :: starttime, endtime, time ++ integer :: a(100) ++ integer :: b(100) ++ starttime = omp_get_wtime() ++ do n = 1, 100000 ++ !$omp parallel do ++ do i = 1, 100 ++ a(i) = i ++ b(i) = i ++ end do ++ !$omp end parallel do ++ end do ++ endtime = omp_get_wtime() ++ time = endtime - starttime ++ print *, time ++end program main +\ No newline at end of file +diff --git a/test/openmp_optimization/optimized_main002.f90 b/test/openmp_optimization/optimized_main002.f90 +new file mode 100644 +index 0000000..edfba4a +--- /dev/null ++++ b/test/openmp_optimization/optimized_main002.f90 +@@ -0,0 +1,21 @@ ++! Test optimizaton for fortran use openmp about implicit nowait at end ++! of parallel region ++! ++program main ++ use omp_lib ++ real(kind = 8) :: starttime, endtime, time ++ integer :: a(100) ++ starttime = omp_get_wtime() ++ do n = 1, 100000 ++ !$omp parallel ++ !$omp do ++ do i = 1, 100 ++ a(i) = i ++ end do ++ !$omp end do nowait ++ !$omp end parallel ++ end do ++ endtime = omp_get_wtime() ++ time = endtime - starttime ++ print *, time ++end program main +diff --git a/test/openmp_optimization/optimized_main004.f90 b/test/openmp_optimization/optimized_main004.f90 +new file mode 100644 +index 0000000..3274556 +--- /dev/null ++++ b/test/openmp_optimization/optimized_main004.f90 +@@ -0,0 +1,26 @@ ++! Test optimizaton for fortran use openmp about remove the redundant ++! barrier ++! ++program main ++ use omp_lib ++ real(kind = 8) :: starttime, endtime, time ++ integer :: a(100), b(100), c(100), d(100) ++ starttime = omp_get_wtime() ++ do n = 1, 100000 ++ !$omp parallel ++ !$omp do ++ do i = 1, 100 ++ a(i) = d(i) ++ end do ++ !$omp end do nowait ++ !$omp do ++ do i = 1, 100 ++ b(i) = c(i) ++ end do ++ !$omp end do nowait ++ !$omp end parallel ++ end do ++ endtime = omp_get_wtime() ++ time = endtime - starttime ++ print *, time ++end program main +\ No newline at end of file +diff --git a/test/openmp_optimization/optimized_main005.f90 b/test/openmp_optimization/optimized_main005.f90 +new file mode 100644 +index 0000000..79910a9 +--- /dev/null ++++ b/test/openmp_optimization/optimized_main005.f90 +@@ -0,0 +1,26 @@ ++! Test optimizaton for fortran use openmp about remove the redundant ++! barrier ++! ++program main ++ use omp_lib ++ real(kind = 8) :: starttime, endtime, time ++ integer :: a(100), b(100) ++ starttime = omp_get_wtime() ++ do n = 1, 100000 ++ !$omp parallel ++ !$omp do ++ do i = 1, 99, 2 ++ a(i) = b(i) ++ end do ++ !$omp end do nowait ++ !$omp do ++ do i = 2, 100, 2 ++ a(i) = b(i) ++ end do ++ !$omp end do nowait ++ !$omp end parallel ++ end do ++ endtime = omp_get_wtime() ++ time = endtime - starttime ++ print *, time ++end program main +\ No newline at end of file +diff --git a/test/openmp_optimization/optimized_main007.f90 b/test/openmp_optimization/optimized_main007.f90 +new file mode 100644 +index 0000000..557f705 +--- /dev/null ++++ b/test/openmp_optimization/optimized_main007.f90 +@@ -0,0 +1,25 @@ ++! Test optimizaton for fortran use openmp about orphaned directives ++! ++subroutine add1(s) ++ use omp_lib ++ real :: s ++ if(omp_in_parallel()) then ++ !$omp critical ++ s = s + 1 ++ !$omp end critical ++ else ++ s = s + 1 ++ end if ++end subroutine add1 ++program main ++ use omp_lib ++ real(kind = 8) :: starttime, endtime, time ++ real :: a ++ starttime = omp_get_wtime() ++ do n = 1, 50000000 ++ call add1(a) ++ end do ++ endtime = omp_get_wtime() ++ time = endtime - starttime ++ print *, time ++end program main +\ No newline at end of file +diff --git a/test/openmp_optimization/optimized_main008.f90 b/test/openmp_optimization/optimized_main008.f90 +new file mode 100644 +index 0000000..d0149b6 +--- /dev/null ++++ b/test/openmp_optimization/optimized_main008.f90 +@@ -0,0 +1,30 @@ ++! Test optimizaton for fortran use openmp about alternative code. The ++! goal is to have the performance of the serial code if it is faster ++! than the parallel ++! ++subroutine add1(s, n) ++ use omp_lib ++ real :: s ++ integer :: n ++ if(n > 10000) then ++ !$omp parallel do ++ do i = 1, n ++ s = s + 1 ++ end do ++ !$omp end parallel do ++ else ++ do i = 1, n ++ s = s + 1 ++ end do ++ end if ++end subroutine add1 ++program main ++ use omp_lib ++ real(kind = 8) :: starttime, endtime, time ++ real :: a ++ starttime = omp_get_wtime() ++ call add1(a, 8000) ++ endtime = omp_get_wtime() ++ time = endtime - starttime ++ print *, time ++end program main +\ No newline at end of file +diff --git a/test/openmp_optimization/optimized_main009.f90 b/test/openmp_optimization/optimized_main009.f90 +new file mode 100644 +index 0000000..b131f57 +--- /dev/null ++++ b/test/openmp_optimization/optimized_main009.f90 +@@ -0,0 +1,20 @@ ++! Test optimizaton for fortran use openmp about parallel region merge ++! ++program main ++ use omp_lib ++ real(kind = 8) :: starttime, endtime, time ++ integer :: a(100) ++ integer :: b(100) ++ starttime = omp_get_wtime() ++ do n = 1, 100000 ++ !$omp parallel do ++ do i = 1, 100 ++ a(i) = i ++ b(i) = i ++ end do ++ !$omp end parallel do ++ end do ++ endtime = omp_get_wtime() ++ time = endtime - starttime ++ print *, time ++end program main +\ No newline at end of file +diff --git a/test/openmp_optimization/readme.txt b/test/openmp_optimization/readme.txt +new file mode 100644 +index 0000000..010300e +--- /dev/null ++++ b/test/openmp_optimization/readme.txt +@@ -0,0 +1,19 @@ ++These files are designed to test how OpenMP programs can be optimized. ++This folder has two types of test file, one is unoptimized, the other ++one is optimized. ++ ++Testing Environment: 2-way 32-core Intel(R) Xeon(R) Silver 4215R CPU @ ++3.20GHz, 512GB RAM, X86 ++OMP_NUM_THREADS=8 ++ ++test every case 10 times ++ unoptimized optimized ++test001: 0.771 0.395 ++test002: 0.270 0.153 ++test003: Unable to optimize with hand-written code ++test004: 0.571 0.201 ++test005: 0.524 0.199 ++test006: Unable to optimize with hand-written code ++test007: 1.808 0.614 ++test008: 6.265E-03 1.313E-04 ++test009: 0.790 0.376 +\ No newline at end of file +diff --git a/test/openmp_optimization/run.sh b/test/openmp_optimization/run.sh +new file mode 100644 +index 0000000..510f119 +--- /dev/null ++++ b/test/openmp_optimization/run.sh +@@ -0,0 +1,32 @@ ++for i in {001..009} ++do ++echo "------- test $i ------." ++flang-new fortran_main$i.f90 -fopenmp ++export OMP_NUM_THREADS=8 ++./a.out ++rm a.out ++done ++for i in {001..002} ++do ++echo "------- test $i ------." ++flang-new optimized_main$i.f90 -fopenmp ++export OMP_NUM_THREADS=8 ++./a.out ++rm a.out ++done ++for i in {004..005} ++do ++echo "------- test $i ------." ++flang-new optimized_main$i.f90 -fopenmp ++export OMP_NUM_THREADS=8 ++./a.out ++rm a.out ++done ++for i in {007..009} ++do ++echo "------- test $i ------." ++flang-new optimized_main$i.f90 -fopenmp ++export OMP_NUM_THREADS=8 ++./a.out ++rm a.out ++done +\ No newline at end of file +-- +2.25.1 + diff --git a/flang.spec b/flang.spec index bbef480aeccbd03e4e359f2820c955fbb52ede2e..109321ed10c53a25ec8757b7371b833f1333fa4d 100644 --- a/flang.spec +++ b/flang.spec @@ -2,7 +2,7 @@ Name: flang Version: flang_20210324 -Release: 7 +Release: 8 Summary: Fortran language compiler targeting LLVM License: Apache-2.0 @@ -14,6 +14,7 @@ Requires: gcc >= 9.3.0 Patch0: 1-flang-runtime-inline.patch Patch1: 2-inline_f90_str_copy_klen.patch Patch2: 3-add-tests-interoperability-C.patch +Patch3: 4-add-test-cases-for-openmp-optimization.patch %description Flang depends on a fork of the LLVM project (https://github.com/flang-compiler/classic-flang-llvm-project). The fork made some changes to the upstream LLVM project to support Flang toolchain. Flang cannot build independently for now. @@ -35,6 +36,9 @@ TODO: support build Flang. %changelog +* Mon Sep 19 2022 xieyihui - flang_20210324-8 +- Add patch for add test cases for OpenMP optimization + * Thu Sep 8 2022 a - flang_20210324-7 - Add patch for add test cases for interoperability with C about fortran call C