commit e4538e51f0394019ff326bfc69d42dcc5a7d633f
parent 38620e1c79ee698e1c9dbf7fd72028db3bf372fb
Author: Christos Margiolis <christos@margiolis.net>
Date: Sun, 3 Jan 2021 17:07:00 +0200
finishing some assignments
Diffstat:
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
-}