diff options
| author | Your Name <[email protected]> | 2026-08-28 17:29:33 -0700 |
|---|---|---|
| committer | Your Name <[email protected]> | 2026-08-28 17:29:33 -0700 |
| commit | 02158c7613495f1a02a2a8f108cd1c397656ce2b (patch) | |
| tree | 5cdd0d716b0ef6ae98375354d952c4cac1670846 /src/online_crossbar.c | |
| parent | 2a3cb69b71539953489752cea5f34e87cdb7814a (diff) | |
cleaned up
Diffstat (limited to 'src/online_crossbar.c')
| -rw-r--r-- | src/online_crossbar.c | 161 |
1 files changed, 113 insertions, 48 deletions
diff --git a/src/online_crossbar.c b/src/online_crossbar.c index b01ea19..ff346bd 100644 --- a/src/online_crossbar.c +++ b/src/online_crossbar.c @@ -8,6 +8,7 @@ #include <ngspice/sharedspice.h> #include <pthread.h> #include <stdbool.h> +#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -32,14 +33,41 @@ struct Online_Crossbar { pthread_cond_t progress; }; +static int config_is_valid(const Online_Crossbar_Config *config) +{ + if (!config || config->num_neurons == 0 || config->num_outputs == 0 || + config->num_timesteps == 0 || !isfinite(config->time_step) || + config->time_step <= 0.0 || !isfinite(config->spike_amplitude) || + config->spike_amplitude == 0.0 || + !isfinite(config->load_resistance) || + config->load_resistance <= 0.0 || !isfinite(config->r_on) || + !isfinite(config->r_off) || config->r_on <= 0.0 || + config->r_off <= config->r_on || !config->model_path || + !config->subcircuit_name || !config->netlist_path) { + return 0; + } + + if (config->num_outputs > SIZE_MAX / 2 || + config->num_neurons > SIZE_MAX / 2 || + config->num_timesteps > SIZE_MAX / config->num_outputs || + config->num_timesteps * config->num_outputs > + SIZE_MAX / sizeof(double)) { + return 0; + } + + double stop_time = config->num_timesteps * config->time_step; + return isfinite(stop_time) && stop_time > 0.0; +} + static int callback_text(char *text, int ident, void *user_data) { (void)ident; (void)user_data; if (text && (strncmp(text, "stderr", 6) == 0 || strstr(text, "Error") != NULL || - strstr(text, "error") != NULL)) + strstr(text, "error") != NULL)) { fprintf(stderr, "ngspice: %s\n", text); + } return 0; } @@ -77,12 +105,14 @@ static int callback_background(NG_BOOL running, int ident, void *user_data) (void)ident; Online_Crossbar *crossbar = user_data; /* libngspice passes false at worker start and true at worker exit. */ - if (!running) + if (!running) { return 0; + } pthread_mutex_lock(&crossbar->mutex); crossbar->simulation_done = 1; - if (crossbar->result_count < crossbar->config.num_timesteps) + if (crossbar->result_count < crossbar->config.num_timesteps) { fail_locked(crossbar); + } pthread_cond_broadcast(&crossbar->progress); pthread_cond_broadcast(&crossbar->state_available); pthread_mutex_unlock(&crossbar->mutex); @@ -92,28 +122,33 @@ static int callback_background(NG_BOOL running, int ident, void *user_data) static int row_from_name(const char *name, size_t *row_out) { const char *digits = name + strlen(name); - while (digits > name && isdigit((unsigned char)digits[-1])) + while (digits > name && isdigit((unsigned char)digits[-1])) { digits--; - if (*digits == '\0') + } + if (*digits == '\0') { return -1; + } char *end = NULL; unsigned long value = strtoul(digits, &end, 10); - if (end == digits || *end != '\0') + if (end == digits || *end != '\0') { return -1; + } *row_out = (size_t)value; return 0; } static size_t timestep_for_time(const Online_Crossbar *crossbar, double time) { - if (time <= 0.0) + if (time <= 0.0) { return 0; + } double scaled = time / crossbar->config.time_step; /* Hold state[t] over the full interval (t*dt, (t+1)*dt]. */ double interval = ceil(scaled - 1.0e-9); size_t timestep = interval <= 1.0 ? 0 : (size_t)interval - 1; - if (timestep >= crossbar->config.num_timesteps) + if (timestep >= crossbar->config.num_timesteps) { timestep = crossbar->config.num_timesteps - 1; + } return timestep; } @@ -132,8 +167,9 @@ static int callback_voltage(double *voltage, double time, char *name, int ident, size_t timestep = timestep_for_time(crossbar, time); pthread_mutex_lock(&crossbar->mutex); - while (!crossbar->failed && crossbar->published_count <= timestep) + while (!crossbar->failed && crossbar->published_count <= timestep) { pthread_cond_wait(&crossbar->state_available, &crossbar->mutex); + } if (crossbar->failed) { pthread_mutex_unlock(&crossbar->mutex); return 1; @@ -178,8 +214,9 @@ static int callback_data(pvecvaluesall values, int count, int ident, continue; } const char *col = strstr(value->name, "col"); - if (!col) + if (!col) { continue; + } char *end = NULL; unsigned long index = strtoul(col + 3, &end, 10); if (end != col + 3 && @@ -197,8 +234,9 @@ static int callback_data(pvecvaluesall values, int count, int ident, size_t timestep = (size_t)rounded - 1; int complete = 1; for (size_t i = 0; i < crossbar->config.num_outputs * 2; - i++) + i++) { complete = complete && found[i]; + } if (complete) { double *decoded = crossbar->results + @@ -213,14 +251,16 @@ static int callback_data(pvecvaluesall values, int count, int ident, decoded) == 0) { pthread_mutex_lock(&crossbar->mutex); if (crossbar->result_count < - timestep + 1) + timestep + 1) { crossbar->result_count = timestep + 1; + } if (timestep + 1 < - crossbar->config.num_timesteps) + crossbar->config.num_timesteps) { ngSpice_SetBkpt( (timestep + 2) * crossbar->config.time_step); + } pthread_cond_broadcast( &crossbar->progress); pthread_mutex_unlock(&crossbar->mutex); @@ -238,38 +278,44 @@ int online_crossbar_init(const Online_Crossbar_Config *config, const spires_reservoir *reservoir, Online_Crossbar **crossbar_out) { - if (!config || !reservoir || !crossbar_out || - config->num_neurons == 0 || config->num_outputs == 0 || - config->num_timesteps == 0 || config->time_step <= 0.0 || - config->spike_amplitude == 0.0 || config->load_resistance <= 0.0 || - !config->model_path || !config->subcircuit_name || - !config->netlist_path) + if (!crossbar_out) { return -1; + } + *crossbar_out = NULL; + if (!reservoir || !config_is_valid(config)) { + return -1; + } Online_Crossbar *crossbar = calloc(1, sizeof(*crossbar)); - if (!crossbar) + if (!crossbar) { return -1; + } crossbar->config = *config; - if (pthread_mutex_init(&crossbar->mutex, NULL) != 0) + if (pthread_mutex_init(&crossbar->mutex, NULL) != 0) { goto fail; + } crossbar->mutex_initialized = 1; - if (pthread_cond_init(&crossbar->state_available, NULL) != 0) + if (pthread_cond_init(&crossbar->state_available, NULL) != 0) { goto fail; + } crossbar->state_condition_initialized = 1; - if (pthread_cond_init(&crossbar->progress, NULL) != 0) + if (pthread_cond_init(&crossbar->progress, NULL) != 0) { goto fail; + } crossbar->progress_condition_initialized = 1; crossbar->state_ring = calloc(2 * config->num_neurons, sizeof(double)); crossbar->results = calloc(config->num_timesteps * config->num_outputs, sizeof(double)); - if (!crossbar->state_ring || !crossbar->results) + if (!crossbar->state_ring || !crossbar->results) { goto fail; + } if (convert_weights_to_resistances( reservoir, config->num_neurons, config->num_outputs, config->r_on, config->r_off, &crossbar->resistances, - &crossbar->mapping) != 0) + &crossbar->mapping) != 0) { goto fail; + } Crossbar_Config netlist = {.rows = config->num_neurons, .columns = config->num_outputs * 2, @@ -283,8 +329,9 @@ int online_crossbar_init(const Online_Crossbar_Config *config, .stop_time = config->num_timesteps * config->time_step, .print_state_nodes = 0}; - if (generate_online_crossbar(config->netlist_path, &netlist) != 0) + if (generate_online_crossbar(config->netlist_path, &netlist) != 0) { goto fail; + } *crossbar_out = crossbar; return 0; @@ -296,23 +343,32 @@ fail: int online_crossbar_start(Online_Crossbar *crossbar) { - if (!crossbar || crossbar->started) + if (!crossbar || crossbar->started) { return -1; + } if (ngSpice_Init(callback_text, callback_text, callback_exit, callback_data, callback_init_data, callback_background, - crossbar) != 0 || - ngSpice_Init_Sync(callback_voltage, NULL, NULL, NULL, crossbar) != - 0) + crossbar) != 0) { return -1; + } + if (ngSpice_Init_Sync(callback_voltage, NULL, NULL, NULL, crossbar) != + 0) { + ngSpice_Reset(); + return -1; + } char command[4096]; - if (snprintf(command, sizeof(command), "source %s", - crossbar->config.netlist_path) >= (int)sizeof(command) || - ngSpice_Command(command) != 0) + int written = snprintf(command, sizeof(command), "source %s", + crossbar->config.netlist_path); + if (written < 0 || (size_t)written >= sizeof(command) || + ngSpice_Command(command) != 0) { + ngSpice_Reset(); return -1; + } crossbar->started = 1; ngSpice_SetBkpt(crossbar->config.time_step); if (ngSpice_Command("bg_run") != 0) { + ngSpice_Reset(); crossbar->started = 0; return -1; } @@ -325,12 +381,15 @@ int online_crossbar_submit(Online_Crossbar *crossbar, size_t timestep, { if (!crossbar || !state || !output_ready || !crossbar->started || timestep >= crossbar->config.num_timesteps || - timestep != crossbar->published_count) + timestep != crossbar->published_count || + (timestep != 0 && !previous_output)) { return -1; + } pthread_mutex_lock(&crossbar->mutex); - while (!crossbar->failed && timestep >= crossbar->consumed_count + 2) + while (!crossbar->failed && timestep >= crossbar->consumed_count + 2) { pthread_cond_wait(&crossbar->progress, &crossbar->mutex); + } if (crossbar->failed) { pthread_mutex_unlock(&crossbar->mutex); return -1; @@ -343,13 +402,10 @@ int online_crossbar_submit(Online_Crossbar *crossbar, size_t timestep, *output_ready = timestep != 0; if (timestep != 0) { - if (!previous_output) { - pthread_mutex_unlock(&crossbar->mutex); - return -1; - } - while (!crossbar->failed && crossbar->result_count < timestep) + while (!crossbar->failed && crossbar->result_count < timestep) { pthread_cond_wait(&crossbar->progress, &crossbar->mutex); + } if (crossbar->failed) { pthread_mutex_unlock(&crossbar->mutex); return -1; @@ -366,12 +422,14 @@ int online_crossbar_submit(Online_Crossbar *crossbar, size_t timestep, int online_crossbar_finish(Online_Crossbar *crossbar, double *final_output) { if (!crossbar || !final_output || - crossbar->published_count != crossbar->config.num_timesteps) + crossbar->published_count != crossbar->config.num_timesteps) { return -1; + } pthread_mutex_lock(&crossbar->mutex); while (!crossbar->failed && - crossbar->result_count < crossbar->config.num_timesteps) + crossbar->result_count < crossbar->config.num_timesteps) { pthread_cond_wait(&crossbar->progress, &crossbar->mutex); + } if (crossbar->failed) { pthread_mutex_unlock(&crossbar->mutex); return -1; @@ -386,28 +444,35 @@ int online_crossbar_finish(Online_Crossbar *crossbar, double *final_output) void online_crossbar_destroy(Online_Crossbar *crossbar) { - if (!crossbar) + if (!crossbar) { return; + } if (crossbar->started && ngSpice_running()) { ngSpice_Command("bg_halt"); if (crossbar->mutex_initialized) { pthread_mutex_lock(&crossbar->mutex); - while (!crossbar->simulation_done && ngSpice_running()) + while (!crossbar->simulation_done && + ngSpice_running()) { pthread_cond_wait(&crossbar->progress, &crossbar->mutex); + } pthread_mutex_unlock(&crossbar->mutex); } } - if (crossbar->started) + if (crossbar->started) { ngSpice_Reset(); + } free(crossbar->resistances); free(crossbar->state_ring); free(crossbar->results); - if (crossbar->state_condition_initialized) + if (crossbar->state_condition_initialized) { pthread_cond_destroy(&crossbar->state_available); - if (crossbar->progress_condition_initialized) + } + if (crossbar->progress_condition_initialized) { pthread_cond_destroy(&crossbar->progress); - if (crossbar->mutex_initialized) + } + if (crossbar->mutex_initialized) { pthread_mutex_destroy(&crossbar->mutex); + } free(crossbar); } |
