diff options
| author | Your Name <[email protected]> | 2026-07-30 12:36:31 -0700 |
|---|---|---|
| committer | Your Name <[email protected]> | 2026-07-30 12:36:31 -0700 |
| commit | f4854ae4c816a7718c88b3b0d230c24786553f26 (patch) | |
| tree | 961026865725518e3f85ace350cdc8db75588f43 /src/read_crossbar.c | |
| parent | 09c8f740da0b833c08c78fa30f80e3dc04e218c4 (diff) | |
SPICE crossbar readout layer
Diffstat (limited to 'src/read_crossbar.c')
| -rw-r--r-- | src/read_crossbar.c | 301 |
1 files changed, 204 insertions, 97 deletions
diff --git a/src/read_crossbar.c b/src/read_crossbar.c index 3666d53..b075c69 100644 --- a/src/read_crossbar.c +++ b/src/read_crossbar.c @@ -3,6 +3,7 @@ #include <ctype.h> #include <errno.h> //maybe I could use this #include <fcntl.h> +#include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -10,123 +11,229 @@ #include <sys/wait.h> #include <unistd.h> -int run_ngspice(const char *crossbar_path) { - if (crossbar_path == NULL) { - fprintf(stderr, "One of the file paths returned null when running ngspice"); - return -1; - } +int run_ngspice(const char *crossbar_path) +{ + if (crossbar_path == NULL) { + fprintf( + stderr, + "One of the file paths returned null when running ngspice"); + return -1; + } - char command[4096]; - int written = snprintf(command, sizeof(command), - "ngspice -b \"%s\" > /dev/null 2>&1", crossbar_path); - - if (written < 0) { - fprintf(stderr, "Failed to write spice command"); - return -1; - } + char command[4096]; + int written = + snprintf(command, sizeof(command), + "ngspice -b \"%s\" > /dev/null 2>&1", crossbar_path); - int status = system(command); - if (status < 0) { - fprintf(stderr, "Failed to run ngspice command"); - } + if (written < 0) { + fprintf(stderr, "Failed to write spice command"); + return -1; + } - return 0; + int status = system(command); + if (status < 0) { + fprintf(stderr, "Failed to run ngspice command"); + } + + return 0; } 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"); - return -1; - } + Crossbar_Output_Matrix *result) +{ + + FILE *file = fopen(data_path, "r"); + if (!file) { + fprintf(stderr, "Faile to open data file"); + return -1; + } + + result->num_samples = 0; + result->num_outputs = num_outputs; + result->time = NULL; + result->voltages = NULL; + + size_t capacity = 100000; + + 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"); + fclose(file); + free_crossbar_output_matrix(result); + return -1; + } + + char line[16384]; + // size_t line_number = 0; + + while (fgets(line, sizeof(line), file) != NULL) { + /* Raises capacity if needed, not working rn tho */ + // if (result->num_samples == capacity) { + // capacity *= 2; + // + // result->time = realloc(result->time, capacity * + // sizeof(double)); result->voltages = + // realloc(result->voltages, capacity * sizeof(double)); + // + // if (result->time == NULL || result->voltages == NULL) { + // fprintf(stderr, "Failed to reallocate memory"); + // fclose(file); + // return -1; + // } + // } + + 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; + int char_count; + + if (sscanf(position, "%lf %lf %n", &time, &voltage, + &char_count) != 2) { + fprintf(stderr, "invalide data line"); + fclose(file); + return -1; + } + + if (output == 0) { + sample_time = time; + } + + result->voltages[result->num_samples * num_outputs + + output] = voltage; + position += char_count; + } + result->time[result->num_samples] = sample_time; + result->num_samples++; + } + fclose(file); + return 0; +} + +int convert_output_to_software(size_t num_neurons, size_t num_outputs, + size_t num_timesteps, const double *voltages, + const double *resistances, + double load_resistance, + const conductance_mapping *mapping, + const double *row_voltages, + double spike_amplitude, double *decoded_outputs) +{ + // Using differential pair mapping + size_t num_physical_columns; + + if (!voltages || !resistances || !mapping || !decoded_outputs) + return -1; + + if (load_resistance <= 0.0 || mapping->alpha == 0.0 || + spike_amplitude == 0.0) + return -1; + + num_physical_columns = num_outputs * 2; + + for (size_t timestep = 0; timestep < num_timesteps; timestep++) { + for (size_t output = 0; output < num_outputs; output++) { + size_t positive_column; + size_t negative_column; + size_t positive_voltage_index; + size_t negative_voltage_index; + size_t output_index; + double positive_conductance_sum = 0.0; + double negative_conductance_sum = 0.0; + double positive_voltage; + double negative_voltage; + double positive_load_current; + double negative_load_current; + double positive_source_current; + double negative_source_current; + + positive_column = 2 * output; + negative_column = positive_column + 1; + + for (size_t neuron = 0; neuron < num_neurons; + neuron++) { + size_t positive_resistance_index; + size_t negative_resistance_index; + + positive_resistance_index = + neuron * num_physical_columns + + positive_column; + + negative_resistance_index = + neuron * num_physical_columns + + negative_column; + + positive_conductance_sum += + 1.0 / + resistances[positive_resistance_index]; - result->num_samples = 0; - result->num_outputs = num_outputs; - result->time = NULL; - result->voltages = NULL; + negative_conductance_sum += + 1.0 / + resistances[negative_resistance_index]; + } - size_t capacity = 100000; + positive_voltage_index = + timestep * num_physical_columns + positive_column; - 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; - } + negative_voltage_index = + timestep * num_physical_columns + negative_column; - 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"); - fclose(file); - free_crossbar_output_matrix(result); - return -1; - } + positive_voltage = voltages[positive_voltage_index]; - char line[16384]; - // size_t line_number = 0; + negative_voltage = voltages[negative_voltage_index]; - while(fgets(line, sizeof(line), file) != NULL) { - /* Raises capacity if needed, not working rn tho */ - // if (result->num_samples == capacity) { - // capacity *= 2; - // - // result->time = realloc(result->time, capacity * sizeof(double)); - // result->voltages = realloc(result->voltages, capacity * sizeof(double)); - // - // if (result->time == NULL || result->voltages == NULL) { - // fprintf(stderr, "Failed to reallocate memory"); - // fclose(file); - // return -1; - // } - // } + positive_load_current = + positive_voltage / load_resistance; - char *position = line; - double sample_time = 0.0; + negative_load_current = + negative_voltage / load_resistance; - //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; - int char_count; + positive_source_current = + positive_load_current + + positive_voltage * positive_conductance_sum; - if(sscanf(position, "%lf %lf %n", &time, &voltage, &char_count) != 2) { - fprintf(stderr, "invalide data line"); - fclose(file); - return -1; - } + negative_source_current = + negative_load_current + + negative_voltage * negative_conductance_sum; - if (output == 0) { - sample_time = time; - } + output_index = timestep * num_outputs + output; - result->voltages[result->num_samples * num_outputs + output] = voltage; - position += char_count; + decoded_outputs[output_index] = + (positive_source_current - + negative_source_current) / + (mapping->alpha * spike_amplitude); + } + } - } - result->time[result->num_samples] = sample_time; - result->num_samples++; - } - fclose(file); - return 0; + return 0; } -void free_crossbar_output_matrix(Crossbar_Output_Matrix *result) { - if (result == NULL) { - return; - } +void free_crossbar_output_matrix(Crossbar_Output_Matrix *result) +{ + if (result == NULL) { + return; + } - free(result->time); - free(result->voltages); + free(result->time); + free(result->voltages); - result->num_samples = 0; - result->num_outputs = 0; - result->time = NULL; - result->voltages = NULL; + result->num_samples = 0; + result->num_outputs = 0; + result->time = NULL; + result->voltages = NULL; } |
