-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
cs241svngrader
committed
Sep 22, 2016
1 parent
cb7d917
commit e4f9c37
Showing
8 changed files
with
318 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
OBJS_DIR = .objs | ||
|
||
# define all of student executables | ||
EXE_PAR_MAP=par_map | ||
EXES_STUDENT=$(EXE_PAR_MAP) | ||
|
||
# list object file dependencies for each | ||
OBJS_PAR_MAP=main.o map.o mappers.o par_map.o | ||
|
||
# set up compiler | ||
CC = clang | ||
WARNINGS = -Wall -Wextra -Werror -Wno-error=unused-parameter | ||
INCLUDES=-I./includes/ | ||
CFLAGS_DEBUG = $(INCLUDES) -O0 $(WARNINGS) -g -std=c99 -c -MMD -MP -D_GNU_SOURCE -DDEBUG | ||
CFLAGS_RELEASE = $(INCLUDES) -O2 $(WARNINGS) -g -std=c99 -c -MMD -MP -D_GNU_SOURCE | ||
|
||
# set up linker | ||
LD = clang | ||
LDFLAGS = -lrt -pthread | ||
|
||
# the string in grep must appear in the hostname, otherwise the Makefile will | ||
# not allow the assignment to compile | ||
IS_VM=$(shell hostname | grep "fa16") | ||
|
||
ifeq ($(IS_VM),) | ||
$(error This assignment must be compiled on the CS241 VMs) | ||
endif | ||
|
||
.PHONY: all | ||
all: release | ||
|
||
# build types | ||
.PHONY: release | ||
.PHONY: debug | ||
|
||
release: $(EXES_STUDENT) | ||
debug: clean $(EXES_STUDENT:%=%-debug) | ||
|
||
# include dependencies | ||
-include $(OBJS_DIR)/*.d | ||
|
||
$(OBJS_DIR): | ||
@mkdir -p $(OBJS_DIR) | ||
|
||
# patterns to create objects | ||
# keep the debug and release postfix for object files so that we can always | ||
# separate them correctly | ||
$(OBJS_DIR)/%-debug.o: %.c | $(OBJS_DIR) | ||
$(CC) $(CFLAGS_DEBUG) $< -o $@ | ||
|
||
$(OBJS_DIR)/%-release.o: %.c | $(OBJS_DIR) | ||
$(CC) $(CFLAGS_RELEASE) $< -o $@ | ||
|
||
# exes | ||
# you will need a pair of exe and exe-debug targets for each exe | ||
$(EXE_PAR_MAP)-debug: $(OBJS_PAR_MAP:%.o=$(OBJS_DIR)/%-debug.o) | ||
$(LD) $^ $(LDFLAGS) -o $@ | ||
|
||
$(EXE_PAR_MAP): $(OBJS_PAR_MAP:%.o=$(OBJS_DIR)/%-release.o) | ||
$(LD) $^ $(LDFLAGS) -o $@ | ||
|
||
.PHONY: clean | ||
clean: | ||
rm -rf .objs $(EXES_STUDENT) $(EXES_STUDENT:%=%-debug) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/** | ||
* Parallel Map Lab | ||
* CS 241 - Fall 2016 | ||
*/ | ||
#include <assert.h> | ||
#include <stdbool.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <time.h> | ||
|
||
#include "map.h" | ||
#include "mappers.h" | ||
#include "par_map.h" | ||
|
||
#define SEED 241 | ||
|
||
void validate_args(int argc, char *argv[]) { | ||
// Verify correct number of arguments: | ||
if (argc != 4) { | ||
fprintf(stderr, "usage: %s <mapper_name> <list_len> <num_threads>\n", | ||
argv[0]); | ||
exit(1); | ||
} | ||
|
||
// Verifying that list_len and num_threads are actually integers greater than | ||
// 1: | ||
char *endptr; | ||
for (int i = 2; i <= 3; i++) { | ||
char *str_value = argv[i]; | ||
long value = strtol(str_value, &endptr, 10); | ||
|
||
if (*endptr != '\0') { | ||
fprintf(stderr, "Failed to convert an [%s] to a long!\n", str_value); | ||
exit(3); | ||
} | ||
|
||
if (value < 1) { | ||
fprintf(stderr, "[%s] needs to be greater than or equal to 1!\n", | ||
str_value); | ||
exit(4); | ||
} | ||
} | ||
} | ||
|
||
double *gen_random_list(size_t num_elems) { | ||
double *list = (double *)malloc(sizeof(double) * num_elems); | ||
|
||
for (size_t i = 0; i < num_elems; ++i) { | ||
list[i] = ((double)rand() / (double)RAND_MAX); | ||
} | ||
|
||
return list; | ||
} | ||
|
||
bool verify(double *output_list, double *input_list, mapper map_func, | ||
size_t list_len) { | ||
// call on 'map_func' to modify 'list' inplace | ||
// then verify element wise with 'output_list'. | ||
double *soln_list = map(input_list, list_len, map_func); | ||
for (size_t i = 0; i < list_len; ++i) { | ||
if (soln_list[i] != output_list[i]) { | ||
return false; | ||
} | ||
} | ||
free(output_list); | ||
free(soln_list); | ||
return true; | ||
} | ||
|
||
int main(int argc, char *argv[]) { | ||
validate_args(argc, argv); | ||
|
||
// Seeding random number generator | ||
srand(SEED); | ||
|
||
char *mapper_name = argv[1]; | ||
size_t list_len = strtol(argv[2], NULL, 10); | ||
size_t num_threads = strtol(argv[3], NULL, 10); | ||
|
||
double *list = gen_random_list(list_len); | ||
mapper map_func = get_mapper(mapper_name); | ||
|
||
double *list_copy = (double *)malloc(sizeof(double) * list_len); | ||
memcpy(list_copy, list, sizeof(double) * list_len); | ||
|
||
struct timespec start, end; | ||
clock_gettime(CLOCK_MONOTONIC, &start); | ||
|
||
double *ret_list = par_map(list_copy, list_len, map_func, num_threads); | ||
|
||
clock_gettime(CLOCK_MONOTONIC, &end); | ||
double diff = | ||
(end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1E9; | ||
printf("par_map ran in %f seconds\n", diff); | ||
|
||
bool passed = verify(ret_list, list_copy, map_func, list_len); | ||
if (passed) { | ||
printf("Congratulations you have succesfully ran par_map with %s on a list " | ||
"with %zu elements, and %zu threads\n", | ||
mapper_name, list_len, num_threads); | ||
} | ||
|
||
free(list); | ||
free(list_copy); | ||
return passed; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/** | ||
* Parallel Map Lab | ||
* CS 241 - Fall 2016 | ||
*/ | ||
#include "map.h" | ||
#include <stdlib.h> | ||
|
||
double *map(double *list, size_t length, mapper map_func) { | ||
double *ret_list = (double *)malloc(sizeof(double) * length); | ||
|
||
for (size_t i = 0; i < length; ++i) { | ||
ret_list[i] = map_func(list[i]); | ||
} | ||
|
||
return ret_list; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/** | ||
* Parallel Map Lab | ||
* CS 241 - Fall 2016 | ||
*/ | ||
#ifndef __CS241_MAP_H__ | ||
#define __CS241_MAP_H__ | ||
|
||
#include "mappers.h" | ||
#include <stdlib.h> | ||
|
||
/** | ||
* Single threaded solution to map(). | ||
* | ||
* This method takes in a `list` of doubles and returns a list of doubles where | ||
* every element has had `map_func` applied to it. | ||
* | ||
* Note: that this function DOES NOT modify the original list. | ||
* | ||
* `list`- is a pointer to the begining of an array of doubles. | ||
* `length` - is how many doubles are in the array of doubles. | ||
* `map_func` - is the mapper used to transform a double to another double and | ||
* is applied to every element of the list. | ||
*/ | ||
double *map(double *list, size_t length, mapper map_func); | ||
#endif /* __CS241_MAP_H__ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/** | ||
* Parallel Map Lab | ||
* CS 241 - Fall 2016 | ||
*/ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
|
||
#include "mappers.h" | ||
|
||
mapper get_mapper(char *mapper_name) { | ||
if (strcmp(mapper_name, "triple") == 0) { | ||
return triple; | ||
} else if (strcmp(mapper_name, "negate") == 0) { | ||
return negate; | ||
} else if (strcmp(mapper_name, "slow") == 0) { | ||
return slow; | ||
} | ||
/* more else if clauses */ | ||
else /* default: */ { | ||
fprintf(stderr, "Could not recognize [%s] as a mapper!\n", mapper_name); | ||
exit(4); | ||
} | ||
} | ||
|
||
double triple(double elem) { return 3 * elem; } | ||
|
||
double negate(double elem) { return -1 * elem; } | ||
|
||
double slow(double elem) { | ||
usleep(1000); | ||
return elem; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/** | ||
* Parallel Map Lab | ||
* CS 241 - Fall 2016 | ||
*/ | ||
#ifndef __CS241_MAPPERS_H__ | ||
#define __CS241_MAPPERS_H__ | ||
/** | ||
* This callback function takes in a double and returns a double. | ||
*/ | ||
typedef double (*mapper)(double elem); | ||
|
||
/** | ||
* Returns the mapper that matches the name 'mapper_name' | ||
*/ | ||
mapper get_mapper(char *mapper_name); | ||
|
||
// Callback functions | ||
double triple(double elem); | ||
double negate(double elem); | ||
double slow(double elem); | ||
#endif /* __CS241_MAPPERS_H__ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** | ||
* Parallel Map Lab | ||
* CS 241 - Fall 2016 | ||
*/ | ||
#include <pthread.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
|
||
#include "map.h" | ||
#include "mappers.h" | ||
|
||
/* You should create a struct that will get passed in by reference to your | ||
* start_routine. */ | ||
|
||
/* You should create a start routine for your threads. */ | ||
|
||
double *par_map(double *list, size_t list_len, mapper map_func, | ||
size_t num_threads) { | ||
/* Your implementation goes here */ | ||
return NULL; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/** | ||
* Parallel Map Lab | ||
* CS 241 - Fall 2016 | ||
*/ | ||
#ifndef __CS241_PAR_MAP_H__ | ||
#define __CS241_PAR_MAP_H__ | ||
|
||
#include "mappers.h" | ||
|
||
/** | ||
* multi-threaded solution to map(). | ||
* | ||
* This method takes in a `list` of doubles and returns a list of doubles where | ||
* every element has had `map_func` applied to it, but does so with | ||
* `num_threads` threads. | ||
* | ||
* Note: that this function DOES NOT modify the original list. | ||
* | ||
* `list`- is a pointer to the begining of an array of doubles. | ||
* `length` - is how many doubles are in the array of doubles. | ||
* `map_func` - is the mapper used to transform a double to another double and | ||
* is applied to every element of the list. | ||
* `num_threads` - is how many threads (in addition to the main thread) are used | ||
* in the parallelization. | ||
*/ | ||
double *par_map(double *list, size_t length, mapper map_func, | ||
size_t num_threads); | ||
#endif /* __CS241_PAR_MAP_H__ */ |