# public api ## benchmark.c The public API for running crossbar simulation, calculating performance metrics, and generating plots. * **MemModel struct** * This is a struct for making model swapping easier * members * const char *model_path * const char *subcircuit_name * **run_benchmark() (int)** * Executes the offline crossbar pipeline. It generates a batch netlist from a previously collected state matrix, launches the ngspice executable, reads the output file, and stores the decoded predictions in the output array. * parameters * const spires_reservoir_config *config * spires_reservoir *reservoir * Reservoir_State_Matrix *state_matrix * const char *model_path * const char *subcircuit_name * double *predictions_out * **run_online_benchmark() (int)** * Steps SPIRES once per input, streams each live reservoir state to a persistent shared-ngspice crossbar, and stores the one-step-delayed decoded predictions in the output array. * parameters * const spires_reservoir_config *config * spires_reservoir *reservoir * const double *input_series * size_t num_timesteps * const char *model_path * const char *subcircuit_name * double *predictions_out * **calculate_MSE() (double)** * calculates the mean squared error of the predictions against the expected values * parameters * const double *expected * const double *predicted * const size_t *num_steps * const size_t num_outputs * **plot_raster() (int)** * generates a raster plot of the reservoir based on the spike threshhold parameter (not that useful tbh but can be cool to see), plot stored as svg in output directory * parameters * const Reservoir_State_Matrix *matrix * const size_t neurons_to_plot * const double spike_threshold * **plot_reservoir_predictions() (int)** * plots the decoded crossbar predictions against the expected values, plot stored as svg in output directory with name "reservoir_prediction_$(model_name).svg" * parameters * const double *expected * const double *predicted * size_t num_samples * size_t num_outputs * size_t output_to_plot * const char *model_path * **plot_model_delta() (int)** * plots the prediction differences for every timestep between the given model and the fixed resistor baseline * parameters * const double *fixed * const double *model * const size_t num_samples * const size_t num_outputs * const size_t output_to_plot # Internal header files ## crossbar_generator.h Handles generation of the SPICE netlist used to simulate the memristive crossbar. * **Crossbar_Config struct** * Stores the configuration needed to generate a crossbar netlist * members * size_t rows * size_t columns * const double *input_series * size_t num_samples * const double *initial_resistance * double load_resistance * const char *model_path * const char *subcircuit_name * double time_step * double stop_time * int print_state_nodes * **generate_crossbar() (int)** * Generates the SPICE crossbar netlist using the passed Crossbar_Config * parameters * const char *output_filename * const Crossbar_Config *config * **generate_online_crossbar() (int)** * Generates a persistent transient netlist whose row voltages are supplied through shared-ngspice external voltage-source callbacks. * parameters * const char *output_filename * const Crossbar_Config *config ## online_crossbar.h Provides the stateful online readout engine used by `run_online_benchmark()`. The engine owns the shared-ngspice lifecycle, synchronization state, trained weight-to-resistance mapping, bounded state buffer, and decoded result storage. * **Online_Crossbar_Config struct** * Configures the crossbar dimensions, known run length, SPICE timestep, voltage scale, load and device resistance limits, device model, subcircuit, and generated netlist path. * **online_crossbar_init() (int)** * Copies the trained SPIRES readout weights, maps them into differential resistances, allocates the bounded pipeline, and generates the external-source netlist. * **online_crossbar_start() (int)** * Initializes shared-ngspice, loads the netlist, installs the first timestep breakpoint, and starts the transient simulation on the ngspice worker thread. * **online_crossbar_submit() (int)** * Submits `state[t]` with bounded backpressure. Submission `t = 0` reports that no output is ready. Each later submission returns decoded output `t - 1`. * **online_crossbar_finish() (int)** * Waits for and returns the decoded output associated with the final submitted state. * **online_crossbar_destroy() (void)** * Stops a running simulation if necessary, waits for its callbacks to exit, resets shared-ngspice, and releases all synchronization and data storage. The online simulation remains continuous for the full known run length, so stateful memristor models retain their internal state between reservoir timesteps. Explicit SPICE breakpoints guarantee that a result is emitted before the pipeline requests a state that has not yet been published. At most one future state is buffered; slow crossbar evaluation therefore blocks the producer instead of dropping or reordering data. ## spires_interface.h Handles communication between SPIRES and the crossbar simulation, including collecting reservoir states and mapping trained weights to resistances. * **Reservoir_State_Matrix struct** * Stores the collected reservoir states in a flat row-major array * members * size_t num_samples * size_t num_features * double *states * **conductance_mapping struct** * Stores the values used to map software readout weights to crossbar conductances and later decode the crossbar outputs * members * double g_min * double g_max * double alpha * double max_abs_weight * **collect_reservoir_states() (int)** * Runs the input series through the SPIRES reservoir and saves the state of every neuron at every timestep * parameters * spires_reservoir *reservoir * const double *input_series * size_t series_length * Reservoir_State_Matrix *result * **convert_weights_to_resistances() (int)** * Converts the trained SPIRES readout weights into differential-pair resistances for the crossbar * parameters * const spires_reservoir *reservoir * size_t num_neurons * size_t num_outputs * double r_on * double r_off * double **resistances_out * conductance_mapping *mapping * **train_reservoir() (int)** * Wrapper around SPIRES ridge regression training * parameters * spires_reservoir *reservoir * double *input_series * double *target_series * size_t series_length * double lambda * **free_reservoir_state_matrix() (void)** * Frees the memory allocated for a Reservoir_State_Matrix * parameters * Reservoir_State_Matrix *matrix ## read_crossbar.h Handles running ngspice, reading the generated simulation data, and decoding the crossbar voltages back into software predictions. * **Crossbar_Output_Matrix struct** * Stores the output voltages read from the ngspice simulation * members * size_t num_samples * size_t num_outputs * double *time * double *voltages * **run_ngspice() (int)** * Runs ngspice in batch mode on the generated crossbar netlist * parameters * const char *crossbar_path * **read_crossbar() (int)** * Reads the ngspice output data file into a Crossbar_Output_Matrix * parameters * const char *data_path * size_t num_outputs * Crossbar_Output_Matrix *result * **convert_output_to_software() (int)** * Decodes the differential-pair crossbar voltages back into the equivalent software readout predictions * parameters * 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 * **free_crossbar_output_matrix() (void)** * Frees the memory allocated for a Crossbar_Output_Matrix * parameters * Crossbar_Output_Matrix *result