jacobian

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 757192251eee3763c010b0bfb80b2912eaf0f2ca
parent c0c5b322018a181d57415988386354a530a47591
Author: David Freifeld <freifeld.david@gmail.com>
Date:   Mon, 21 Sep 2020 10:40:30 -0700

Migrating network to 3x faster file read

Diffstat:
Msrc/bpnn.cpp | 8++++----
Msrc/bpnn.hpp | 8++++----
Msrc/data.cpp | 43++++++++++++++++++++++++++++---------------
Msrc/utils.cpp | 14++++++++++++++
Msrc/utils.hpp | 2+-
5 files changed, 51 insertions(+), 24 deletions(-)

diff --git a/src/bpnn.cpp b/src/bpnn.cpp @@ -74,8 +74,8 @@ Network::Network(char* path, int batch_sz, float learn_rate, float bias_rate, Re { int total_instances = prep_file(path, SHUFFLED_PATH); val_instances = split_file(SHUFFLED_PATH, total_instances, ratio); - data = fopen(TRAIN_PATH, "r"); - val_data = fopen(VAL_PATH, "r"); + data = open(TRAIN_PATH, O_RDONLY & O_NONBLOCK); + val_data = open(VAL_PATH, O_RDONLY & O_NONBLOCK); instances = total_instances - val_instances; assert(batch_size > 0 || batch_size < instances); decay = [this]() -> void {}; @@ -363,7 +363,7 @@ float Network::validate(char* path) } val_acc = 1.0/(static_cast<float>(val_instances/batch_size)) * accsum; val_cost = 1.0/(static_cast<float>(val_instances/batch_size)) * costsum; - rewind(val_data); + val_data = open(VAL_PATH, O_RDONLY & O_NONBLOCK); return 0; } @@ -386,7 +386,7 @@ void Network::train() validate(VAL_PATH); if (silenced == false) printf("Epoch %i complete - cost %f - acc %f - val_cost %f - val_acc %f\n", epochs, epoch_cost, epoch_acc, val_cost, val_acc); batches=1; - rewind(data); + data = open(TRAIN_PATH, O_RDONLY & O_NONBLOCK); decay(); epochs++; } diff --git a/src/bpnn.hpp b/src/bpnn.hpp @@ -15,6 +15,7 @@ #include <random> #include <algorithm> +#define BUFFER_SIZE 16*1024 enum Regularization {L1, L2}; class Layer { @@ -39,10 +40,10 @@ public: class Network { public: - FILE* data; - FILE* val_data; - FILE* test_data; + int data; + int val_data; int instances; + char buf[BUFFER_SIZE + 1]; int val_instances; int test_instances; Eigen::MatrixXf numerical_grad(int i, float epsilon); @@ -94,7 +95,6 @@ public: float validate(char* path); void train(); - float get_acc() {return epoch_acc;} float get_val_acc() {return val_acc;} float get_cost() {return epoch_cost;} diff --git a/src/data.cpp b/src/data.cpp @@ -1,22 +1,35 @@ int Network::next_batch() { - char line[MAXLINE] = {' '}; - int inputs = layers[0].contents->cols(); - int datalen = batch_size * inputs; - float batch[datalen]; - for (int i = 0; i < batch_size; i++) { - fgets(line, MAXLINE, data); - char *p; - p = strtok(line,","); - for (int j = 0; j < inputs; j++) { - batch[j + (i * inputs)] = strtod(p, NULL); - p = strtok(NULL,","); + uintmax_t lines = 0 + while(size_t bytes_read = read(fd, buf, BUFFER_SIZE)) + { + if (!bytes_read) break; + for(char *p = buf; lines < 10;) { + char* bound = (char*) memchr(p, '\n', (buf + bytes_read) - p); + if (bound - p < 0) break; // Stop. + for (int i=0; i<layers[0].contents->cols(); ++i) (*layers[0].contents)(lines,i) = scan(&p); + labels (lines,0) = scan(&p); + p = bound + 1; + ++lines; } - (*labels)(i, 0) = strtod(p, NULL); } - float* batchptr = batch; - update_layer(batchptr, datalen, 0); - return 0; + // char line[MAXLINE]; + // int inputs = layers[0].contents->cols(); + // int datalen = batch_size * inputs; + // float batch[datalen]; + // for (int i = 0; i < batch_size; i++) { + // fgets(line, MAXLINE, data); + // char *p; + // p = strtok(line,","); + // for (int j = 0; j < inputs; j++) { + // batch[j + (i * inputs)] = strtod(p, NULL); + // p = strtok(NULL,","); + // } + // (*labels)(i, 0) = strtod(p, NULL); + // } + // float* batchptr = batch; + // update_layer(batchptr, datalen, 0); + // return 0; } int prep_file(char* path, char* out_path) diff --git a/src/utils.cpp b/src/utils.cpp @@ -88,6 +88,20 @@ std::function<float(float)> rectifier(float (*activation)(float)) return rectified; } +typedef float val_t; +inline float scan(char **p) +{ + float n; + int neg = 1; + while (!isdigit(**p) && **p != '-' && **p != '.') ++*p; + if (**p == '-') neg = -1, ++*p; + for (n=0; isdigit(**p); ++*p) (n *= 10) += (**p-'0'); + if (*(*p)++ != '.') return n*neg; + float d = 1; + for (; isdigit(**p); ++*p) n += (d /= 10) * (**p-'0'); + return n*neg; +} + #if (AVX) // Intel intrinsics for the win! Eigen::MatrixXf avx_product(Eigen::MatrixXf a, Eigen::MatrixXf b) diff --git a/src/utils.hpp b/src/utils.hpp @@ -46,7 +46,7 @@ Eigen::MatrixXf avx_cpow(Eigen::MatrixXf m, float exponent); Eigen::MatrixXf avx_tanh(Eigen::MatrixXf m); Eigen::MatrixXf avx_cosh(Eigen::MatrixXf m); - +inline float scan(char **p); Eigen::MatrixXf strassen_mul(Eigen::MatrixXf a, Eigen::MatrixXf b); #endif /* MODULE_H */