# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     name: python3
# ---

# + [markdown] id="view-in-github" colab_type="text"
# <a href="https://colab.research.google.com/github/pcsilcan/pcd/blob/master/20202/pcd_20202_0701_openmp_ftw.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>

# + [markdown] id="6PHJhP2PSgxc"
# # OpenMP

# + id="PCwQPTVwQu96" outputId="da1c1efb-4b1a-4578-d66e-70297be290be" colab={"base_uri": "https://localhost:8080/", "height": 34}
# %%writefile 1.cpp
#include <stdio.h>
#include <omp.h>

int main() {
#pragma omp parallel
{
    int id = omp_get_thread_num();
    printf("Hello(%d), ", id);
    printf("World(%d)!\n", id);
}

    return 0;
}

# + id="-8akyMBkTCgJ" outputId="96f210d8-c5e0-41e6-d9e7-186b216ef35b" colab={"base_uri": "https://localhost:8080/", "height": 50}
# !g++ -std=c++17 -fopenmp 1.cpp && ./a.out

# + [markdown] id="hYJ7CyfMa-MN"
# # Calc $\pi$
#
# ## Serial

# + id="_OFOSMWITNN1" outputId="ceee1066-cf2f-4bcd-f98c-8fde446b6fce" colab={"base_uri": "https://localhost:8080/", "height": 34}
# %%writefile pi0.cpp
#include <stdio.h>
#include <omp.h>

double calcPi(int num_steps) {
    double step;
    double x, pi, sum = .0;
    step = 1. / (double)num_steps;
    for (int i = 0; i < num_steps; ++i) {
        x = (i + .5) * step;
        sum += 4. / (1 + x*x);
    }
    pi = sum / num_steps;
    return pi;
}

int main() {
    double pi;
    double ti = omp_get_wtime();
    pi = calcPi(100000);
    double et = omp_get_wtime() - ti;
    printf("Pi = %lf time = %lfs\n", pi, et);
    return 0;
}

# + [markdown] id="bV2L9Q-LhC5p"
# ## Parallel v1

# + id="EZI8dBlTcYQf" outputId="a8569089-b80b-4bb0-ec9f-4013b3280d32" colab={"base_uri": "https://localhost:8080/", "height": 34}
# %%writefile pi1.cpp
#include <stdio.h>
#include <omp.h>

#define NUM_THREADS 2

double calcPi(int num_steps) {
    double step;
    int nthreads;
    double pi, sum[NUM_THREADS];
    step = 1. / (double)num_steps;
    omp_set_num_threads(NUM_THREADS);
#pragma omp parallel
{
    double  x;
    int     nthrds = omp_get_num_threads();
    int     id = omp_get_thread_num();
    if (id == 0) nthreads = nthrds;
    sum[id] = 0.0;
    for (int i = id; i < num_steps; i+=nthrds) {
        x = (i + .5) * step;
        sum[id] += 4. / (1 + x*x);
    }
}
    for (int i = 0; i < nthreads; ++i) {
        pi += sum[i];
    }
    return pi / num_steps;
}

int main() {
    double pi;
    double ti = omp_get_wtime();
    pi = calcPi(100000);
    double et = omp_get_wtime() - ti;
    printf("Pi = %lf time = %lfs\n", pi, et);
    return 0;
}

# + [markdown] id="ICiXcVfiphG_"
# ## Parallel v2

# + id="GC6EHt3InmFr" outputId="6cb80086-1340-4c0f-de9b-483da0fda2ff" colab={"base_uri": "https://localhost:8080/", "height": 34}
# %%writefile pi2.cpp
#include <stdio.h>
#include <omp.h>

#define PAD 16
#define NUM_THREADS 2

double calcPi(int num_steps) {
    double step;
    int nthreads;
    double pi, sum[NUM_THREADS][PAD];
    step = 1. / (double)num_steps;
    omp_set_num_threads(NUM_THREADS);
#pragma omp parallel
{
    double  x;
    int     nthrds = omp_get_num_threads();
    int     id = omp_get_thread_num();
    if (id == 0) nthreads = nthrds;
    sum[id][0] = 0.0;
    for (int i = id; i < num_steps; i+=nthrds) {
        x = (i + .5) * step;
        sum[id][0] += 4. / (1 + x*x);
    }
}
    for (int i = 0; i < nthreads; ++i) {
        pi += sum[i][0];
    }
    return pi / num_steps;
}

int main() {
    double pi;
    double ti = omp_get_wtime();
    pi = calcPi(100000);
    double et = omp_get_wtime() - ti;
    printf("Pi = %lf time = %lfs\n", pi, et);
    return 0;
}

# + [markdown] id="maASxiLQpuwn"
# ## Parallel v3

# + id="m1Hb3H-gpwtv" outputId="8cb70ed2-c6f0-4102-f0ab-bdc1424c4577" colab={"base_uri": "https://localhost:8080/", "height": 34}
# %%writefile pi3.cpp
#include <stdio.h>
#include <omp.h>

#define PAD 16
#define NUM_THREADS 2

double calcPi(int num_steps) {
    double step;
    int nthreads;
    double pi;
    step = 1. / (double)num_steps;
    omp_set_num_threads(NUM_THREADS);
#pragma omp parallel
{
    double  x;
    int     nthrds = omp_get_num_threads();
    int     id = omp_get_thread_num();
    double  sum = 0.0;
    if (id == 0) nthreads = nthrds;
    for (int i = id; i < num_steps; i+=nthrds) {
        x = (i + .5) * step;
        sum += 4. / (1 + x*x);
    }
#pragma omp critical
    pi += sum;
}

    return pi / num_steps;
}

int main() {
    double pi;
    double ti = omp_get_wtime();
    pi = calcPi(100000);
    double et = omp_get_wtime() - ti;
    printf("Pi = %lf time = %lfs\n", pi, et);
    return 0;
}

# + [markdown] id="_L4vWgMatfse"
#

# + id="ztVoRH71thOa" outputId="500c2ce5-015d-4b26-a61c-5e5f57330d78" colab={"base_uri": "https://localhost:8080/", "height": 34}
# %%writefile pi4.cpp
#include <stdio.h>
#include <omp.h>

double calcPi(int num_steps) {
    double step;
    double x, pi, sum = .0;
    step = 1. / (double)num_steps;
#pragma omp parallel for private(x) reduction(+:sum)
    for (int i = 0; i < num_steps; ++i) {
        x = (i + .5) * step;
        sum += 4. / (1 + x*x);
    }
    pi = sum / num_steps;
    return pi;
}

int main() {
    double pi;
    double ti = omp_get_wtime();
    pi = calcPi(100000);
    double et = omp_get_wtime() - ti;
    printf("Pi = %lf time = %lfs\n", pi, et);
    return 0;
}

# + id="wybQsAOXcRDG" outputId="32663efe-28fd-4eee-c1aa-e6b6aec478b8" colab={"base_uri": "https://localhost:8080/", "height": 101} magic_args="bash" language="script"
# g++ -std=c++17 -fopenmp pi0.cpp -o pi0
# g++ -std=c++17 -fopenmp pi1.cpp -o pi1
# g++ -std=c++17 -fopenmp pi2.cpp -o pi2
# g++ -std=c++17 -fopenmp pi3.cpp -o pi3
# g++ -std=c++17 -fopenmp pi4.cpp -o pi4
#
# ./pi0
# ./pi1
# ./pi2
# ./pi3
# ./pi4

# + id="7OitZN43hli4"


StarcoderdataJupyterScriptsDedupFiltered