/*
 * 02-parallel-sum.c  —  Data parallelism done RIGHT (with reduction)
 * Session 03 · 2311CSC501J Parallel Processing
 *
 * WHAT THIS SHOWS
 *   We sum a big array across many threads. Splitting the loop is easy —
 *   #pragma omp parallel for hands each thread a slice of the iterations.
 *   The tricky part is combining the partial results without a data race.
 *   The reduction(+:sum) clause does exactly that: each thread keeps its OWN
 *   private running total, and OpenMP adds those private totals together
 *   safely at the end. No race, correct answer, every single run.
 *
 *   Compare this with 03-race-condition.c, which drops the reduction clause
 *   and gets a WRONG, unstable answer. Run both and see the difference.
 *
 * HOW TO COMPILE & RUN
 *       gcc -fopenmp 02-parallel-sum.c -o sum
 *       ./sum
 *       OMP_NUM_THREADS=8 ./sum
 *
 *   macOS (Apple clang): clang -Xpreprocessor -fopenmp -lomp 02-parallel-sum.c -o sum
 *   Or paste into OnlineGDB / godbolt.org (add -fopenmp) — no install needed.
 */

#include <stdio.h>
#include <omp.h>

#define N 10000000    /* 10 million elements */

int main(void) {
    static int a[N];              /* static so this large array lives in BSS, not the stack */
    long sum = 0;

    /* Fill the array: a[i] = 1, so the correct total is exactly N. */
    #pragma omp parallel for
    for (int i = 0; i < N; i++) {
        a[i] = 1;
    }

    /* Sum it in parallel. reduction(+:sum) makes this correct AND fast. */
    #pragma omp parallel for reduction(+:sum)
    for (int i = 0; i < N; i++) {
        sum += a[i];
    }

    int threads = 0;
    #pragma omp parallel
    {
        #pragma omp single
        threads = omp_get_num_threads();
    }

    printf("Summed %d elements across %d threads\n", N, threads);
    printf("Result   = %ld\n", sum);
    printf("Expected = %d\n", N);
    printf("%s\n", (sum == (long)N) ? "CORRECT — reduction handled the combine safely."
                                    : "WRONG — that should not happen with reduction!");
    return 0;
}
