csci5451/assignments/01/lc_openmp.c

125 lines
No EOL
3.3 KiB
C

#include <math.h>
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
int main(int argc, char **argv) {
if (argc < 5) {
fprintf(stderr,
"USAGE: %s data_file label_file outer_iterations thread_count",
argv[0]);
exit(1);
}
char *data_file_name = argv[1], *label_file_name = argv[2];
int outer_iterations = atoi(argv[3]);
int thread_count = atoi(argv[4]);
omp_set_num_threads(thread_count);
struct data *data = read_data(data_file_name);
struct labels *label = read_labels(label_file_name);
// NAN CHECK
for (int i = 0; i < data->dimensions * data->rows; i++) {
if (isnan(data->buf[i]))
printf("failed at index %d\n", i);
}
printf("Running %d iteration(s) with %d thread(s).\n", outer_iterations,
thread_count);
FLOAT *w = calloc(data->dimensions, sizeof(FLOAT));
FLOAT *new_w = calloc(data->dimensions, sizeof(FLOAT));
FLOAT *ouais = calloc(data->dimensions * data->rows, sizeof(FLOAT));
for (int iter = 0; iter < outer_iterations; iter++) {
double start_time = monotonic_seconds();
#pragma omp parallel for default(shared)
for (int i = 0; i < data->dimensions; i++) {
// #pragma omp parallel for default(shared)
for (int j = 0; j < data->rows; j++) {
FLOAT x_ni_w_ni = 0;
// #pragma omp parallel for default(shared) reduction(+ : x_ni_w_ni)
for (int i2 = 0; i2 < data->dimensions; i2++) {
if (i2 == i)
continue;
x_ni_w_ni = data->buf[data->rows * i2 + j] * w[i2];
}
ouais[data->rows * i + j] = label->buf[j] - x_ni_w_ni;
}
FLOAT numer = 0, denom = 0;
// #pragma omp parallel for default(shared) reduction(+ : numer, denom)
for (int j = 0; j < data->rows; j++) {
FLOAT xij = data->buf[data->rows * i + j];
numer += xij * ouais[data->rows * i + j];
denom += xij * xij;
}
if (denom == 0) {
new_w[i] = 0;
// printf("wtf? %f\n", numer);
} else
new_w[i] = numer / denom;
}
double end_time = monotonic_seconds();
print_time(end_time - start_time);
printf("Done.\nw = [");
for (int idx = 0; idx < data->dimensions; idx++) {
w[idx] = new_w[idx];
printf("%.3f ", w[idx]);
}
printf("]\n");
// memcpy(w, new_w, data->dimensions * sizeof(FLOAT));
}
free(ouais);
free(new_w);
free(data->buf);
free(label->buf);
free(data);
free(label);
// NOTE: NOT PART OF THE ASSIGNMENT
// Perform testing to ensure that the training actually works
if (argc >= 7) {
struct data *test_data = read_data(argv[5]);
struct labels *test_label = read_labels(argv[6]);
int num_correct = 0;
for (int j = 0; j < test_data->rows; j++) {
FLOAT output = 0;
for (int i = 0; i < test_data->dimensions; i++) {
output += test_data->buf[test_data->rows * i + j] * w[i];
}
// printf("expected: %f, actual: %f\n", test_label->buf[j], output);
FLOAT correct_answer = test_label->buf[j];
FLOAT incorrect_answer = -correct_answer;
if (fabs(output - correct_answer) < fabs(output - incorrect_answer))
num_correct += 1;
}
printf("num correct: %d, out of %d (%.2f%%)\n", num_correct,
test_data->rows, (100.0 * num_correct) / test_data->rows);
}
free(w);
return 0;
}