summaryrefslogtreecommitdiff
path: root/src/read_crossbar.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/read_crossbar.c')
-rw-r--r--src/read_crossbar.c113
1 files changed, 69 insertions, 44 deletions
diff --git a/src/read_crossbar.c b/src/read_crossbar.c
index 5b79233..0825147 100644
--- a/src/read_crossbar.c
+++ b/src/read_crossbar.c
@@ -1,19 +1,18 @@
#include "read_crossbar.h"
-#include <stdbool.h>
#include <ngspice/sharedspice.h>
+#include <stdbool.h>
#include <sched.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int run_ngspice(const char *crossbar_path)
{
- if (crossbar_path == NULL) {
- fprintf(
- stderr,
- "One of the file paths returned null when running ngspice");
+ if (!crossbar_path) {
+ fprintf(stderr, "Crossbar path is required\n");
return -1;
}
@@ -22,14 +21,15 @@ int run_ngspice(const char *crossbar_path)
snprintf(command, sizeof(command),
"ngspice -b \"%s\" > /dev/null 2>&1", crossbar_path);
- if (written < 0) {
- fprintf(stderr, "Failed to write spice command");
+ if (written < 0 || (size_t)written >= sizeof(command)) {
+ fprintf(stderr, "Could not construct ngspice command\n");
return -1;
}
int status = system(command);
- if (status < 0) {
- fprintf(stderr, "Failed to run ngspice command");
+ if (status != 0) {
+ fprintf(stderr, "ngspice command failed\n");
+ return -1;
}
return 0;
@@ -38,50 +38,68 @@ int run_ngspice(const char *crossbar_path)
int read_crossbar(const char *data_path, size_t num_outputs,
Crossbar_Output_Matrix *result)
{
-
- FILE *file = fopen(data_path, "r");
- if (!file) {
- fprintf(stderr, "Faile to open data file");
+ if (!data_path || num_outputs == 0 || !result) {
return -1;
}
- // result->num_samples = 0;
- // result->num_outputs = num_outputs;
result->time = NULL;
result->voltages = NULL;
- size_t capacity = 100000;
+ FILE *file = fopen(data_path, "r");
+ if (!file) {
+ fprintf(stderr, "Failed to open crossbar data file\n");
+ return -1;
+ }
+
+ size_t capacity = 1024;
+ if (num_outputs > SIZE_MAX / capacity ||
+ capacity * num_outputs > SIZE_MAX / sizeof(*result->voltages)) {
+ fclose(file);
+ return -1;
+ }
result->time = malloc(capacity * sizeof(*result->time));
result->voltages =
malloc(capacity * num_outputs * sizeof(*result->voltages));
if (result->time == NULL || result->voltages == NULL) {
- fprintf(stderr, "Failed to allocate memory for results");
- fclose(file);
- free_crossbar_output_matrix(result);
- return -1;
- }
-
- size_t expected_fields = num_outputs * 2;
- double *fields = malloc(expected_fields * sizeof(*fields));
- if (fields == NULL) {
- fprintf(stderr, "failed to allocate memory for fields");
+ fprintf(stderr, "Failed to allocate crossbar results\n");
fclose(file);
free_crossbar_output_matrix(result);
return -1;
}
char line[16384];
- // size_t line_number = 0;
-
size_t sample = 0;
while (fgets(line, sizeof(line), file) != NULL) {
+ if (sample == capacity) {
+ if (capacity > SIZE_MAX / 2 ||
+ capacity * 2 > SIZE_MAX / num_outputs ||
+ capacity * 2 * num_outputs >
+ SIZE_MAX / sizeof(*result->voltages)) {
+ goto fail;
+ }
+ capacity *= 2;
+
+ double *new_times = realloc(
+ result->time, capacity * sizeof(*result->time));
+ if (!new_times) {
+ goto fail;
+ }
+ result->time = new_times;
+
+ double *new_voltages = realloc(
+ result->voltages,
+ capacity * num_outputs * sizeof(*result->voltages));
+ if (!new_voltages) {
+ goto fail;
+ }
+ result->voltages = new_voltages;
+ }
+
char *position = line;
double sample_time = 0.0;
- // each loop reads one time-voltage pair, saves it
- // then moves to next loop (next time-voltage pair)
for (size_t output = 0; output < num_outputs; output++) {
double time;
double voltage;
@@ -89,9 +107,10 @@ int read_crossbar(const char *data_path, size_t num_outputs,
if (sscanf(position, "%lf %lf %n", &time, &voltage,
&char_count) != 2) {
- fprintf(stderr, "invalide data line");
- fclose(file);
- return -1;
+ fprintf(stderr,
+ "Invalid crossbar data at sample %zu\n",
+ sample);
+ goto fail;
}
if (output == 0) {
@@ -105,8 +124,16 @@ int read_crossbar(const char *data_path, size_t num_outputs,
result->time[sample] = sample_time;
sample++;
}
- fclose(file);
+ if (ferror(file) || fclose(file) != 0) {
+ free_crossbar_output_matrix(result);
+ return -1;
+ }
return 0;
+
+fail:
+ fclose(file);
+ free_crossbar_output_matrix(result);
+ return -1;
}
int convert_output_to_software(size_t num_neurons, size_t num_outputs,
@@ -117,17 +144,19 @@ int convert_output_to_software(size_t num_neurons, size_t num_outputs,
const double *row_voltages,
double spike_amplitude, double *decoded_outputs)
{
- // Using differential pair mapping
- size_t num_physical_columns;
+ (void)row_voltages;
- if (!voltages || !resistances || !mapping || !decoded_outputs)
+ if (num_neurons == 0 || num_outputs == 0 || num_timesteps == 0 ||
+ !voltages || !resistances || !mapping || !decoded_outputs) {
return -1;
+ }
if (load_resistance <= 0.0 || mapping->alpha == 0.0 ||
- spike_amplitude == 0.0)
+ spike_amplitude == 0.0) {
return -1;
+ }
- num_physical_columns = num_outputs * 2;
+ size_t num_physical_columns = num_outputs * 2;
for (size_t timestep = 0; timestep < num_timesteps; timestep++) {
for (size_t output = 0; output < num_outputs; output++) {
@@ -177,12 +206,10 @@ int convert_output_to_software(size_t num_neurons, size_t num_outputs,
timestep * num_physical_columns + negative_column;
positive_voltage = voltages[positive_voltage_index];
-
negative_voltage = voltages[negative_voltage_index];
positive_load_current =
positive_voltage / load_resistance;
-
negative_load_current =
negative_voltage / load_resistance;
@@ -208,15 +235,13 @@ int convert_output_to_software(size_t num_neurons, size_t num_outputs,
void free_crossbar_output_matrix(Crossbar_Output_Matrix *result)
{
- if (result == NULL) {
+ if (!result) {
return;
}
free(result->time);
free(result->voltages);
- // result->num_samples = 0;
- // result->num_outputs = 0;
result->time = NULL;
result->voltages = NULL;
}