Original Repository by Matthew Maccelari, Warwick Brown & Liberty Kapungu
This repository provides in-place transposition of square matrices using shared‐memory parallelism in both C (OpenMP & PThreads) and Rust. It also includes automated build/run scripts and benchmarking infrastructure.
Before running any of the shell scripts make sure they are executable using:
chmod +x build_all.sh run_all.shSimply run:
./build_all.shThis will:
- Compile all OpenMP C programs (Naïve, Diagonal, Block)
- Compile all PThread C programs (Diagonal, Block)
- Build the Rust binaries in
src/RustBlock/,src/RustDiagonal/, (andsrc/RustNaive/if present) with--release
Once everything is built, run:
./run_all.shThis will:
- Execute each C and Rust implementation on matrix sizes 128, 1024, 2048, 4096
- Append execution times to the corresponding
.csvfiles inBenchmarks/ - (Optionally) Dump full matrix outputs to
Results/for inspection
This script above will also run the verification tests to confirm algorithmic correctness. Each test will print the original and transposed 4×4 matrix and report whether it matches the expected result.
# from the repo root
gcc -fopenmp -lgomp src/C/OpenMPNaiveThreaded.c -o OpenMPNaiveThreaded
gcc -fopenmp -lgomp src/C/OpenMPDiagonalThreaded.c -o OpenMPDiagonalThreaded
gcc -fopenmp -lgomp src/C/OpenMPBlockOrientated.c -o OpenMPBlockOrientated./OpenMPNaiveThreaded
./OpenMPDiagonalThreaded
./OpenMPBlockOrientatedEach C binary will transpose matrices of sizes 128, 1024, 2048, and 4096 (with
bs = 64in the block version) and append timing data to its corresponding CSV underBenchmarks/.
gcc -pthread src/C/PThreadDiagonalThreaded.c -o PThreadDiagonalThreaded
gcc -pthread src/C/PThreadBlockOrientated.c -o PThreadBlockOrientated./PThreadDiagonalThreaded
./PThreadBlockOrientatedEach C binary will transpose matrices of sizes 128, 1024, 2048, and 4096 (with
bs = 64in the block version) and append timing data to its corresponding CSV underBenchmarks/.
Each Rust variant lives in its own crate directory under src/. You can build & run in one step.
cd src/RustNaive
cargo run --releasecd src/RustDiagonal
cargo run --releasecd src/RustBlock
cargo run --releaseEach Rust binary will transpose matrices of sizes 128, 1024, 2048, and 4096 (with
bs = 64in the block version) and append timing data to its corresponding CSV underBenchmarks/.
The lab implements multiple algorithms for in-place transposition of a square matrix:
-
OpenMP Implementations:
-
Naïve-Threaded Algorithm:
Inserts#pragma omp parallel foraround the standard nested swap loops so that all element swaps above the diagonal are done in parallel. -
Diagonal-Threaded Algorithm:
Spawns one OpenMP task per diagonal position; each task swaps its corresponding off-diagonal element pairs(i, j)and(j, i)forj > iin parallel. -
Block-Oriented-Threaded Algorithm:
Chunks theN×Nmatrix intobs×bsblocks and uses OpenMP tasks to (1) transpose each diagonal block internally and (2) swap symmetric off-diagonal block pairs, yielding two levels of concurrency.
-
-
PThread Implementations:
-
Diagonal-Threaded Algorithm:
Creates one POSIX thread per diagonal index; each thread handles swapping off-diagonal element pairs in its row/column. -
Block-Oriented-Threaded Algorithm:
Divides the matrix intobs×bstiles and spawns threads to (1) transpose each diagonal tile and (2) swap entire off-diagonal tile pairs using the PThread API.
-
-
Rust Implementations:
-
Naïve-Threaded in Rust:
UsesNUM_THREADSworker threads. Each thread takes everyNUM_THREADS-th row (i = tid, tid+NUM_THREADS, …) and atomically swaps(i,j)↔(j,i)usingArc<Vec<AtomicI32>>withAcquire/Releaseordering. -
Diagonal-Threaded in Rust:
Mirrors the PThread/OpenMP diagonal approach by either spawning onestd::threadper diagonal index or using a small worker pool; each thread performs atomic loads/stores to swap off-diagonal element pairs. -
Block-Oriented-Threaded in Rust:
Divides theN×Nmatrix intobs×bsblocks (defaultbs = 64). For each block index pair(bi, bj), it spawns astd::threadthat:- Clones the shared
Arc<Vec<AtomicI32>>buffer. - If
bi == bj, swaps only the upper triangle within that block; otherwise swaps corresponding elements between the two blocks. - Uses atomic
load(Ordering::Acquire)andstore(Ordering::Release)for each element to ensure safe in-place updates.
All thread handles are collected and joined before proceeding, mirroring the manual per-block threading of the C implementations.
- Clones the shared
-
For correctness validation, the Testing/ folder provides C and Rust test programs that transpose a fixed 4×4 matrix (values 1…16) and compare the result against the expected output.
project-root/
├── Benchmarks/ # CSV timing results & spreadsheet
│ ├── OpenMPNaiveThreaded.csv
│ ├── OpenMPDiagonalThreaded.csv
│ ├── OpenMPBlockOrientated.csv
│ ├── PThreadDiagonalThreaded.csv
│ ├── PThreadBlockOrientated.csv
│ ├── RustBlockOrientated.csv
│ ├── RustDiagonalThreaded.csv
│ ├── RustNaiveThreaded.csv
│ ├── combined_benchmarks.csv
│ └── merge_benchmarks.py
│
├── src/ # All source code
│ ├── Results/ # Detailed matrix dumps (optional)
│ │ └── \*.txt
│ ├── OpenMPNaiveThreaded.c
│ ├── OpenMPDiagonalThreaded.c
│ ├── OpenMPBlockOrientated.c
│ ├── PThreadDiagonalThreaded.c
│ ├── PThreadBlockOrientated.c
│ ├── RustBlock/ # Block‐oriented transpose
│ │ └── src/main.rs
│ ├── RustDiagonal/ # Diagonal‐threaded transpose
│ │ └── src/main.rs
│ └── RustNaive/ # Naïve single‐threaded baseline
│ └── src/main.rs
│
├── Testing/ # Fixed 4×4 test matrices for correctness
│ ├── OpenMPBlockOrientatedTest.c
│ ├── OpenMPDiagonalThreadedTest.c
│ ├── OpenMPNaiveThreadedTest.c
│ ├── PThreadBlockOrientatedTest.c
│ ├── PThreadsDiagonalThreadedTest.c
│ └── RustAllTests/ # All Rust tests
│ └── src/lib.rs
│
├── build_all.sh # Compile ALL C & Rust implementations
├── run_all.sh # Execute ALL benchmarks & save results
└── README.md # This file
All timing results are collected under Benchmarks/:
- CSV files (
*.csv) list each run’s timings, as well as a combined file with all results.
The benchmarks compare execution times with different matrix sizes (e.g., 128, 1024, 2048, 4096) for both C OpenMP, C PThread, and Rust implementations.
This lab demonstrates:
- Naïve, Diagonal, and Block-oriented in-place transpose algorithms.
- Shared-memory parallelism in OpenMP, PThreads, and Rust (
std::thread). - Automated build & run workflows via
build_all.shandrun_all.sh. - Correctness validation on a fixed 4×4 test matrix.
- Performance benchmarking across multiple matrix sizes.