From dbfa26936719275598235921d50456f9b8eb8387 Mon Sep 17 00:00:00 2001
From: Bruce Cowan <bruce@bcowan.me.uk>
Date: Mon, 24 Sep 2018 10:46:03 +0100
Subject: [PATCH] Add OpenMP and licence

Must have forgotten in the last commit, I'm stupid
---
 COPYING            |  0
 meson.build        |  4 ++-
 openmp/meson.build |  7 +++++
 openmp/pi.c        | 48 +++++++++++++++++++++++++++++++++
 openmp/simd.c      | 66 ++++++++++++++++++++++++++++++++++++++++++++++
 openmp/taylor.c    | 65 +++++++++++++++++++++++++++++++++++++++++++++
 openmp/threads.c   | 20 ++++++++++++++
 7 files changed, 209 insertions(+), 1 deletion(-)
 create mode 100644 COPYING
 create mode 100644 openmp/meson.build
 create mode 100644 openmp/pi.c
 create mode 100644 openmp/simd.c
 create mode 100644 openmp/taylor.c
 create mode 100644 openmp/threads.c

diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..e69de29
diff --git a/meson.build b/meson.build
index a994b3a..27dd1dc 100644
--- a/meson.build
+++ b/meson.build
@@ -6,6 +6,7 @@ libm = cc.find_library('m')
 utils = library('utils', 'utils.c')
 
 glib_dep = dependency('glib-2.0', version: '>= 2.16')
+openmp_dep = dependency('openmp')
 
 executable('add', 'add.c')
 executable('add2', 'add2.c', link_with: utils)
@@ -30,4 +31,5 @@ executable('write', 'write.c')
 subdir('array')
 subdir('hashtable')
 subdir('list')
-subdir('winter')
\ No newline at end of file
+subdir('openmp')
+subdir('winter')
diff --git a/openmp/meson.build b/openmp/meson.build
new file mode 100644
index 0000000..f154584
--- /dev/null
+++ b/openmp/meson.build
@@ -0,0 +1,7 @@
+cc = meson.get_compiler('c')
+libm = cc.find_library('m')
+
+executable('pi', 'pi.c', dependencies: [openmp_dep, libm])
+executable('simd', 'simd.c', dependencies: openmp_dep)
+executable('taylor', 'taylor.c', dependencies: openmp_dep)
+executable('threads', 'threads.c', dependencies: openmp_dep)
diff --git a/openmp/pi.c b/openmp/pi.c
new file mode 100644
index 0000000..6d2384f
--- /dev/null
+++ b/openmp/pi.c
@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <tgmath.h>
+#include <time.h>
+
+#include <omp.h>
+
+#define NUM_STEPS (10 * 1000 * 1000)
+
+static double
+random_coord (void)
+{
+    return 2 * ((double) rand () / RAND_MAX) - 1;
+}
+
+static double
+pi_func (size_t n)
+{
+    size_t inside = 0;
+
+    printf ("Started\n");
+
+    srand (time (NULL));
+
+    #pragma omp parallel for reduction(+:inside)
+    for (size_t i = 0; i < n; i++)
+    {
+        double x = random_coord ();
+        double y = random_coord ();
+        double r2 = pow (x, 2) + pow (y, 2);
+        if (r2 <= 1.0)
+            inside++;
+    }
+
+	return (4 * ((double) inside / n));
+}
+
+int 
+main (void)
+{
+    double start = omp_get_wtime ();
+    double pi = pi_func (NUM_STEPS);
+    double stop = omp_get_wtime ();
+
+    printf ("pi = %lf, took %.3f seconds\n", pi, stop-start);
+
+	return 0;
+}
diff --git a/openmp/simd.c b/openmp/simd.c
new file mode 100644
index 0000000..ae48262
--- /dev/null
+++ b/openmp/simd.c
@@ -0,0 +1,66 @@
+#include <stdio.h>
+
+static const int N = 32;
+
+#pragma omp declare simd uniform(fact)
+double
+add1 (double a,
+      double b,
+      double fact)
+{
+    return a + b + fact;
+}
+
+#pragma omp declare simd uniform(a,b,fact) linear(i:1)
+double
+add2 (double *a,
+      double *b,
+      int     i,
+      double  fact)
+{
+    return a[i] + b[i] + fact;
+}
+
+#pragma omp declare simd uniform(fact) linear(a,b:1)
+double
+add3 (double *a,
+      double *b,
+      double  fact)
+{
+    return *a + *b + fact;
+}
+
+void
+work (double *a,
+      double *b,
+      int     n)
+{
+    double tmp;
+
+    #pragma omp simd private(tmp)
+    for (int i = 0; i < n; i++)
+    {
+        tmp = add1 (a[i], b[i], 1.0);
+        a[i] = add2 (a, b, i, 1.0 + tmp);
+        a[i] = add3 (&a[i], &b[i], 1.0);
+    }
+}
+
+int
+main (void)
+{
+    double a[N], b[N];
+
+    for (int i = 0; i < N; i++)
+    {
+        a[i] = i;
+        b[i] = N - i;
+    }
+
+    work (a, b, N);
+
+    for (int i = 0; i < N; i++)
+        printf ("%d %f\n", i, a[i]);
+
+    return 0;
+}
diff --git a/openmp/taylor.c b/openmp/taylor.c
new file mode 100644
index 0000000..28df1dd
--- /dev/null
+++ b/openmp/taylor.c
@@ -0,0 +1,65 @@
+#include <stdio.h>
+
+#include <omp.h>
+
+static const size_t NUM_STEPS = 1e9;
+
+static double
+e_func (size_t n)
+{
+	double e = 1;
+	double factorial = 1;
+
+	printf ("e started\n");
+
+	#pragma omp parallel for shared(factorial) reduction(+:e)
+	for (size_t i = 1; i < n; i++)
+	{
+		factorial *= i;
+		e += 1.0 / factorial;
+	}
+
+	return e;
+}
+
+static double
+pi_func (size_t n)
+{
+	double pi = 0;
+
+	printf ("pi started\n");
+
+	for (size_t i = 0; i < n; i++)
+	{
+		pi += 1.0 / (i * 4.0 + 1.0);
+		pi -= 1.0 / (i * 4.0 + 3.0);
+	}
+
+	pi *= 4.0;
+
+	return pi;
+}
+
+int 
+main (void)
+{
+	#pragma omp parallel sections
+	{
+		#pragma omp section
+		{
+			double start = omp_get_wtime ();
+			double e = e_func (NUM_STEPS);
+			double stop = omp_get_wtime ();
+			printf ("e = %lf, took %.3f seconds\n", e, stop-start);
+		}
+		#pragma omp section
+		{
+			double start = omp_get_wtime ();
+			double pi = pi_func (NUM_STEPS);
+			double stop = omp_get_wtime ();
+			printf ("pi = %lf, took %.3f seconds\n", pi, stop-start);
+		}
+	}
+
+	return 0;
+}
diff --git a/openmp/threads.c b/openmp/threads.c
new file mode 100644
index 0000000..7963ce7
--- /dev/null
+++ b/openmp/threads.c
@@ -0,0 +1,20 @@
+#include <stdio.h>
+
+#include <omp.h>
+
+int
+main (void)
+{
+    #pragma omp parallel
+    {
+        int tid = omp_get_thread_num ();
+        printf ("Hello world from thread %d\n", tid);
+
+        #pragma omp master
+        {
+            int nthreads = omp_get_max_threads ();
+            int procs = omp_get_num_procs ();
+            printf ("%d threads and %d processors\n", nthreads, procs);
+        }
+    }
+}
-- 
GitLab