Skip to content

Commit

Permalink
Finialise command line args
Browse files Browse the repository at this point in the history
  • Loading branch information
brucehow committed Sep 11, 2019
1 parent 24cb3e3 commit cce5e5b
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 52 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
# @date 03/09/2019

PROGNAME = matrix
GCC = gcc-9 -std=c99 -pedantic -fopenmp
DEPENDENCIES = matrix.c format.c memory.c process.c
GCC = gcc-9 -std=c99 -pedantic -Wall -Werror
DEPENDENCIES = matrix.c format.c memory.c process.c routines.c

all: $(DEPENDENCIES)
@$(GCC) -o $(PROGNAME) $(DEPENDENCIES)
@echo "make: 'matrix' successfully built."

clean: $(DEPENDENCIES)
@rm $(PROGNAME)
@echo "make: 'matrix' has been removed."
@echo "make: 'matrix' has been removed."
49 changes: 24 additions & 25 deletions format.c
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
#include "matrix.h"

void check_numeric(char *val) {
int len = strlen(val);
for (int i = 0; i < len; i++) {
if (!isdigit(val[i])) {
fprintf(stderr, "Invalid value in matrix data '%s'\n", val);
exit(EXIT_FAILURE);
}
}
}

struct COO coo_format(int rows, int cols, enum mat_type type, char *data) {
struct COO coo_format(int rows, int cols, enum VAR_TYPE type, char *data) {
// Structure variable initialisation
struct COO matrix;
size_t elements_size = MEMSIZ * sizeof(struct ELEMENT);
Expand Down Expand Up @@ -41,11 +31,14 @@ struct COO coo_format(int rows, int cols, enum mat_type type, char *data) {
}
val[len] = '\0';
pos++; // Move away from separating char
check_numeric(val);


// Zero value filter
if (type == INT_MAT) {
int value = atoi(val);
if (type == TYPE_INT) {
int value = strtoimax(val, NULL, 10);
if (errno == EINVAL) {
fprintf(stderr, "Invalid value in matrix data '%s'\n", val);
exit(EXIT_FAILURE);
}
if (value != 0) {
// Dynamically allocate memory for elements struct pointer
if (((matrix.count) * sizeof(struct ELEMENT)) == elements_size) {
Expand Down Expand Up @@ -76,12 +69,12 @@ struct COO coo_format(int rows, int cols, enum mat_type type, char *data) {
return matrix;
}

struct CSR csr_format(int rows, int cols, enum mat_type type, char *data) {
struct CSR csr_format(int rows, int cols, enum VAR_TYPE type, char *data) {
// Structure variable initialisation
struct CSR matrix;
size_t nnz_size;
size_t ja_size = MEMSIZ * sizeof(int);
if (type == INT_MAT) {
if (type == TYPE_INT) {
nnz_size = MEMSIZ * sizeof(int);
matrix.nnz.i = allocate(nnz_size);
} else {
Expand Down Expand Up @@ -118,11 +111,14 @@ struct CSR csr_format(int rows, int cols, enum mat_type type, char *data) {
}
val[len] = '\0';
pos++; // Move away from separating char
check_numeric(val);

// Zero value filter
if (type == INT_MAT) {
int value = atoi(val);
if (type == TYPE_INT) {
int value = strtoimax(val, NULL, 10);
if (errno == EINVAL) {
fprintf(stderr, "Invalid value in matrix data '%s'\n", val);
exit(EXIT_FAILURE);
}
if (value != 0) {
// Dynamically allocate memory for nnz and ja pointers
if ((matrix.count * sizeof(int)) == ja_size) {
Expand Down Expand Up @@ -156,12 +152,12 @@ struct CSR csr_format(int rows, int cols, enum mat_type type, char *data) {
return matrix;
}

struct CSC csc_format(int rows, int cols, enum mat_type type, char *data) {
struct CSC csc_format(int rows, int cols, enum VAR_TYPE type, char *data) {
// Structure variable initialisation
struct CSC matrix;
size_t nnz_size;
size_t ja_size = MEMSIZ * sizeof(int);
if (type == INT_MAT) {
if (type == TYPE_INT) {
nnz_size = MEMSIZ * sizeof(int);
matrix.nnz.i = allocate(nnz_size);
} else {
Expand Down Expand Up @@ -215,11 +211,14 @@ struct CSC csc_format(int rows, int cols, enum mat_type type, char *data) {
pos++;
}
skip = 0;
check_numeric(val);

// Zero value filter
if (type == INT_MAT) {
int value = atoi(val);
if (type == TYPE_INT) {
int value = strtoimax(val, NULL, 10);
if (errno == EINVAL) {
fprintf(stderr, "Invalid value in matrix data '%s'\n", val);
exit(EXIT_FAILURE);
}
if (value != 0) {
// Dynamically allocate memory for nnz and ja pointers
if ((matrix.count * sizeof(int)) == ja_size) {
Expand Down
151 changes: 140 additions & 11 deletions matrix.c
Original file line number Diff line number Diff line change
@@ -1,30 +1,159 @@
#include "matrix.h"

int main(int argc, char *argv[]) {
enum mat_type type;
int rows, cols;
char *data = NULL;

char *usage = "usage: matrix {routines} [options] -f matrix1 [matrix2]\nroutines:\n"
void usage(char *err) {
char *usage = "\nusage: matrix {routines} [options] -f matrix1 [matrix2]\n"
"routines:\n"
" --sm alpha\tperform scalar multiplcation with value alpha\n"
" --tr\t\tcompute the matrix trace value\n"
" --ad\t\tperform matrix addition on two matrices\n"
" --ad\t\tperform matrix addition on two matrices, matrix2 must be specified\n"
" --ts\t\ttranspose the given matrix\n"
" --mm\t\tperform matrix multiplication on two matrices\n"
" --mm\t\tperform matrix multiplication on two matrices, matrix2 must be specified\n"
"options:\n"
" -t threads\tspecify the number of execution threads to use\n"
" -l log\tspecify the log file to output results to\n";
if (err != NULL) {
fprintf(stderr, "matrix: %s", err);
}
printf("%s", usage);
}

// Command line args
int main(int argc, char *argv[]) {
// Variable declarations
enum VAR_TYPE type = INVALID;
struct ROUTINE routine;
routine.type = UNDEF;
int rows, cols;
char *data = NULL;
char *filename = NULL;
char *filename2 = NULL;
char *logfile = NULL;
int arg = 1; // Argument pointer

// Argument processing
if (argc < 4) {
fprintf(stderr, "%s", usage);
usage("invalid number of arguments supplied\n");
exit(EXIT_FAILURE);
}
while (arg < argc) {
if (strcmp(argv[arg], "--sm") == 0) {
if (routine.type != UNDEF) {
usage("only one routine may be specified\n");
exit(EXIT_FAILURE);
} else if ((arg + 1) == argc) { // Expect alpha value
usage("no alpha value supplied when using --sm\n");
exit(EXIT_FAILURE);
}
arg++;
type = numeric_type(argv[arg]); // Check alpha input type
if (type == INVALID) {
usage("alpha value must be numeric\n");
exit(EXIT_FAILURE);
} else {
routine.type = SM;
switch (type) {
case TYPE_INT:
routine.param.i = strtoimax(argv[arg], NULL, 10);
if (errno == EINVAL || errno == ERANGE) {
fprintf(stderr, "Failed to convert alpha value '%s' to int\n", argv[arg]);
exit(EXIT_FAILURE);
}
break;
case TYPE_FLOAT:
routine.param.f = strtof(argv[arg], NULL);
if (errno == ERANGE) {
fprintf(stderr, "Failed to convert alpha value '%s' to float\n", argv[arg]);
exit(EXIT_FAILURE);
}
break;
case INVALID: // Should not get here
fprintf(stderr, "Unable to determine alpha value data type '%s'\n", argv[arg]);
exit(EXIT_FAILURE);
}
}
} else if (strcmp(argv[arg], "--tr") == 0) {
if (routine.type != UNDEF) {
usage("only one routine may be specified\n");
exit(EXIT_FAILURE);
}
routine.type = TR;
} else if (strcmp(argv[arg], "--ad") == 0) {
if (routine.type != UNDEF) {
usage("only one routine may be specified\n");
exit(EXIT_FAILURE);
}
routine.type = AD;
} else if (strcmp(argv[arg], "--ts") == 0) {
if (routine.type != UNDEF) {
usage("only one routine may be specified\n");
exit(EXIT_FAILURE);
}
routine.type = TS;
} else if (strcmp(argv[arg], "--mm") == 0) {
if (routine.type != UNDEF) {
usage("only one routine may be specified\n");
exit(EXIT_FAILURE);
}
routine.type = MM;
} else if (strcmp(argv[arg], "-t") == 0) {
if ((arg + 1) == argc) { // Expect thread value
usage("number of execution threads must be specified when using -t\n");
exit(EXIT_FAILURE);
}
arg++;
type = numeric_type(argv[arg]); // Check thread input type
if (type != TYPE_INT) {
usage("invalid number of execution threads\n");
exit(EXIT_FAILURE);
} else {
continue; // TODO: CONVERT TO INT AND ASSIGN TO OMP NUM OF THREADS
// TODO: NEED TO CHECK FOR MULTIPLE -T PARAM
}
} else if (strcmp(argv[arg], "-l") == 0) {
if (logfile != NULL) { // Logfile already specified
usage("log parameter should only be used once\n");
exit(EXIT_FAILURE);
} else if ((arg + 1) == argc) { // Expect log file
usage("log file must be specified when using -l\n");
exit(EXIT_FAILURE);
} else {
arg++;
logfile = argv[arg];
}
} else if (strcmp(argv[arg], "-f") == 0) {
if (filename != NULL) { // File already specified
usage("file parameter should only be used onece\n");
exit(EXIT_FAILURE);
} else if ((arg + 1) == argc) { // Expect matrix file
usage("at least one matrix file must be specified after -f\n");
exit(EXIT_FAILURE);
} else if (strcmp(argv[arg+1], "--sm") == 0 || strcmp(argv[arg+1], "--tr") == 0 || strcmp(argv[arg+1], "--ad") == 0
|| strcmp(argv[arg+1], "--ts") == 0 || strcmp(argv[arg+1], "--mm") == 0 || strcmp(argv[arg+1], "-t") == 0
|| strcmp(argv[arg+1], "-l") == 0 || strcmp(argv[arg+1], "-f") == 0) {
usage("at least one matrix file must be specified after -f\n");
exit(EXIT_FAILURE);
} else {
arg++;
filename = argv[arg];
// Check for second matrix file if any
if ((arg + 1) != argc && strcmp(argv[arg+1], "--sm") != 0 && strcmp(argv[arg+1], "--tr") != 0 && strcmp(argv[arg+1], "--ad") != 0
&& strcmp(argv[arg+1], "--ts") != 0 && strcmp(argv[arg+1], "--mm") != 0 && strcmp(argv[arg+1], "-t") != 0
&& strcmp(argv[arg+1], "-l") != 0 && strcmp(argv[arg+1], "-f") != 0) {
arg++;
filename2 = argv[arg];
}
}
}
arg++;
}

// File validation
if (filename == NULL) {
usage("no matrix file specified\n");
exit(EXIT_FAILURE);
}
if (filename2 == NULL) {
printf("no filename2\n");
}
FILE *fp = fopen(filename, "r");
if(fp == NULL) {
fprintf(stderr, "%s: No such file\n", filename);
Expand Down Expand Up @@ -57,7 +186,7 @@ int main(int argc, char *argv[]) {
printf("\n");
/////////////// DEBUG //////////////////

fclose(fp);
free(data);
exit(EXIT_SUCCESS);
}

Loading

0 comments on commit cce5e5b

Please sign in to comment.