summaryrefslogtreecommitdiff
path: root/spires_memristor_sim
diff options
context:
space:
mode:
Diffstat (limited to 'spires_memristor_sim')
-rw-r--r--spires_memristor_sim/README.md24
-rw-r--r--spires_memristor_sim/requirements.txt71
-rw-r--r--spires_memristor_sim/spires_interface.py116
-rw-r--r--spires_memristor_sim/torch_reservoir.py68
4 files changed, 0 insertions, 279 deletions
diff --git a/spires_memristor_sim/README.md b/spires_memristor_sim/README.md
deleted file mode 100644
index e5717b6..0000000
--- a/spires_memristor_sim/README.md
+++ /dev/null
@@ -1,24 +0,0 @@
-# Spires reservoir simulated on memristor crossbar using memTorch
-
-## overview
-### simulation
-Here we are using both memTorch and the Spiresrc libraries working together to simulate
-a spires reservoir on a memristor crossbar. memTorch is acting as the weights, simulating
-at a physics level including device to device differences, conductance drag, etc....
-Spires is acting as the actual reservoir neurons and determining the spikes.
-
-### benchmark
-
-## setup
-
-
-## Goal
-The goal is to able to simulate a spires reservoir on a memristor crossbar using
-a custom memristor spice model(HIL), thus you can run multiple simulations with
-multiple models to compare how each performs using benchmark results.
-
-## task
-The plan right now is to give the cart-pole task for benchmarking.
-
-## metrics
-
diff --git a/spires_memristor_sim/requirements.txt b/spires_memristor_sim/requirements.txt
deleted file mode 100644
index c9b7376..0000000
--- a/spires_memristor_sim/requirements.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-asteval==1.0.9
-asttokens==3.0.1
-contourpy==1.3.3
-cuda-bindings==13.3.1
-cuda-pathfinder==1.5.5
-cuda-toolkit==13.0.2
-cycler==0.12.1
-decorator==5.3.1
-dill==0.4.1
-executing==2.2.1
-filelock==3.29.4
-fonttools==4.63.0
-fsspec==2026.6.0
-ipython==9.15.0
-ipython_pygments_lexers==1.1.1
-jedi==0.20.0
-Jinja2==3.1.6
-joblib==1.5.3
-kiwisolver==1.5.0
-lmfit==1.3.4
-MarkupSafe==3.0.3
-matplotlib==3.11.0
-matplotlib-inline==0.2.2
-memtorch-cpu==1.1.6
-mpmath==1.3.0
-narwhals==2.22.1
-networkx==3.6.1
-numpy==2.5.0
-nvidia-cublas==13.1.1.3
-nvidia-cuda-cupti==13.0.85
-nvidia-cuda-nvrtc==13.0.88
-nvidia-cuda-runtime==13.0.96
-nvidia-cudnn-cu13==9.20.0.48
-nvidia-cufft==12.0.0.61
-nvidia-cufile==1.15.1.6
-nvidia-curand==10.4.0.35
-nvidia-cusolver==12.0.4.66
-nvidia-cusparse==12.6.3.3
-nvidia-cusparselt-cu13==0.8.1
-nvidia-nccl-cu13==2.29.7
-nvidia-nvjitlink==13.0.88
-nvidia-nvshmem-cu13==3.4.5
-nvidia-nvtx==13.0.85
-packaging==26.2
-pandas==3.0.4
-parso==0.8.7
-pexpect==4.9.0
-pillow==12.2.0
-prompt_toolkit==3.0.52
-psutil==7.2.2
-ptyprocess==0.7.0
-pure_eval==0.2.3
-Pygments==2.20.0
-pyparsing==3.3.2
-python-dateutil==2.9.0.post0
-scikit-learn==1.9.0
-scipy==1.18.0
-seaborn==0.13.2
-setuptools==81.0.0
-six==1.17.0
-sklearn==0.0.post12
-stack-data==0.6.3
-sympy==1.14.0
-threadpoolctl==3.6.0
-torch==2.12.1
-torchvision==0.27.1
-traitlets==5.15.1
-triton==3.7.1
-typing_extensions==4.15.0
-uncertainties==3.2.3
-wcwidth==0.8.1
diff --git a/spires_memristor_sim/spires_interface.py b/spires_memristor_sim/spires_interface.py
deleted file mode 100644
index b7e5fff..0000000
--- a/spires_memristor_sim/spires_interface.py
+++ /dev/null
@@ -1,116 +0,0 @@
-import ctypes
-import numpy
-import torch
-import random
-
-LIF_DISCRETE = 0
-
-#load the spires library
-spires_lib = ctypes.CDLL("../spires/lib/libspires.so")
-
-# C signautes for creating reservoir
-spires_lib.create_reservoir.argtypes = [
- ctypes.c_size_t,
- ctypes.c_size_t,
- ctypes.c_size_t,
- ctypes.c_double,
- ctypes.c_double,
- ctypes.c_double,
- ctypes.c_double,
- ctypes.c_double,
- ctypes.c_int,
- ctypes.c_int,
- ctypes.POINTER(ctypes.c_double)
-]
-spires_lib.create_reservoir.restype = ctypes.c_void_p
-
-# C signatures for reservoir destruction
-spires_lib.free_reservoir.argtypes = [ctypes.c_void_p]
-spires_lib.free_reservoir.restype = None
-
-# C signatures for step reservoir function
-spires_lib.update_neuron.argtypes = [
- ctypes.c_void_p, #Pointer to spires reservoir struct
- ctypes.c_int,
- ctypes.c_double,
- ctypes.c_double
-]
-spires_lib.update_neuron.restype = None
-
-# C signatures for get neuron spike function
-spires_lib.read_reservoir_spikes.argtypes = [
- ctypes.c_void_p,
- ctypes.POINTER(ctypes.c_float)
-]
-spires_lib.read_reservoir_spikes.restype = None
-
-def init_spires_reservoir(reservoir_size):
- print("Creating spires reservoir")
-
- neuron_parameters = (ctypes.c_double * 4)(0.0, 1.0, 0.2, 0.5)
- c_neuron_parameters = ctypes.cast(neuron_parameters, ctypes.POINTER(ctypes.c_double))
-
- reservoir_ptr = spires_lib.create_reservoir(
- ctypes.c_size_t(int(reservoir_size)), # num neurons
- ctypes.c_size_t(int(reservoir_size)), # num neurons
- ctypes.c_size_t(2), # num_outputs
- ctypes.c_double(0.9), # spectral radius
- ctypes.c_double(0.8), # ei_ratio
- ctypes.c_double(1.0), # input_strength
- ctypes.c_double(0.1), # connectivity
- ctypes.c_double(1.0), # dt
- ctypes.c_int(1), # connectivity type ( 1 = sparse)
- ctypes.c_int(LIF_DISCRETE), # neuron type
- c_neuron_parameters # neuron params
- )
-
- #allocate empty void pointer, (reservoir will go here)
- if not reservoir_ptr:
- raise RuntimeError(f"Spires faile to initialize the reservoir: {status_code}")
- else:
- print("Spires reservoir initialized")
-
- # reservoir_ptr._keep_alive = neuron_parameters
-
- return reservoir_ptr
-
-def free_spires_reservoir(reservoir_ptr):
- print("Freeing the spires reservoir")
- spires_lib.free_reservoir(reservoir_ptr)
- return 0
-
-
-#change currents from tensor to a flat C pointer array for spires to read
-def send_currents_to_spires(reservoir_ptr, currents_tensor):
- print("Sending currents to spires")
- # ----- extract from pytorhc graph -----
- # .detach() removes it from auto gradient tracking
- # .cpu() make sure data is in RAM, not VRAM
- # .numpy() maps it to numpy array
- # ----- makes suren layout matches 64 bit double C-array -----
- # .astype(npfloat64) forces standard CC float precistion
- # .flatten() makes sure the memory is a 1D block
- numpy_array = currents_tensor.detach().cpu().numpy().astype(numpy.float64).flatten()
-
- some_ptr = ctypes.cast(reservoir_ptr, ctypes.POINTER(ctypes.POINTER(ctypes.c_void_p)))
-
- neurons_array = some_ptr[0]
-
- print("updating the neurons")
- for i in range(len(numpy_array)):
- neuron_ptr = neurons_array[i]
- input_current = numpy_array[i]
-
- spires_lib.update_neuron(neuron_ptr, LIF_DISCRETE, input_current, 1.0)
-
- return numpy_array
-
-def read_spikes_from_spires(reservoir_ptr, size=0):
- print("Recieved spikes from spires")
- #didnt do any safety checking womp womp
- returned_spikes = numpy.zeros(size, dtype=numpy.float64)
- c_spike_ptr = returned_spikes.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
-
- spires_lib.read_reservoir_spikes(reservoir_ptr, c_spike_ptr)
-
- return returned_spikes
diff --git a/spires_memristor_sim/torch_reservoir.py b/spires_memristor_sim/torch_reservoir.py
deleted file mode 100644
index 9d58d43..0000000
--- a/spires_memristor_sim/torch_reservoir.py
+++ /dev/null
@@ -1,68 +0,0 @@
-import torch
-import memtorch
-from spires_interface import (
- free_spires_reservoir,
- init_spires_reservoir,
- send_currents_to_spires,
- read_spikes_from_spires,
-)
-
-NUM_INPUTS = 4
-NUM_OUTPUTS = 4
-NUM_NEURONS = 800
-
-input_layer = torch.nn.Linear(NUM_INPUTS, NUM_NEURONS, bias=False)
-#this is a recurrent layer sort of???
-reservoir_layer = torch.nn.Linear(NUM_NEURONS, NUM_NEURONS, bias=False)
-readout_layer = torch.nn.Linear(NUM_NEURONS, NUM_OUTPUTS, bias=False)
-
-spires_reservoir = init_spires_reservoir(NUM_NEURONS)
-
-#make the reservoir sparse and random
-with torch.no_grad():
- reservoir_layer.weight.data.normal_(0.0, 0.5) #random weight
-
- #mask so 10% of connections exist
- mask = (torch.rand(NUM_NEURONS, NUM_NEURONS) < 0.10).float()
- reservoir_layer.weight.data *= mask
-
-# patch layers into memristor crossbars with memTorch
-memristor_model = memtorch.bh.memristor.VTEAM
-memristor_model_params = {
- 'time_series_resolution': 1e-3,
- 'r_on': 50,
- 'r_off': 1000,
-}
-
-mem_input_layer = memtorch.mn.Module.patch_model(
- input_layer,
- memristor_model,
- memristor_model_params,
-)
-
-mem_reservoir_layer = memtorch.mn.Module.patch_model(
- reservoir_layer,
- memristor_model,
- memristor_model_params,
-)
-
-#run spiking loop with spires
-previous_spikes = torch.zeros(1, NUM_NEURONS)
-for step in range(500):
- cartpole_state = [0, 1, 2, 3] #this isn't final
- input_tensor = torch.tensor(cartpole_state).float().unsqueeze(0)
- currents_in = mem_input_layer(input_tensor)
-
- currents_recv = mem_reservoir_layer(previous_spikes)
-
- #may need to scale currents?
- total_currents = currents_in + currents_recv
-
- send_currents_to_spires(spires_reservoir, total_currents)
-
- current_spikes_np = read_spikes_from_spires(spires_reservoir, NUM_NEURONS)
- previous_spikes = torch.from_numpy(current_spikes_np).float().unsqueeze(0)
-
-free_spires_reservoir(spires_reservoir)
-#pass current spikes np to readout layer
-