From aa16d2a1c2e2c6dd6eb275807ba8e92b33cf40c0 Mon Sep 17 00:00:00 2001 From: Kjartan Thor Wikfeldt <ktwikfeldt@gmail.com> Date: Fri, 10 Aug 2018 15:10:27 +0200 Subject: [PATCH] rm solutions --- intro_lab/solutions/hello_par.c | 22 ------ intro_lab/solutions/hello_par.f90 | 22 ------ intro_lab/solutions/pi_loop.c | 65 ----------------- intro_lab/solutions/pi_loop.f90 | 56 --------------- intro_lab/solutions/pi_spmd_final.c | 94 ------------------------- intro_lab/solutions/pi_spmd_final.f90 | 66 ----------------- intro_lab/solutions/pi_spmd_simple.c | 92 ------------------------ intro_lab/solutions/pi_spmd_simple.f90 | 67 ------------------ intro_lab/solutions/solutions.zip | Bin 7353 -> 0 bytes 9 files changed, 484 deletions(-) delete mode 100755 intro_lab/solutions/hello_par.c delete mode 100755 intro_lab/solutions/hello_par.f90 delete mode 100755 intro_lab/solutions/pi_loop.c delete mode 100755 intro_lab/solutions/pi_loop.f90 delete mode 100755 intro_lab/solutions/pi_spmd_final.c delete mode 100755 intro_lab/solutions/pi_spmd_final.f90 delete mode 100755 intro_lab/solutions/pi_spmd_simple.c delete mode 100755 intro_lab/solutions/pi_spmd_simple.f90 delete mode 100644 intro_lab/solutions/solutions.zip diff --git a/intro_lab/solutions/hello_par.c b/intro_lab/solutions/hello_par.c deleted file mode 100755 index 93ae09f..0000000 --- a/intro_lab/solutions/hello_par.c +++ /dev/null @@ -1,22 +0,0 @@ -#include <stdio.h> -#include <omp.h> - -int main () -{ - int nthreads = 4; - omp_set_num_threads(nthreads); - - #pragma omp parallel - { - int id = omp_get_thread_num(); - - printf("Hello World from thread = %d", id); - printf(" with %d threads\n",omp_get_num_threads()); - } - - printf("all done, with hopefully %d threads\n",nthreads); - -} - - - diff --git a/intro_lab/solutions/hello_par.f90 b/intro_lab/solutions/hello_par.f90 deleted file mode 100755 index 5a535ef..0000000 --- a/intro_lab/solutions/hello_par.f90 +++ /dev/null @@ -1,22 +0,0 @@ -program hello_par - -use omp_lib - -implicit none - -integer :: num_threads = 4 -integer thread_id - -call OMP_SET_NUM_THREADS(num_threads) - -!$omp parallel private(thread_id) - - thread_id = OMP_GET_THREAD_NUM() - - print '("Hello World from thread = ", i0, " with ", i0, " threads")', thread_id, num_threads - -!$omp end parallel - -print '("all done, with hopefully ", i0, " threads")', num_threads - -end program diff --git a/intro_lab/solutions/pi_loop.c b/intro_lab/solutions/pi_loop.c deleted file mode 100755 index 4bac389..0000000 --- a/intro_lab/solutions/pi_loop.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - -This program will numerically compute the integral of - - 4/(1+x*x) - -from 0 to 1. The value of this integral is pi -- which -is great since it gives us an easy way to check the answer. - -The program was parallelized using OpenMP by adding just -four lines - -(1) A line to include omp.h -- the include file that -contains OpenMP's function prototypes and constants. - -(2) A pragma that tells OpenMP to create a team of threads - -(3) A pragma to cause one of the threads to print the -number of threads being used by the program. - -(4) A pragma to split up loop iterations among the team -of threads. This pragma includes 2 clauses to (1) create a -private variable and (2) to cause the threads to compute their -sums locally and then combine their local sums into a -single global value. - -History: Written by Tim Mattson, 11/99. - -*/ -#include <stdio.h> -#include <omp.h> -static long num_steps = 100000000; -double step; -int main () -{ - int i; - double x, pi, sum = 0.0; - double start_time, run_time; - - step = 1.0/(double) num_steps; - for (i=1;i<=4;i++){ - sum = 0.0; - omp_set_num_threads(i); - start_time = omp_get_wtime(); -#pragma omp parallel -{ -#pragma omp single - printf(" num_threads = %d",omp_get_num_threads()); - -#pragma omp for private(x) reduction(+:sum) - for (i=1;i<= num_steps; i++){ - x = (i-0.5)*step; - sum = sum + 4.0/(1.0+x*x); - } -} - pi = step * sum; - run_time = omp_get_wtime() - start_time; - printf("\n pi is %f in %f seconds and %d threads\n",pi,run_time,i); -} -} - - - - - diff --git a/intro_lab/solutions/pi_loop.f90 b/intro_lab/solutions/pi_loop.f90 deleted file mode 100755 index 286da85..0000000 --- a/intro_lab/solutions/pi_loop.f90 +++ /dev/null @@ -1,56 +0,0 @@ -! This program will numerically compute the integral of -! -! 4/(1+x*x) -! -! from 0 to 1. The value of this integral is pi -- which -! is great since it gives us an easy way to check the answer. - -program calc_pi - -use omp_lib - -implicit none - -integer, parameter :: MAX_THREADS = 4 - -integer(kind=8) :: num_steps = 100000000 - -real(kind=8) step - -integer i, num_threads -real(kind=8) x, pi, raw_sum -real(kind=8) start_time, run_time - -step = 1.0D0 / num_steps - -do num_threads = 1, MAX_THREADS - - call OMP_SET_NUM_THREADS(num_threads) - start_time = OMP_GET_WTIME() - - raw_sum = 0.0D0 - - !$omp parallel - - !$omp single - print '(" num_threads = ", i0)', num_threads - !$omp end single - - !$omp do private(x) reduction(+:raw_sum) - do i = 1, num_steps - x = (i-0.5D0)*step - raw_sum = raw_sum + 4.0D0/(1.0D0+x*x) - enddo - !$omp end do - - !$omp end parallel - - pi = step * raw_sum - - run_time = OMP_GET_WTIME() - start_time - print '(" pi is ", f12.6, " in ", f12.6, " seconds and ", i0, " threads. Error = ", e15.6)', & - pi, run_time, num_threads, abs(3.14159265358979323846D0 - pi) - -enddo - -end program diff --git a/intro_lab/solutions/pi_spmd_final.c b/intro_lab/solutions/pi_spmd_final.c deleted file mode 100755 index 59901fc..0000000 --- a/intro_lab/solutions/pi_spmd_final.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - -NAME: PI SPMD final version without false sharing - -This program will numerically compute the integral of - - 4/(1+x*x) - -from 0 to 1. The value of this integral is pi -- which -is great since it gives us an easy way to check the answer. - -The program was parallelized using OpenMP and an SPMD -algorithm. The following OpenMP specific lines were -added: - -(1) A line to include omp.h -- the include file that -contains OpenMP's function prototypes and constants. - -(2) A pragma that tells OpenMP to create a team of threads -with an integer variable i being created for each thread. - -(3) two function calls: one to get the thread ID (ranging -from 0 to one less than the number of threads), and the other -returning the total number of threads. - -(4) A "single" construct so only one thread prints the number -of threads. - -(5) A cyclic distribution of the loop by changing loop control -expressions to run from the thread ID incremented by the number -of threads. Local sums accumlated into sum[id]. - -(6) A barrier to make sure everyone's done. - -(7) A single construct so only one thread combines the local -sums into a single global sum. - -Note that this program avoids the false sharing problem -by storing partial sums into a private scalar. - -History: Written by Tim Mattson, 11/99. - -*/ - -#include <stdio.h> -#include <omp.h> - -#define MAX_THREADS 4 - -static long num_steps = 100000000; -double step; -int main () -{ - int i,j; - double pi, full_sum = 0.0; - double start_time, run_time; - double sum[MAX_THREADS]; - - step = 1.0/(double) num_steps; - - -for(j=1;j<=MAX_THREADS ;j++){ - omp_set_num_threads(j); - full_sum = 0.0; - start_time = omp_get_wtime(); -#pragma omp parallel private(i) -{ - int id = omp_get_thread_num(); - int numthreads = omp_get_num_threads(); - double x; - - double partial_sum = 0; - -#pragma omp single - printf(" num_threads = %d",numthreads); - - for (i=id;i< num_steps; i+=numthreads){ - x = (i+0.5)*step; - partial_sum += + 4.0/(1.0+x*x); - } -#pragma omp critical - full_sum += partial_sum; -} - - pi = step * full_sum; - run_time = omp_get_wtime() - start_time; - printf("\n pi is %f in %f seconds %d threds \n ",pi,run_time,j); -} -} - - - - - diff --git a/intro_lab/solutions/pi_spmd_final.f90 b/intro_lab/solutions/pi_spmd_final.f90 deleted file mode 100755 index 571a32d..0000000 --- a/intro_lab/solutions/pi_spmd_final.f90 +++ /dev/null @@ -1,66 +0,0 @@ -! NAME: PI SPMD final version without false sharing -! -! This program will numerically compute the integral of -! -! 4/(1+x*x) -! -! from 0 to 1. The value of this integral is pi -- which -! is great since it gives us an easy way to check the answer. -! -! The program was parallelized using OpenMP and an SPMD -! algorithm. - -program calc_pi - -use omp_lib - -implicit none - -integer, parameter :: MAX_THREADS = 4 - -integer(kind=8) :: num_steps = 100000000 -real(kind=8) step - -integer i, num_threads -real(kind=8) pi, full_sum, partial_sum -real(kind=8) start_time, run_time - -integer thread_id -real(kind=8) x - -step = 1.0D0 / num_steps - -do num_threads = 1, MAX_THREADS - - call OMP_SET_NUM_THREADS(num_threads) - start_time = OMP_GET_WTIME() - full_sum = 0.0D0 - - !$omp parallel private(thread_id, partial_sum, i, x) - - thread_id = OMP_GET_THREAD_NUM() + 1 - partial_sum = 0.0D0 - - !$omp single - print '(" num_threads = ", i0)', num_threads - !$omp end single - - do i = thread_id, num_steps, num_threads - x = (i-0.5D0)*step - partial_sum = partial_sum + 4.0D0/(1.0D0+x*x) - enddo - - !$omp critical - full_sum = full_sum + partial_sum - !$omp end critical - - !$omp end parallel - - pi = step * full_sum - run_time = OMP_GET_WTIME() - start_time - print '(" pi is ", f12.6, " in ", f12.6, " seconds and ", i0, " threads. Error = ", e15.6)', & - pi, run_time, num_threads, abs(3.14159265358979323846D0 - pi) - -enddo - -end program diff --git a/intro_lab/solutions/pi_spmd_simple.c b/intro_lab/solutions/pi_spmd_simple.c deleted file mode 100755 index ba0fe2c..0000000 --- a/intro_lab/solutions/pi_spmd_simple.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - -NAME: PI SPMD ... a simple version. - -This program will numerically compute the integral of - - 4/(1+x*x) - -from 0 to 1. The value of this integral is pi -- which -is great since it gives us an easy way to check the answer. - -The program was parallelized using OpenMP and an SPMD -algorithm. The following OpenMP specific lines were -added: - -(1) A line to include omp.h -- the include file that -contains OpenMP's function prototypes and constants. - -(2) A pragma that tells OpenMP to create a team of threads -with an integer variable i being created for each thread. - -(3) two function calls: one to get the thread ID (ranging -from 0 to one less than the number of threads), and the other -returning the total number of threads. - -(4) A cyclic distribution of the loop by changing loop control -expressions to run from the thread ID incremented by the number -of threads. Local sums accumlated into sum[id]. - -Note that this program will show low performance due to -false sharing. In particular, sum[id] is unique to each -thread, but adfacent values of this array share a cache line -causing cache thrashing as the program runs. - -History: Written by Tim Mattson, 11/99. - -*/ - -#include <stdio.h> -#include <omp.h> - -#define MAX_THREADS 4 - -static long num_steps = 100000000; -double step; -int main () -{ - int i,j; - double pi, full_sum = 0.0; - double start_time, run_time; - double sum[MAX_THREADS]; - - step = 1.0/(double) num_steps; - - - for (j=1;j<=MAX_THREADS ;j++) { - - omp_set_num_threads(j); - full_sum=0.0; - start_time = omp_get_wtime(); - - #pragma omp parallel - { - int i; - int id = omp_get_thread_num(); - int numthreads = omp_get_num_threads(); - double x; - - sum[id] = 0.0; - - if (id == 0) - printf(" num_threads = %d",numthreads); - - for (i=id;i< num_steps; i+=numthreads){ - x = (i+0.5)*step; - sum[id] = sum[id] + 4.0/(1.0+x*x); - } - } - - for(full_sum = 0.0, i=0;i<j;i++) - full_sum += sum[i]; - - pi = step * full_sum; - run_time = omp_get_wtime() - start_time; - printf("\n pi is %f in %f seconds %d thrds \n",pi,run_time,j); - } -} - - - - - diff --git a/intro_lab/solutions/pi_spmd_simple.f90 b/intro_lab/solutions/pi_spmd_simple.f90 deleted file mode 100755 index eb87ddf..0000000 --- a/intro_lab/solutions/pi_spmd_simple.f90 +++ /dev/null @@ -1,67 +0,0 @@ -! NAME: PI SPMD ... a simple version. -! -! This program will numerically compute the integral of -! -! 4/(1+x*x) -! -! from 0 to 1. The value of this integral is pi -- which -! is great since it gives us an easy way to check the answer. -! -! The program was parallelized using OpenMP and an SPMD -! algorithm. - -program calc_pi - -use omp_lib - -implicit none - -integer, parameter :: MAX_THREADS = 4 - -integer(kind=8) :: num_steps = 100000000 -real(kind=8) step - -integer i, num_threads -real(kind=8) pi, full_sum -real(kind=8) start_time, run_time -real(kind=8), dimension(1:MAX_THREADS) :: partial_sum - -integer thread_id -real(kind=8) x - -step = 1.0D0 / num_steps - -do num_threads = 1, MAX_THREADS - - call OMP_SET_NUM_THREADS(num_threads) - start_time = OMP_GET_WTIME() - - !$omp parallel private(thread_id, i, x) - - thread_id = OMP_GET_THREAD_NUM() + 1 - partial_sum(thread_id) = 0.0D0 - - if (thread_id == 1) then - print '(" num_threads = ", i0)', num_threads - endif - - do i = thread_id, num_steps, num_threads - x = (i-0.5D0)*step - partial_sum(thread_id) = partial_sum(thread_id) + 4.0D0/(1.0D0+x*x) - enddo - - !$omp end parallel - - full_sum = 0.0 - do thread_id = 1, num_threads - full_sum = full_sum + partial_sum(thread_id) - enddo - - pi = step * full_sum - run_time = OMP_GET_WTIME() - start_time - print '(" pi is ", f12.6, " in ", f12.6, " seconds and ", i0, " threads. Error = ", e15.6)', & - pi, run_time, num_threads, abs(3.14159265358979323846D0 - pi) - -enddo - -end program diff --git a/intro_lab/solutions/solutions.zip b/intro_lab/solutions/solutions.zip deleted file mode 100644 index 167225807dd6e5b5299f25763759f01bf22517c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7353 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 -- GitLab