Skip to content

Commit

Permalink
Add CSR matrix addition code
Browse files Browse the repository at this point in the history
  • Loading branch information
brucehow committed Sep 14, 2019
1 parent b6a1bd6 commit 906501f
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 9 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ matrix

# Resource files
resources/

# Mac OS
*.DS_STORE
60 changes: 51 additions & 9 deletions matrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ int main(int argc, char *argv[]) {
routine.type = UNDEF;
int rows, cols;
char *data = NULL;
char *data2 = NULL;
char *filename = NULL;
char *filename2 = NULL;
bool log = false;
Expand Down Expand Up @@ -159,7 +160,10 @@ int main(int argc, char *argv[]) {
exit(EXIT_FAILURE);
}
if (filename2 != NULL && routine.type != MM && routine.type != AD) {
usage("only one matrix input file is required with routine\n");
usage("only one matrix input file is required with this routine\n");
exit(EXIT_FAILURE);
} else if (filename2 == NULL && (routine.type == MM || routine.type == AD)) {
usage("two matrix input files are required with this routine\n");
exit(EXIT_FAILURE);
}

Expand Down Expand Up @@ -215,7 +219,7 @@ int main(int argc, char *argv[]) {
exit(EXIT_FAILURE);
}
data = read_line(fp);
struct CSR csr_matrix = csr_format(rows, cols, type, data);
struct CSR trmatrix = csr_format(rows, cols, type, data);
end = clock();
load_time = (double) (end - start) / CLOCKS_PER_SEC; // Divide by CPS for seconds

Expand All @@ -224,14 +228,14 @@ int main(int argc, char *argv[]) {
int i;
float f;
} trace_result;
if (csr_matrix.type == TYPE_INT) {
if (trmatrix.type == TYPE_INT) {
start = clock();
trace_result.i = trace(csr_matrix);
trace_result.i = trace(trmatrix);
end = clock();
routine_time = (double) (end - start) / CLOCKS_PER_SEC;
} else {
start = clock();
trace_result.f = trace_f(csr_matrix);
trace_result.f = trace_f(trmatrix);
end = clock();
routine_time = (double) (end - start) / CLOCKS_PER_SEC;
}
Expand All @@ -243,10 +247,10 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "matrix: failed to generate output file\n");
exit(EXIT_FAILURE);
}
write_details(output, filename, filename2, rows, cols, routine.type, csr_matrix.type);
write_details(output, filename, filename2, rows, cols, routine.type, trmatrix.type);

// Write single trace value
if (csr_matrix.type == TYPE_INT) {
if (trmatrix.type == TYPE_INT) {
fprintf(output, "%d\n", trace_result.i);
} else {
fprintf(output, "%f\n", trace_result.f);
Expand All @@ -256,8 +260,8 @@ int main(int argc, char *argv[]) {
fclose(output);
free(output_file);
} else {
write_details(stdout, filename, filename2, rows, cols, routine.type, csr_matrix.type);
if (csr_matrix.type == TYPE_INT) {
write_details(stdout, filename, filename2, rows, cols, routine.type, trmatrix.type);
if (trmatrix.type == TYPE_INT) {
fprintf(stdout, "%d\n", trace_result.i);
} else {
fprintf(stdout, "%f\n", trace_result.f);
Expand All @@ -266,6 +270,43 @@ int main(int argc, char *argv[]) {
}
break;
case AD:
// Read input files
start = clock();
type = read_mat_type(fp);
rows = read_mat_dim(fp);
cols = read_mat_dim(fp);
data = read_line(fp);
struct CSR admatrix = csr_format(rows, cols, type, data);
end = clock();
load_time = (double) (end - start) / CLOCKS_PER_SEC;

// Filename2 validation
FILE *fp2 = fopen(filename2, "r");
if (fp2 == NULL) {
fprintf(stderr, "%s: no such file\n", filename2);
exit(EXIT_FAILURE);
}

start = clock();
type = read_mat_type(fp2);
rows = read_mat_dim(fp2);
cols = read_mat_dim(fp2);
data2 = read_line(fp2);
struct CSR admatrix2 = csr_format(rows, cols, type, data2);

end = clock();
load_time += (double) (end - start) / CLOCKS_PER_SEC; // Divide by CPS for seconds

// Check identical dims
if (admatrix.rows != admatrix2.rows || admatrix.cols != admatrix2.cols) {
fprintf(stderr, "matrix: the addition routine can only be performed on matrices with identical dimensions\n");
exit(EXIT_FAILURE);
}

start = clock();
struct CSR result = matrix_addition(admatrix, admatrix2);
end = clock();
routine_time = (double) (end - start) / CLOCKS_PER_SEC;
break;
case TS:
break;
Expand All @@ -277,5 +318,6 @@ int main(int argc, char *argv[]) {
}
fclose(fp);
free(data);
free(data2);
exit(EXIT_SUCCESS);
}
3 changes: 3 additions & 0 deletions matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ extern int trace(struct CSR matrix);

extern float trace_f(struct CSR matrix);

extern struct CSR matrix_addition(struct CSR matrix1, struct CSR matrix2);


/**
* Allocates memory of a given size using malloc
*
Expand Down
74 changes: 74 additions & 0 deletions routines.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ void scalar_multiply(struct COO matrix, float scalar) {
int trace(struct CSR matrix) {
int trace = 0;

#pragma omp parallel for
for (int i = 1; i < matrix.rows + 1; i++) {
// Check num of elements in row i
int elements = matrix.ia[i] - matrix.ia[i-1];
Expand All @@ -40,6 +41,7 @@ int trace(struct CSR matrix) {
float trace_f(struct CSR matrix) {
float trace = 0.0;

#pragma omp parallel for
for (int i = 1; i < matrix.rows + 1; i++) {
// Check num of elements in row i
int elements = matrix.ia[i] - matrix.ia[i-1];
Expand All @@ -60,6 +62,78 @@ float trace_f(struct CSR matrix) {
return trace;
}

struct CSR matrix_addition(struct CSR matrix, struct CSR matrix2) {
struct CSR result;
result.rows = matrix.rows;
result.cols = matrix.cols;
result.type = matrix.type;

size_t nnz_size = matrix.count * sizeof(int);
result.ia = allocate(sizeof(int) * (result.rows+1));
result.ja = allocate(nnz_size);
result.nnz.i = allocate(nnz_size);
result.count = 0;
result.ia[0] = 0;

for (int i = 1; i < matrix.rows + 1; i++) {
int elements = matrix.ia[i] - matrix.ia[i-1];
int elements2 = matrix2.ia[i] - matrix2.ia[i-1];
int pos = matrix.ia[i-1];
int pos2 = matrix2.ia[i-1];
int total = elements + elements2;

while (total > 0) {
if (pos - matrix.ia[i-1] == elements) { // Matrix no more elements
while (pos2 - matrix2.ia[i-1] <= elements2) {
result.nnz.i[result.count++] = matrix2.nnz.i[pos2++];

// Dynamic memory allocation
if (sizeof(int) * result.count == nnz_size) {
nnz_size *= 2;
result.nnz.i = reallocate(result.nnz.i, nnz_size);
result.ja = reallocate(result.ja, nnz_size);
}
}
break;
} else if (pos2 - matrix2.ia[i-1] == elements2) { // Matrix2 no more elements
while (pos - matrix.ia[i-1] <= elements) {
result.nnz.i[result.count++] = matrix.nnz.i[pos++];

// Dynamic memory allocation
if (sizeof(int) * result.count == nnz_size) {
nnz_size *= 2;
result.nnz.i = reallocate(result.nnz.i, nnz_size);
result.ja = reallocate(result.ja, nnz_size);
}
}
break;
} else { // Both matrices have elements
if (matrix.ja[pos] < matrix2.ja[pos2]) {
result.ja[result.count] = matrix.ja[pos];
result.nnz.i[result.count++] = matrix.nnz.i[pos++];
} else if (matrix2.ja[pos2] < matrix.ja[pos]) {
result.ja[result.count] = matrix2.ja[pos2];
result.nnz.i[result.count++] = matrix2.nnz.i[pos2++];
} else { // Perform addition
result.ja[result.count] = matrix.ja[pos];
result.nnz.i[result.count++] = matrix.nnz.i[pos++] + matrix2.nnz.i[pos2++];
total--;
}
// Dynamic memory allocation
if (sizeof(int) * result.count == nnz_size) {
nnz_size *= 2;
result.nnz.i = reallocate(result.nnz.i, nnz_size);
result.ja = reallocate(result.ja, nnz_size);
}
total--;
}
}
result.ia[i] = result.count;
}
return result;
}


void transpose(struct COO matrix) {

}
Expand Down

0 comments on commit 906501f

Please sign in to comment.