uni

University stuff
git clone git://git.christosmarg.xyz/uni-assignments.git
Log | Files | Refs | README | LICENSE

commit e4538e51f0394019ff326bfc69d42dcc5a7d633f
parent 38620e1c79ee698e1c9dbf7fd72028db3bf372fb
Author: Christos Margiolis <christos@margiolis.net>
Date:   Sun,  3 Jan 2021 17:07:00 +0200

finishing some assignments

Diffstat:
Mc-parallel-computing/ex2/ex2.c | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Msh-os1/ex2/mfproc | 43++++++++++++++++++++++++++++++++-----------
Ash-os1/ex3/avgs.awk | 17+++++++++++++++++
Dsh-os1/ex3/avgsort.awk | 10----------
4 files changed, 126 insertions(+), 35 deletions(-)

diff --git a/c-parallel-computing/ex2/ex2.c b/c-parallel-computing/ex2/ex2.c @@ -8,6 +8,11 @@ #define COUNT_BELOW_AVG 1 << 0 #define COUNT_ABOVE_AVG 1 << 1 +struct Max { + float val; /* max value in array */ + int i; /* index of max */ +}; + /* function declarations */ static float input(const char *, int); static void readvec(float *, int); @@ -16,12 +21,15 @@ static float findavg(float *, int); static float calcavg(void); static int count(float, int); static float calcvar(float); +static float *calcd(float, float); +struct Max findmax(float *); +static void printv(const char *, const float *); static void *emalloc(size_t); /* global variables */ static int rank, nproc, root = 0; -static int n, localn; static float *vec, *localvec; +static int n, localn; /* function implementations */ static float @@ -54,12 +62,11 @@ find(int flag) float *res; int i; + res = emalloc(nproc * sizeof(float)); for (i = 0; i < localn; i++) if ((flag & FIND_XMIN && localvec[i] < localres) || (flag & FIND_XMAX && localvec[i] > localres)) localres = localvec[i]; - - res = emalloc(nproc * sizeof(float)); MPI_Gather(&localres, 1, MPI_FLOAT, res, 1, MPI_FLOAT, root, MPI_COMM_WORLD); if (rank == root) @@ -107,12 +114,11 @@ count(float avg, int flag) { int *res, localres = 0, finalres = 0, i; + res = emalloc(nproc * sizeof(int)); for (i = 0; i < localn; i++) if ((flag & COUNT_BELOW_AVG && localvec[i] < avg) || (flag & COUNT_ABOVE_AVG && localvec[i] > avg)) localres++; - - res = emalloc(nproc * sizeof(int)); MPI_Gather(&localres, 1, MPI_INT, res, 1, MPI_INT, root, MPI_COMM_WORLD); if (rank == root) @@ -150,18 +156,68 @@ calcvar(float avg) static float * calcd(float xmin, float xmax) { - float *locald, *finald = NULL; + float *locald, *finald; + int *displs, *rcounts; int i; locald = emalloc(localn * sizeof(float)); - for (i = 0; i < localn; i++) + finald = emalloc(n * sizeof(float)); + displs = emalloc(n * sizeof(int)); + rcounts = emalloc(n * sizeof(int)); + + for (i = 0; i < localn; i++) { locald[i] = ((localvec[i] - xmin) / (xmax - xmin)) * 100; + displs[i] = i * localn; + rcounts[i] = localn; + } + MPI_Gatherv(locald, localn, MPI_FLOAT, finald, rcounts, displs, + MPI_FLOAT, root, MPI_COMM_WORLD); free(locald); + free(displs); + free(rcounts); return finald; } +struct Max +findmax(float *d) +{ + struct Max in, out; + float *locald; + int i = 0; + + locald = emalloc(localn * sizeof(float)); + /* TODO: change to Scatterv */ + MPI_Scatter(d, localn, MPI_FLOAT, locald, localn, MPI_FLOAT, root, + MPI_COMM_WORLD); + + in.val = *locald; + in.i = 0; + for (; i < localn; i++) { + if (in.val < locald[i]) { + in.val = locald[i]; + in.i = i; + } + } + in.i += rank * localn; + MPI_Reduce(&in, &out, 1, MPI_FLOAT_INT, MPI_MAXLOC, root, MPI_COMM_WORLD); + free(locald); + + return out; +} + +static void +printv(const char *str, const float *v) +{ + int i = 0; + + printf("%s [", str); + for (; i < n; i++) + printf("%.4f%s", v[i], i != n-1 ? ", " : ""); + printf("]\n"); +} + static void * emalloc(size_t nb) { @@ -177,7 +233,9 @@ emalloc(size_t nb) int main(int argc, char *argv[]) { - float *d, avg, var, xmin, xmax; + struct Max dmax; + float avg, var, xmin, xmax; + float *d; int belowavg, aboveavg; MPI_Init(&argc, &argv); @@ -194,6 +252,7 @@ main(int argc, char *argv[]) MPI_Bcast(&n, 1, MPI_INT, root, MPI_COMM_WORLD); localn = n / nproc; localvec = emalloc(localn * sizeof(float)); + /* TODO: change to Scatterv */ MPI_Scatter(vec, localn, MPI_FLOAT, localvec, localn, MPI_FLOAT, root, MPI_COMM_WORLD); /* part 0.1 - calculate min and max */ @@ -216,25 +275,29 @@ main(int argc, char *argv[]) */ d = calcd(xmin, xmax); + /* part 4 - find dmax and dmaxloc */ + dmax = findmax(d); + + /* part 5 - prefixs sum of vec */ + /* print all results */ if (rank == root) { printf("\n"); + printv("X: ", vec); printf("Average: %.4f\n", avg); printf("Xmin: %.4f\n", xmin); printf("Xmax: %.4f\n", xmax); printf("Below Average: %d\n", belowavg); printf("Above Average: %d\n", aboveavg); printf("Variance: %.4f\n", var); - - /* TODO: cleanup, very ugly */ - printf("Vector D: ["); - for (int i = 0; i < n; i++) - printf("%.4f%s", var, i != n-1 ? ", " : ""); - printf("]\n"); + printv("D: ", d); + printf("Dmax: %.4f\n", dmax.val); + printf("Dmaxloc: %d\n", dmax.i % n); } free(vec); free(localvec); + free(d); MPI_Finalize(); diff --git a/sh-os1/ex2/mfproc b/sh-os1/ex2/mfproc @@ -1,43 +1,64 @@ #!/bin/sh +# Exit codes: +# 0 Success +# 1 No user +# 2 No process +# 3 Usage + main() { + # TODO: explain getopts(1) while getopts u:s: arg; do case "${arg}" in u) test ! -z "$(grep -w "^${OPTARG}" /etc/passwd)" || - err "'${OPTARG}' is not in /etc/passwd" + err "'${OPTARG}' is not in /etc/passwd" 1 uid=$(id -u ${OPTARG}) ;; - # TODO: error check - s) state="${OPTARG}" ;; + s) state="${OPTARG}" + validstate ${state} || usage ;; *) usage esac done + count=0 printf "Name\tPID\tPPID\tUID\tGID\tState\n" | expand -t 16 for proc in /proc/*/status; do - # call getfield once - # handle flags - procname=$(getfield "Name" ${proc}) - procpid=$(getfield "Pid" ${proc}) - procppid=$(getfield "PPid" ${proc}) procuid=$(getfield "Uid:\s*${uid}" ${proc}) procgid=$(getfield "Gid" ${proc}) + test -z ${uid} || [ "${procuid}" == "${uid}" ] || continue + procstate=$(getfield "State:\s*${state}" ${proc}) + # Ignore any state other than S|R|Z + validstate ${procstate} || continue + test -z ${state} || [ "${procstate}" == "${state}" ] || continue + + procname=$(getfield "Name" ${proc}) + procpid=$(getfield "Pid" ${proc}) + procppid=$(getfield "PPid" ${proc}) printf "%s\t%s\t%s\t%s\t%s\t%s\n" \ ${procname} ${procpid} ${procppid} ${procuid} ${procgid} ${procstate} | expand -t 16 - + count=$(expr ${count} + 1) done + + # We didn't print any process + test ${count} -eq 0 && exit 2 + # Success! + exit 0 } usage() { echo "usage: ${0##*/} [-u username] [-s S|R|Z]" 1>&2 - exit 1 + exit 3 } err() { echo "${0##*/}: $@" 1>&2 - exit 1 + exit ${2} +} + +validstate() { + [ "${1}" = "S" ] || [ "${1}" = "R" ] || [ "${1}" = "Z" ] } getfield() { diff --git a/sh-os1/ex3/avgs.awk b/sh-os1/ex3/avgs.awk @@ -0,0 +1,17 @@ +#!/usr/bin/env -S awk -f + +BEGIN { + if (ARGC < 2) { + print "usage: avgs.awk grades" + exit 1 + } +} + +{ + sum = cnt = 0; + for (i = 4; i <= NF; i++) { + sum += $i; + cnt++; + } + print "Student", NR",", $1, $2",", sum / cnt +} diff --git a/sh-os1/ex3/avgsort.awk b/sh-os1/ex3/avgsort.awk @@ -1,10 +0,0 @@ -#!/usr/bin/env -S awk -f - -{ - sum = cnt = 0; - for (i = 4; i <= NF; i++) { - sum += $i; - cnt++; - } - print "Student", NR",", $1, $2",", sum / cnt -}