Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeffrey Overbey2012-05-04 15:34:35 +0000
committerJeffrey Overbey2012-05-04 15:34:35 +0000
commitbe187d6c3332ba2f89d3c52234ac437c9c0a77ea (patch)
treeeee786d82e1ac1310172564d17fb8686302f4373
parenta7d0900fdd57515932f4732bd367c651ec570f42 (diff)
downloadorg.eclipse.photran-be187d6c3332ba2f89d3c52234ac437c9c0a77ea.tar.gz
org.eclipse.photran-be187d6c3332ba2f89d3c52234ac437c9c0a77ea.tar.xz
org.eclipse.photran-be187d6c3332ba2f89d3c52234ac437c9c0a77ea.zip
Added OpenMP and OpenACC versions of Liebmann example; fixed Makefile
-rw-r--r--org.eclipse.photran-samples/Makefile55
-rw-r--r--org.eclipse.photran-samples/src-liebmann-4-openacc/liebmann.f90103
-rw-r--r--org.eclipse.photran-samples/src-liebmann-5-openmp/Makefile30
-rw-r--r--org.eclipse.photran-samples/src-liebmann-5-openmp/liebmann.f90111
4 files changed, 274 insertions, 25 deletions
diff --git a/org.eclipse.photran-samples/Makefile b/org.eclipse.photran-samples/Makefile
index 35b9b861..d7c31e73 100644
--- a/org.eclipse.photran-samples/Makefile
+++ b/org.eclipse.photran-samples/Makefile
@@ -28,7 +28,8 @@ EXEFILES=$(EXEFILE) *.exe
all: clean build
clean:
- for dir in $(SRCDIRS) .; do \
+ @echo Cleaning output files
+ @for dir in $(SRCDIRS) .; do \
cd $$dir; \
rm -f $(OBJFILES) >/dev/null 2>&1; \
rm -f $(OTHERFILES) >/dev/null 2>&1; \
@@ -37,27 +38,31 @@ clean:
done
build:
- @echo "=====>" Using compiler $(FORTRAN)
- @for dir in $(SRCDIRS); do \
- if [ -e $$dir/Makefile ]; then \
- $(MAKE) -C $$dir; \
- else \
- echo "=====>" Begin compiling sources in $$dir; \
- $(FORTRAN) $(DEBUGSWITCH) \
- $(OUTSWITCH) $$dir/$(EXEFILE) \
- $(INCLUDESWITCH). \
- $(INCLUDESWITCH)$$dir \
- $(LIBSWITCH). \
- $(LIBSWITCH)$$dir \
- $(OPTSWITCH) \
- $(CRAYSWITCH) \
- $$dir/$(SRCFILES); \
- echo "<=====" Done compiling sources in $$dir; \
- fi \
- done
- @for dir in $(SRCDIRS) .; do \
- cd $$dir; \
- rm -f $(OBJFILES) >/dev/null 2>&1; \
- rm -f $(OTHERFILES) >/dev/null 2>&1; \
- cd ..; \
- done
+ @if [ "$(FORTRAN)" == "" ]; then \
+ echo "No Fortran compiler found; cannot compile photran-samples"; \
+ else \
+ echo "=====>" Using compiler $(FORTRAN); \
+ for dir in $(SRCDIRS); do \
+ if [ -e $$dir/Makefile ]; then \
+ $(MAKE) -C $$dir; \
+ else \
+ echo "=====>" Begin compiling sources in $$dir; \
+ $(FORTRAN) $(DEBUGSWITCH) \
+ $(OUTSWITCH) $$dir/$(EXEFILE) \
+ $(INCLUDESWITCH). \
+ $(INCLUDESWITCH)$$dir \
+ $(LIBSWITCH). \
+ $(LIBSWITCH)$$dir \
+ $(OPTSWITCH) \
+ $(CRAYSWITCH) \
+ $$dir/$(SRCFILES); \
+ echo "<=====" Done compiling sources in $$dir; \
+ fi \
+ done; \
+ for dir in $(SRCDIRS) .; do \
+ cd $$dir; \
+ rm -f $(OBJFILES) >/dev/null 2>&1; \
+ rm -f $(OTHERFILES) >/dev/null 2>&1; \
+ cd ..; \
+ done; \
+ fi
diff --git a/org.eclipse.photran-samples/src-liebmann-4-openacc/liebmann.f90 b/org.eclipse.photran-samples/src-liebmann-4-openacc/liebmann.f90
new file mode 100644
index 00000000..e7656f4d
--- /dev/null
+++ b/org.eclipse.photran-samples/src-liebmann-4-openacc/liebmann.f90
@@ -0,0 +1,103 @@
+!!
+!! Liebmann's method to compute heat transfer across a 2-D surface
+!! J. Overbey 8/27/08, updated for OpenACC 5/3/12
+!!
+!! Use liebmann-viz.sh in the main project directory to visualize the resulting
+!! table using gnuplot
+!!
+!! This version is based on the code in src-liebmann-3-loops, but
+!! (1) the "iterate" subroutine is inlined,
+!! (2) the number of iterations is always a multiple of 2 (delta is
+!! only computed on even-numbered iterations), and
+!! (3) with an OpenACC-compliant compiler (e.g., Cray Fortran 8.0), the
+!! stencil computations will be moved to an accelerator device/GPU
+!!
+program liebmann_example
+ implicit none
+
+ integer, parameter :: SIZE = 4096
+ integer, parameter :: INTERIOR_SIZE = SIZE - 2
+ integer, parameter :: OUTPUT_SIZE = 128
+ real, parameter :: BOUNDARY_VALUE = 5.0
+ real, parameter :: EPSILON = 0.001
+
+ call main()
+
+contains
+
+subroutine main()
+ real :: surface(SIZE, SIZE)
+ integer :: i, j
+
+ integer :: start_time, end_time, count_rate
+
+ call system_clock(start_time, count_rate)
+ call liebmann(surface)
+ call system_clock(end_time)
+
+ do i = 1, SIZE, SIZE/OUTPUT_SIZE
+ do j = 1, SIZE-1, SIZE/OUTPUT_SIZE
+ write (*,'(F4.2" ")',advance="no") surface(i, j)
+ end do
+ write (*,'(F4.2" ")') surface(i, SIZE)
+ end do
+
+ print *, "Elapsed Time (seconds):", real(end_time - start_time) / real(count_rate)
+end subroutine
+
+subroutine liebmann(surface)
+ real, dimension(SIZE, SIZE), intent(out) :: surface
+ real, dimension(SIZE, SIZE) :: prev, next
+ real :: delta
+ integer :: i, j
+ logical :: done
+
+ call init_with_boundaries(prev)
+ call init_with_boundaries(next)
+
+ !$acc data copyin(prev,next) copyout(prev)
+ done = .false.
+ do while (.not. done)
+ !$acc parallel loop
+ do j = 2, SIZE-1
+ do i = 2, SIZE-1
+ next(i,j) = &
+ (prev(i-1, j) + &
+ prev(i+1, j) + &
+ prev(i, j-1) + &
+ prev(i, j+1)) / 4.0
+ end do
+ end do
+ !$acc end parallel loop
+ delta = 0.0
+ !$acc parallel loop reduction(max:delta)
+ do j = 2, SIZE-1
+ do i = 2, SIZE-1
+ prev(i,j) = &
+ (next(i-1, j) + &
+ next(i+1, j) + &
+ next(i, j-1) + &
+ next(i, j+1)) / 4.0
+ delta = max(delta, abs(prev(i,j)-next(i,j)))
+ end do
+ end do
+ !$acc end parallel loop
+ if (delta < EPSILON) then
+ done = .true.
+ end if
+ end do
+ !$acc end data
+ surface = prev
+end subroutine
+
+subroutine init_with_boundaries(surface)
+ real, dimension(SIZE, SIZE), intent(out) :: surface
+
+ surface = 0.0
+ surface(1, :) = BOUNDARY_VALUE
+ surface(SIZE, :) = BOUNDARY_VALUE
+ surface(:, 1) = BOUNDARY_VALUE
+ surface(:, SIZE) = BOUNDARY_VALUE
+end subroutine
+
+end program
diff --git a/org.eclipse.photran-samples/src-liebmann-5-openmp/Makefile b/org.eclipse.photran-samples/src-liebmann-5-openmp/Makefile
new file mode 100644
index 00000000..a0b73c19
--- /dev/null
+++ b/org.eclipse.photran-samples/src-liebmann-5-openmp/Makefile
@@ -0,0 +1,30 @@
+.PHONY: all clean
+SRC=$(wildcard *.f90)
+
+GFORTRAN=`which gfortran 2>/dev/null | head -1`
+IFORT=`which ifort 2>/dev/null | head -1`
+DEBUGSWITCH=-g
+OPTSWITCH=-O4
+OUTSWITCH=-o
+
+all:
+ @if [ "$(GFORTRAN)" != "" ]; then \
+ for file in $(SRC); do \
+ $(GFORTRAN) -fopenmp \
+ $(DEBUGSWITCH) \
+ $(OUTSWITCH) `echo $$file | sed -e 's/.f90/.exe/'` \
+ $(OPTSWITCH) \
+ $$file; \
+ done; \
+ elif [ "$(IFORT)" != "" ]; then \
+ for file in $(SRC); do \
+ $(IFORT) -openmp \
+ $(DEBUGSWITCH) \
+ $(OUTSWITCH) `echo $$file | sed -e 's/.f90/.exe/'` \
+ $(OPTSWITCH) \
+ $$file; \
+ done; \
+ fi
+
+clean:
+ rm -f *.exe *.mod \ No newline at end of file
diff --git a/org.eclipse.photran-samples/src-liebmann-5-openmp/liebmann.f90 b/org.eclipse.photran-samples/src-liebmann-5-openmp/liebmann.f90
new file mode 100644
index 00000000..1aa2e24d
--- /dev/null
+++ b/org.eclipse.photran-samples/src-liebmann-5-openmp/liebmann.f90
@@ -0,0 +1,111 @@
+!!
+!! Liebmann's method to compute heat transfer across a 2-D surface
+!! J. Overbey 8/27/08, updated for OpenMP 5/3/12
+!!
+!! Use liebmann-viz.sh in the main project directory to visualize the resulting
+!! table using gnuplot
+!!
+!! This version is based on the code in src-liebmann-4-openacc but uses OpenMP
+!! rather than OpenACC.
+!!
+program liebmann_example
+ implicit none
+
+ integer, parameter :: SIZE = 4096
+ integer, parameter :: INTERIOR_SIZE = SIZE - 2
+ integer, parameter :: OUTPUT_SIZE = 128
+ real, parameter :: BOUNDARY_VALUE = 5.0
+ real, parameter :: EPSILON = 0.001
+
+ call main()
+
+contains
+
+subroutine main()
+ real :: surface(SIZE, SIZE)
+ integer :: i, j
+ integer :: num_threads
+ integer :: start_time, end_time, count_rate
+
+ call system_clock(start_time, count_rate)
+ call liebmann(surface, num_threads)
+ call system_clock(end_time)
+
+ do i = 1, SIZE, SIZE/OUTPUT_SIZE
+ do j = 1, SIZE-1, SIZE/OUTPUT_SIZE
+ write (*,'(F4.2" ")',advance="no") surface(i, j)
+ end do
+ write (*,'(F4.2" ")') surface(i, SIZE)
+ end do
+
+ print *, "Threads: ", num_threads
+ print *, "Elapsed Time (seconds):", real(end_time - start_time) / real(count_rate)
+end subroutine
+
+subroutine liebmann(surface, num_threads)
+ real, dimension(SIZE, SIZE), intent(out) :: surface
+ integer, intent(out) :: num_threads
+ real, dimension(SIZE, SIZE) :: prev, next
+ real :: delta
+ integer :: i, j
+ logical :: done
+
+ done = .false.
+
+ !$omp parallel
+ !$omp master
+ num_threads = omp_get_num_threads()
+ !$omp end master
+ !$omp end parallel
+
+ call init_with_boundaries(prev)
+ call init_with_boundaries(next)
+
+ done = .false.
+ !$omp parallel
+ do while (.not. done)
+ !$omp do schedule(static) private(i)
+ do j = 2, SIZE-1
+ do i = 2, SIZE-1
+ next(i,j) = &
+ (prev(i-1, j) + &
+ prev(i+1, j) + &
+ prev(i, j-1) + &
+ prev(i, j+1)) / 4.0
+ end do
+ end do
+ !$omp end do
+ delta = 0.0
+ !$omp do schedule(static) private(i) reduction(max:delta)
+ do j = 2, SIZE-1
+ do i = 2, SIZE-1
+ prev(i,j) = &
+ (next(i-1, j) + &
+ next(i+1, j) + &
+ next(i, j-1) + &
+ next(i, j+1)) / 4.0
+ delta = max(delta, abs(prev(i,j)-next(i,j)))
+ end do
+ end do
+ !$omp end do
+ !$omp single
+ if (delta < EPSILON) then
+ done = .true.
+ end if
+ !$omp end single
+ end do
+ !$omp end parallel
+ surface = prev
+end subroutine
+
+subroutine init_with_boundaries(surface)
+ real, dimension(SIZE, SIZE), intent(out) :: surface
+
+ surface = 0.0
+ surface(1, :) = BOUNDARY_VALUE
+ surface(SIZE, :) = BOUNDARY_VALUE
+ surface(:, 1) = BOUNDARY_VALUE
+ surface(:, SIZE) = BOUNDARY_VALUE
+end subroutine
+
+end program

Back to the top