init
This commit is contained in:
commit
a628d873c5
19
lab1/Makefile
Normal file
19
lab1/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
# Makefile for building mpi_hello_world from mpi_hello_world.c
|
||||
MPICC ?= mpicc
|
||||
MPIRUN ?= mpirun
|
||||
CFLAGS ?= -O2 -Wall
|
||||
TARGET := $(basename $(SRC))
|
||||
SRC := mpi_hello_world.c serial_pi.c mpi_pi.c
|
||||
|
||||
.PHONY: all clean run
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(SRC)
|
||||
$(MPICC) $(CFLAGS) -o $@ $<
|
||||
|
||||
run: $(TARGET)
|
||||
$(MPIRUN) -np 4 ./$@
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET)
|
||||
97
lab1/do_lab.sh
Normal file
97
lab1/do_lab.sh
Normal file
@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# cd to the directory where this script lives
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
echo "Running make..."
|
||||
make
|
||||
|
||||
# detect MPI launcher
|
||||
if command -v mpirun >/dev/null 2>&1; then
|
||||
MPI_LAUNCHER=mpirun
|
||||
MPI_FLAG="-np"
|
||||
elif command -v mpiexec >/dev/null 2>&1; then
|
||||
MPI_LAUNCHER=mpiexec
|
||||
MPI_FLAG="-n"
|
||||
else
|
||||
echo "Error: neither mpirun nor mpiexec found in PATH." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# detect number of processes (fallback to 4)
|
||||
if command -v nproc >/dev/null 2>&1; then
|
||||
NP=$(nproc)
|
||||
elif [ -n "${NUMBER_OF_PROCESSORS-}" ]; then
|
||||
NP=$NUMBER_OF_PROCESSORS
|
||||
else
|
||||
NP=4
|
||||
fi
|
||||
|
||||
echo "Using $MPI_LAUNCHER $MPI_FLAG $NP"
|
||||
|
||||
# helper to measure elapsed "real" time (seconds) while also showing program output
|
||||
measure_time() {
|
||||
local label="$1"; shift
|
||||
local -a cmd=("$@")
|
||||
echo "---- Running: $label ----"
|
||||
echo "Command: ${cmd[*]}"
|
||||
|
||||
local outfile timefile
|
||||
outfile=$(mktemp)
|
||||
timefile=$(mktemp)
|
||||
|
||||
if command -v /usr/bin/time >/dev/null 2>&1; then
|
||||
# /usr/bin/time prints real time with %e (seconds) into timefile
|
||||
/usr/bin/time -f "%e" -o "$timefile" "${cmd[@]}" 2>&1 | tee "$outfile"
|
||||
elapsed=$(<"$timefile")
|
||||
else
|
||||
# bash builtin time: capture stderr (which receives the timing) and stdout separately
|
||||
TIMEFORMAT='%R'
|
||||
{ time "${cmd[@]}" 1> "$outfile"; } 2> "$timefile"
|
||||
elapsed=$(<"$timefile")
|
||||
# also print program output
|
||||
cat "$outfile"
|
||||
fi
|
||||
|
||||
rm -f "$outfile" "$timefile"
|
||||
# normalize elapsed to a number (strip spaces)
|
||||
echo "${elapsed//[[:space:]]/}"
|
||||
}
|
||||
|
||||
# ensure executables exist
|
||||
for exe in mpi_hello_world mpi_pi serial_pi; do
|
||||
if [ ! -x "./$exe" ]; then
|
||||
echo "Error: executable ./$exe not found or not executable. Did make build it?" >&2
|
||||
exit 3
|
||||
fi
|
||||
done
|
||||
|
||||
# run mpi_hello_world (show output, don't measure for comparison)
|
||||
echo "==> Executing mpi_hello_world"
|
||||
"$MPI_LAUNCHER" "$MPI_FLAG" "$NP" ./mpi_hello_world
|
||||
|
||||
# measure mpi_pi
|
||||
mpi_elapsed=$(measure_time "mpi_pi" "$MPI_LAUNCHER" "$MPI_FLAG" "$NP" ./mpi_pi)
|
||||
|
||||
# measure serial_pi
|
||||
serial_elapsed=$(measure_time "serial_pi" ./serial_pi)
|
||||
|
||||
# compute comparison
|
||||
# protect against zero
|
||||
if awk "BEGIN{exit($mpi_elapsed <= 0)}"; then
|
||||
echo "Error: measured mpi_pi time is zero or negative." >&2
|
||||
exit 4
|
||||
fi
|
||||
|
||||
speedup=$(awk -v s="$serial_elapsed" -v m="$mpi_elapsed" 'BEGIN{ if(m==0){print "inf"; exit} printf "%.3f", s/m }')
|
||||
diff=$(awk -v s="$serial_elapsed" -v m="$mpi_elapsed" 'BEGIN{printf "%.3f", s-m }')
|
||||
|
||||
echo
|
||||
echo "Summary:"
|
||||
echo " mpi_pi time (s): $mpi_elapsed"
|
||||
echo " serial_pi time (s): $serial_elapsed"
|
||||
echo " Difference (serial - mpi) (s): $diff"
|
||||
echo " Speedup (serial / mpi): $speedup x"
|
||||
|
||||
exit 0
|
||||
29
lab1/mpi_hello_world.c
Normal file
29
lab1/mpi_hello_world.c
Normal file
@ -0,0 +1,29 @@
|
||||
#include <mpi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// Initialize the MPI environment. The two arguments to MPI Init are not
|
||||
// currently used by MPI implementations, but are there in case future
|
||||
// implementations might need the arguments.
|
||||
MPI_Init(NULL, NULL);
|
||||
|
||||
// Get the number of processes
|
||||
int world_size;
|
||||
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
|
||||
|
||||
// Get the rank of the process
|
||||
int world_rank;
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
|
||||
|
||||
// Get the name of the processor
|
||||
char processor_name[MPI_MAX_PROCESSOR_NAME];
|
||||
int name_len;
|
||||
|
||||
MPI_Get_processor_name(processor_name, &name_len);
|
||||
|
||||
// Print off a hello world message
|
||||
printf("Hello world from processor %s, rank %d out of %d processors\n", processor_name, world_rank, world_size);
|
||||
|
||||
// Finalize the MPI environment. No more MPI calls can be made after this
|
||||
MPI_Finalize();
|
||||
}
|
||||
54
lab1/mpi_pi.c
Normal file
54
lab1/mpi_pi.c
Normal file
@ -0,0 +1,54 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <mpi.h>
|
||||
|
||||
/* We define pi here so we can check and see how accurate our computation is. */
|
||||
#define PI 3.141592653589793238462643
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
MPI_Init(&argc, &argv);
|
||||
|
||||
int processes, pe;
|
||||
|
||||
MPI_Comm_size(MPI_COMM_WORLD, &processes);
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &pe);
|
||||
|
||||
/* Let's prompt for the number of intervals. We'll broadcast whatever
|
||||
* process 0 reads to the other processes. We could use command line
|
||||
* arguments instead, but then there'd be no reason to broadcast! */
|
||||
|
||||
int intervals;
|
||||
if (pe == 0) {
|
||||
printf("Number of intervals: ");
|
||||
fflush(stdout);
|
||||
scanf("%d", &intervals);
|
||||
}
|
||||
|
||||
double time1 = MPI_Wtime();
|
||||
|
||||
MPI_Bcast(&intervals, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
||||
|
||||
int count = intervals / processes;
|
||||
int start = count * pe;
|
||||
int end = count * pe + count;
|
||||
int i;
|
||||
double subtotal, total = 0;
|
||||
|
||||
for (i = start; i < end; ++i) {
|
||||
subtotal += pow(-1, i) / (2 * i + 1);
|
||||
}
|
||||
|
||||
MPI_Reduce(&subtotal, &total, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
|
||||
|
||||
double time2 = MPI_Wtime();
|
||||
|
||||
if (pe == 0) {
|
||||
total = total * 4;
|
||||
printf("Result: %.10lf\n", total);
|
||||
|
||||
printf("Accuracy: %.10lf\n", PI - total);
|
||||
printf("Time: %.10lf\n", time2 - time1);
|
||||
}
|
||||
|
||||
MPI_Finalize();
|
||||
}
|
||||
35
lab1/serial_pi.c
Normal file
35
lab1/serial_pi.c
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* File: pi-c.c
|
||||
* Purpose: Estimates pi using the Leibniz formula (in C).
|
||||
* Compile: gcc -o pi-c pi-c.c -lm
|
||||
* Run: ./pi-c
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
/* We define pi here so we can check and see how accurate our computation is. */
|
||||
#define PI 3.141592653589793238462643
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int intervals;
|
||||
printf("Number of intervals: ");
|
||||
fflush(stdout);
|
||||
scanf("%d", &intervals);
|
||||
|
||||
clock_t time1 = clock();
|
||||
|
||||
int i;
|
||||
double sum, total = 0;
|
||||
for (i = 0; i < intervals; ++i) {
|
||||
total += pow(-1, i) / (2 * i + 1);
|
||||
}
|
||||
|
||||
clock_t time2 = clock();
|
||||
|
||||
total = total * 4;
|
||||
printf("Result: %.10lf\n", total);
|
||||
printf("Accuracy: %.10lf\n", PI - total);
|
||||
printf("Time:
|
||||
%.10lf\n", (double)(time2 - time1)/CLOCKS_PER_SEC);
|
||||
}
|
||||
16
lab2/pthread/Makefile
Normal file
16
lab2/pthread/Makefile
Normal file
@ -0,0 +1,16 @@
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -Wextra -O2
|
||||
LDLIBS = -lpthread
|
||||
|
||||
SRCS := $(wildcard *.c)
|
||||
BINS := $(SRCS:.c=)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(BINS)
|
||||
|
||||
%: %.c
|
||||
$(CC) $(CFLAGS) -o $@ $< $(LDLIBS)
|
||||
|
||||
clean:
|
||||
-rm -f $(BINS) *.o
|
||||
73
lab2/pthread/count_words_par.c
Normal file
73
lab2/pthread/count_words_par.c
Normal file
@ -0,0 +1,73 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
FILE *fd;
|
||||
int TotalEvenWords = 0, TotalOddWords = 0, TotalWords = 0;
|
||||
int GetNextLine(FILE *f, char *Line)
|
||||
{
|
||||
if (fgets(Line, 132, f)==NULL) if (feof(f))return EOF; else return 1;
|
||||
}
|
||||
|
||||
int GetWordAndLetterCount(char *Line)
|
||||
{
|
||||
int Word_Count = 0, Letter_Count = 0;
|
||||
for (int i=0;i<132;i++)
|
||||
{
|
||||
if ((Line[i]!=' ')&&(Line[i]!=0)&&(Line[i]!='\n')) Letter_Count++;
|
||||
else {
|
||||
if (Letter_Count % 2) {
|
||||
TotalOddWords++;
|
||||
Word_Count++;
|
||||
Letter_Count = 0;
|
||||
}
|
||||
else {
|
||||
TotalEvenWords++;
|
||||
Word_Count++;
|
||||
Letter_Count = 0;
|
||||
}
|
||||
if (Line[i]==0) break;
|
||||
}
|
||||
}
|
||||
return (Word_Count);
|
||||
// encode two return values
|
||||
}
|
||||
|
||||
int CountWords()
|
||||
{
|
||||
bool bDone = false;
|
||||
char inLine[132];
|
||||
while (!bDone)
|
||||
{
|
||||
bDone = (GetNextLine(fd, inLine) == EOF);
|
||||
if (!bDone){
|
||||
TotalWords += GetWordAndLetterCount(inLine) ;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
fd = fopen("./InFile1.txt", "r"); // Open file for read
|
||||
struct timeval TimeStampStart, TimeStampStop;
|
||||
double ExeTime;
|
||||
|
||||
gettimeofday(&TimeStampStart, NULL);
|
||||
|
||||
CountWords();
|
||||
|
||||
gettimeofday(&TimeStampStop, NULL);
|
||||
|
||||
ExeTime = (double)(TimeStampStop.tv_sec - TimeStampStart.tv_sec) +
|
||||
(double)(TimeStampStop.tv_usec - TimeStampStart.tv_usec) * 1e-6;
|
||||
|
||||
fclose(fd);
|
||||
|
||||
printf("Total Words = %8d\n", TotalWords);
|
||||
printf("Total Even Words = %7d\nTotal Odd Words = %7d\n", TotalEvenWords, TotalOddWords);
|
||||
printf("The time to count word was %f seconds\n", (ExeTime));
|
||||
return 0;
|
||||
}
|
||||
73
lab2/pthread/count_words_ser.c
Normal file
73
lab2/pthread/count_words_ser.c
Normal file
@ -0,0 +1,73 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
FILE *fd;
|
||||
int TotalEvenWords = 0, TotalOddWords = 0, TotalWords = 0;
|
||||
int GetNextLine(FILE *f, char *Line)
|
||||
{
|
||||
if (fgets(Line, 132, f)==NULL) if (feof(f))return EOF; else return 1;
|
||||
}
|
||||
|
||||
int GetWordAndLetterCount(char *Line)
|
||||
{
|
||||
int Word_Count = 0, Letter_Count = 0;
|
||||
for (int i=0;i<132;i++)
|
||||
{
|
||||
if ((Line[i]!=' ')&&(Line[i]!=0)&&(Line[i]!='\n')) Letter_Count++;
|
||||
else {
|
||||
if (Letter_Count % 2) {
|
||||
TotalOddWords++;
|
||||
Word_Count++;
|
||||
Letter_Count = 0;
|
||||
}
|
||||
else {
|
||||
TotalEvenWords++;
|
||||
Word_Count++;
|
||||
Letter_Count = 0;
|
||||
}
|
||||
if (Line[i]==0) break;
|
||||
}
|
||||
}
|
||||
return (Word_Count);
|
||||
// encode two return values
|
||||
}
|
||||
|
||||
int CountWords()
|
||||
{
|
||||
bool bDone = false;
|
||||
char inLine[132];
|
||||
while (!bDone)
|
||||
{
|
||||
bDone = (GetNextLine(fd, inLine) == EOF);
|
||||
if (!bDone){
|
||||
TotalWords += GetWordAndLetterCount(inLine) ;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
fd = fopen("./InFile1.txt", "r"); // Open file for read
|
||||
struct timeval TimeStampStart, TimeStampStop;
|
||||
double ExeTime;
|
||||
|
||||
gettimeofday(&TimeStampStart, NULL);
|
||||
|
||||
CountWords();
|
||||
|
||||
gettimeofday(&TimeStampStop, NULL);
|
||||
|
||||
ExeTime = (double)(TimeStampStop.tv_sec - TimeStampStart.tv_sec) +
|
||||
(double)(TimeStampStop.tv_usec - TimeStampStart.tv_usec) * 1e-6;
|
||||
|
||||
fclose(fd);
|
||||
|
||||
printf("Total Words = %8d\n", TotalWords);
|
||||
printf("Total Even Words = %7d\nTotal Odd Words = %7d\n", TotalEvenWords, TotalOddWords);
|
||||
printf("The time to count word was %f seconds\n", (ExeTime));
|
||||
return 0;
|
||||
}
|
||||
30
lab2/pthread/pi.c
Normal file
30
lab2/pthread/pi.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
long long num_steps = 1000000000;
|
||||
double step;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
struct timeval TimeStampStart, TimeStampStop;
|
||||
double ExeTime;
|
||||
double x, pi, sum=0.0;
|
||||
int i;
|
||||
step = 1./(double)num_steps;
|
||||
|
||||
gettimeofday(&TimeStampStart, NULL);
|
||||
|
||||
for (i=0; i<num_steps; i++)
|
||||
{
|
||||
x = (i + .5)*step;
|
||||
sum = sum + 4.0/(1.+ x*x);
|
||||
}
|
||||
pi = sum*step;
|
||||
|
||||
gettimeofday(&TimeStampStop, NULL);
|
||||
ExeTime = (double)(TimeStampStop.tv_sec - TimeStampStart.tv_sec) + (double)(TimeStampStop.tv_usec - TimeStampStart.tv_usec) * 1e-6;
|
||||
|
||||
printf("The value of PI is %15.12f\n",pi);
|
||||
printf("The time to calculate PI was %f seconds\n", (ExeTime));
|
||||
|
||||
return 0;
|
||||
}
|
||||
36
lab2/pthread/pthread_hello.c
Normal file
36
lab2/pthread/pthread_hello.c
Normal file
@ -0,0 +1,36 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
const int NumThreads = 16;
|
||||
|
||||
static void* HelloFunc(void* pArg)
|
||||
{
|
||||
printf("Hello Thread %d !\n", *((int*)pArg));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int Num[NumThreads];
|
||||
|
||||
pthread_t ThreadIDs[NumThreads];
|
||||
pthread_attr_t attr[NumThreads];
|
||||
|
||||
for (int i = 0; i < NumThreads; i++) {
|
||||
Num[i] = i;
|
||||
pthread_attr_init(&attr[i]);
|
||||
pthread_attr_setdetachstate(&attr[i], PTHREAD_CREATE_JOINABLE);
|
||||
}
|
||||
for (int i = 0; i < NumThreads; i++) {
|
||||
int err = pthread_create(&ThreadIDs[i], &attr[i], HelloFunc, (void*)&Num[i]);
|
||||
|
||||
if(err != 0) {
|
||||
printf("ERROR: pthread_create() return code: %d\n", err);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < NumThreads; i++) {
|
||||
pthread_join(ThreadIDs[i], NULL);
|
||||
printf("Thread %d end !\n", i);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user