summaryrefslogtreecommitdiff
path: root/src/spires_interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/spires_interface.c')
-rw-r--r--src/spires_interface.c96
1 files changed, 63 insertions, 33 deletions
diff --git a/src/spires_interface.c b/src/spires_interface.c
index 665defc..df09985 100644
--- a/src/spires_interface.c
+++ b/src/spires_interface.c
@@ -11,49 +11,57 @@ int collect_reservoir_states(spires_reservoir *reservoir,
const double *input_series, size_t series_length,
Reservoir_State_Matrix *result)
{
- // error checking
- // RIP
+ if (!reservoir || !input_series || series_length == 0 || !result) {
+ return -1;
+ }
- // clear the result first
result->num_samples = 0;
result->num_features = 0;
result->states = NULL;
const size_t num_inputs = spires_num_inputs(reservoir);
-
const size_t num_neurons = spires_num_neurons(reservoir);
+ if (num_inputs == 0 || num_neurons == 0) {
+ return -1;
+ }
if (series_length > SIZE_MAX / num_neurons ||
series_length * num_neurons > SIZE_MAX / sizeof(double)) {
- fprintf(stderr, "matrix size overloaded!!");
+ fprintf(stderr, "Reservoir state matrix is too large\n");
return -1;
}
double *states = malloc(num_neurons * series_length * sizeof(*states));
if (!states) {
- fprintf(stderr, "failed to allocate memory for states");
+ fprintf(stderr, "Failed to allocate reservoir state matrix\n");
return -1;
}
spires_status status = spires_reservoir_reset(reservoir);
if (status != SPIRES_OK) {
- fprintf(stderr, "reservoir reset error");
+ fprintf(stderr, "Failed to reset SPIRES reservoir\n");
free(states);
return -1;
}
- // build state_matrix
- for (size_t i = 0; i < series_length; i++) {
- const double *current_input = &input_series[i * num_inputs];
+ for (size_t timestep = 0; timestep < series_length; timestep++) {
+ const double *current_input =
+ input_series + timestep * num_inputs;
status = spires_step(reservoir, current_input);
if (status != SPIRES_OK) {
+ fprintf(stderr, "SPIRES step failed at timestep %zu\n",
+ timestep);
free(states);
return -1;
}
- double *current_state = &states[i * num_neurons];
+ double *current_state = states + timestep * num_neurons;
status = spires_read_reservoir_state(reservoir, current_state);
if (status != SPIRES_OK) {
+ fprintf(
+ stderr,
+ "Failed to read reservoir state at timestep %zu\n",
+ timestep);
free(states);
return -1;
}
@@ -72,29 +80,48 @@ int convert_weights_to_resistances(const spires_reservoir *reservoir,
double **resistances_out,
conductance_mapping *mapping)
{
- double max_abs_weight = 0.0;
+ if (!reservoir || num_neurons == 0 || num_outputs == 0 || r_on <= 0.0 ||
+ r_off <= r_on || !resistances_out || !mapping) {
+ return -1;
+ }
*resistances_out = NULL;
+ if (num_outputs > SIZE_MAX / 2 ||
+ num_neurons > SIZE_MAX / num_outputs) {
+ return -1;
+ }
+
size_t weight_count = num_neurons * num_outputs;
size_t num_physical_columns = num_outputs * 2;
+ if (num_neurons > SIZE_MAX / num_physical_columns ||
+ num_neurons * num_physical_columns > SIZE_MAX / sizeof(double)) {
+ return -1;
+ }
- double *readout = malloc(num_neurons * num_outputs * sizeof(double));
-
- spires_read_readout(reservoir, readout);
+ double *readout = malloc(weight_count * sizeof(*readout));
+ if (!readout) {
+ fprintf(stderr, "Failed to allocate readout weights\n");
+ return -1;
+ }
+ if (spires_read_readout(reservoir, readout) != SPIRES_OK) {
+ fprintf(stderr, "Failed to read SPIRES readout weights\n");
+ free(readout);
+ return -1;
+ }
double *resistances =
- malloc(num_neurons * num_physical_columns * sizeof(double));
- if (resistances == NULL) {
- fprintf(stderr, "Failed to allocated crossbar resistances");
+ malloc(num_neurons * num_physical_columns * sizeof(*resistances));
+ if (!resistances) {
+ fprintf(stderr, "Failed to allocate crossbar resistances\n");
free(readout);
return -1;
}
- // get the max weight
+ double max_abs_weight = 0.0;
for (size_t i = 0; i < weight_count; i++) {
if (!isfinite(readout[i])) {
fprintf(stderr,
- "invalid readout weight at index %zu: %g\n", i,
+ "Invalid readout weight at index %zu: %g\n", i,
readout[i]);
free(readout);
free(resistances);
@@ -106,15 +133,20 @@ int convert_weights_to_resistances(const spires_reservoir *reservoir,
max_abs_weight = abs_weight;
}
}
+ if (max_abs_weight == 0.0) {
+ fprintf(stderr,
+ "Cannot map an all-zero readout to resistances\n");
+ free(readout);
+ free(resistances);
+ return -1;
+ }
mapping->g_min = 1.0 / r_off;
mapping->g_max = 1.0 / r_on;
mapping->max_abs_weight = max_abs_weight;
- // calculate the alpha scaling parameter to normalize the weights
mapping->alpha = (mapping->g_max - mapping->g_min) / max_abs_weight;
- // differential pair mapping
for (size_t neuron = 0; neuron < num_neurons; neuron++) {
for (size_t output = 0; output < num_outputs; output++) {
size_t weight_index = output * num_neurons + neuron;
@@ -133,8 +165,7 @@ int convert_weights_to_resistances(const spires_reservoir *reservoir,
positive_conductance =
mapping->g_min + mapping->alpha * weight;
negative_conductance = mapping->g_min;
- }
- if (weight < 0.0) {
+ } else {
positive_conductance = mapping->g_min;
negative_conductance =
mapping->g_min + mapping->alpha * (-weight);
@@ -146,10 +177,6 @@ int convert_weights_to_resistances(const spires_reservoir *reservoir,
1.0 / negative_conductance;
}
}
- // printf("max absolute weight = %.12e\n", mapping->max_abs_weight);
- // printf("alpha = %.12e\n", mapping->alpha);
- // printf("physical crossbar dimensions: %zu x %zu\n", num_neurons,
- // num_physical_columns);
*resistances_out = resistances;
free(readout);
@@ -160,12 +187,16 @@ int convert_weights_to_resistances(const spires_reservoir *reservoir,
int train_reservoir(spires_reservoir *reservoir, double *input_series,
double *target_series, size_t series_length, double lambda)
{
- spires_status status =
- spires_train_ridge(reservoir, (double *)input_series,
- (double *)target_series, series_length, lambda);
+ if (!reservoir || !input_series || !target_series ||
+ series_length == 0 || lambda < 0.0) {
+ return -1;
+ }
+
+ spires_status status = spires_train_ridge(
+ reservoir, input_series, target_series, series_length, lambda);
if (status != SPIRES_OK) {
- fprintf(stderr, "Spires ridge training failed");
+ fprintf(stderr, "SPIRES ridge training failed\n");
return -1;
}
@@ -179,7 +210,6 @@ void free_reservoir_state_matrix(Reservoir_State_Matrix *matrix)
}
free(matrix->states);
-
matrix->states = NULL;
matrix->num_samples = 0;
matrix->num_features = 0;