lab1 done
This commit is contained in:
parent
a8a0837e11
commit
2d1c510b49
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Xmake cache
|
||||||
|
.xmake/
|
||||||
|
build/
|
||||||
|
compile_commands.json
|
||||||
|
# MacOS Cache
|
||||||
|
.DS_Store
|
||||||
|
# Vim swap files
|
||||||
|
*.swp
|
||||||
|
# Temporary files
|
||||||
|
*~
|
||||||
@ -1,22 +0,0 @@
|
|||||||
# Makefile for building mpi_hello_world from mpi_hello_world.c
|
|
||||||
MPICC ?= mpicc
|
|
||||||
MPIRUN ?= mpirun
|
|
||||||
CFLAGS ?= -O2 -Wall
|
|
||||||
SRC := mpi_hello_world.c serial_pi.c mpi_pi.c
|
|
||||||
TARGET := $(basename $(SRC))
|
|
||||||
|
|
||||||
.PHONY: all clean run
|
|
||||||
|
|
||||||
all: $(TARGET)
|
|
||||||
|
|
||||||
mpi_%: mpi_%.c
|
|
||||||
$(MPICC) $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
serial_%: serial_%.c
|
|
||||||
$(CC) $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
run: $(TARGET)
|
|
||||||
$(MPIRUN) -np 4 ./$@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(TARGET)
|
|
||||||
@ -1,97 +0,0 @@
|
|||||||
#!/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
|
|
||||||
58
lab1/lab1.sh
Executable file
58
lab1/lab1.sh
Executable file
@ -0,0 +1,58 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "Current directory: $PWD"
|
||||||
|
|
||||||
|
# Build directory
|
||||||
|
BUILD_DIR="./build/linux/x86_64/release"
|
||||||
|
|
||||||
|
# Programs
|
||||||
|
MPI_HELLO="$BUILD_DIR/mpi_hello_world"
|
||||||
|
MPI_PI="$BUILD_DIR/mpi_pi"
|
||||||
|
SERIAL_PI="$BUILD_DIR/serial_pi"
|
||||||
|
|
||||||
|
# Check if programs exist
|
||||||
|
if [[ ! -f "$MPI_HELLO" ]]; then
|
||||||
|
echo "Error: $MPI_HELLO not found. Please build first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ! -f "$MPI_PI" ]]; then
|
||||||
|
echo "Error: $MPI_PI not found. Please build first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ! -f "$SERIAL_PI" ]]; then
|
||||||
|
echo "Error: $SERIAL_PI not found. Please build first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Programs found. Starting tests..."
|
||||||
|
|
||||||
|
# Test mpi_hello_world
|
||||||
|
echo "Testing mpi_hello_world with default settings:"
|
||||||
|
mpirun "$MPI_HELLO"
|
||||||
|
echo "mpi_hello_world test completed."
|
||||||
|
|
||||||
|
# Terms to test
|
||||||
|
TERMS=(1000 100000 1000000 10000000 1000000000)
|
||||||
|
PROCS=(1 2 3 4 5 6)
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Testing mpi_pi with different terms and processes:"
|
||||||
|
|
||||||
|
for procs in "${PROCS[@]}"; do
|
||||||
|
for terms in "${TERMS[@]}"; do
|
||||||
|
echo "Running mpi_pi with $procs processes and $terms terms:"
|
||||||
|
mpirun -np $procs "$MPI_PI" <<< $terms
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Testing serial_pi with different terms:"
|
||||||
|
|
||||||
|
for terms in "${TERMS[@]}"; do
|
||||||
|
echo "Running serial_pi with $terms terms:"
|
||||||
|
"$SERIAL_PI" <<< $terms
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "All tests completed."
|
||||||
92
lab1/xmake.lua
Normal file
92
lab1/xmake.lua
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
add_rules("mode.debug", "mode.release")
|
||||||
|
|
||||||
|
-- Find MPI package
|
||||||
|
add_requires("mpi", {system = true})
|
||||||
|
add_requires("mpi_cxx", {system = true})
|
||||||
|
|
||||||
|
|
||||||
|
target("mpi_hello_world")
|
||||||
|
set_kind("binary")
|
||||||
|
add_files("mpi_hello_world.c")
|
||||||
|
add_packages("mpi")
|
||||||
|
add_packages("mpi_cxx")
|
||||||
|
|
||||||
|
target("mpi_pi")
|
||||||
|
set_kind("binary")
|
||||||
|
add_files("mpi_pi.c")
|
||||||
|
add_packages("mpi")
|
||||||
|
add_packages("mpi_cxx")
|
||||||
|
|
||||||
|
target("serial_pi")
|
||||||
|
set_kind("binary")
|
||||||
|
add_files("serial_pi.c")
|
||||||
|
|
||||||
|
--
|
||||||
|
-- If you want to known more usage about xmake, please see https://xmake.io
|
||||||
|
--
|
||||||
|
-- ## FAQ
|
||||||
|
--
|
||||||
|
-- You can enter the project directory firstly before building project.
|
||||||
|
--
|
||||||
|
-- $ cd projectdir
|
||||||
|
--
|
||||||
|
-- 1. How to build project?
|
||||||
|
--
|
||||||
|
-- $ xmake
|
||||||
|
--
|
||||||
|
-- 2. How to configure project?
|
||||||
|
--
|
||||||
|
-- $ xmake f -p [macosx|linux|iphoneos ..] -a [x86_64|i386|arm64 ..] -m [debug|release]
|
||||||
|
--
|
||||||
|
-- 3. Where is the build output directory?
|
||||||
|
--
|
||||||
|
-- The default output directory is `./build` and you can configure the output directory.
|
||||||
|
--
|
||||||
|
-- $ xmake f -o outputdir
|
||||||
|
-- $ xmake
|
||||||
|
--
|
||||||
|
-- 4. How to run and debug target after building project?
|
||||||
|
--
|
||||||
|
-- $ xmake run [targetname]
|
||||||
|
-- $ xmake run -d [targetname]
|
||||||
|
--
|
||||||
|
-- 5. How to install target to the system directory or other output directory?
|
||||||
|
--
|
||||||
|
-- $ xmake install
|
||||||
|
-- $ xmake install -o installdir
|
||||||
|
--
|
||||||
|
-- 6. Add some frequently-used compilation flags in xmake.lua
|
||||||
|
--
|
||||||
|
-- @code
|
||||||
|
-- -- add debug and release modes
|
||||||
|
-- add_rules("mode.debug", "mode.release")
|
||||||
|
--
|
||||||
|
-- -- add macro definition
|
||||||
|
-- add_defines("NDEBUG", "_GNU_SOURCE=1")
|
||||||
|
--
|
||||||
|
-- -- set warning all as error
|
||||||
|
-- set_warnings("all", "error")
|
||||||
|
--
|
||||||
|
-- -- set language: c99, c++11
|
||||||
|
-- set_languages("c99", "c++11")
|
||||||
|
--
|
||||||
|
-- -- set optimization: none, faster, fastest, smallest
|
||||||
|
-- set_optimize("fastest")
|
||||||
|
--
|
||||||
|
-- -- add include search directories
|
||||||
|
-- add_includedirs("/usr/include", "/usr/local/include")
|
||||||
|
--
|
||||||
|
-- -- add link libraries and search directories
|
||||||
|
-- add_links("tbox")
|
||||||
|
-- add_linkdirs("/usr/local/lib", "/usr/lib")
|
||||||
|
--
|
||||||
|
-- -- add system link libraries
|
||||||
|
-- add_syslinks("z", "pthread")
|
||||||
|
--
|
||||||
|
-- -- add compilation and link flags
|
||||||
|
-- add_cxflags("-stdnolib", "-fno-strict-aliasing")
|
||||||
|
-- add_ldflags("-L/usr/local/lib", "-lpthread", {force = true})
|
||||||
|
--
|
||||||
|
-- @endcode
|
||||||
|
--
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user