#include #include #include #include #include #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; }