Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions Benchmarks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Benchmarks


## Triadic Memory

Measuring the number of read and write operations performed per second for a large batch of random triples {x,y,z}.
Reading z is usually more efficient than reading y or z.



| language | storage size | n | p | items | write / s | read z / s | read y / s | read x / s | computer system |
|:--------:|:------------:|:-----:|:------:|:--------:|:---------:|:----------:|:-----------:|:----------:|:--------------------:|
| C | 1 bit | 1000 | 10 | 1M | 117000 | 14500 | 12000 | 4300 | Apple M1 16GB (2020) |


## Dyadic Memory

Read and write operations performed per second for a large batch of random associations x->y.


| language | storage size | n | p | items | write / s | read | computer system |
|:--------:|:------------:|:-----:|:------:|:--------:|:---------:|:-------:|:-----------------------:|
| C | 1 bit | 1000 | 10 | 1M | 248000 | 30700 | Apple M1 16GB (2020) |



4 changes: 3 additions & 1 deletion C/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ all:
cc -Ofast temporalmemory.c triadicmemory.c -o /usr/local/bin/temporalmemory
cc -Ofast deeptemporalmemory.c triadicmemory.c -o /usr/local/bin/deeptemporalmemory


cc -Ofast dyadicmemorytest.c triadicmemory.c -o /usr/local/bin/dyadicmemorytest
cc -Ofast triadicmemorytest.c triadicmemory.c -o /usr/local/bin/triadicmemorytest

5 changes: 5 additions & 0 deletions C/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,8 @@ Elementary Temporal Memory algorithm and command line tool wrapper. Depends on t
#### deeptemporalmemory.c

Deep Temporal Memory algorithm and command line tool wrapper. Depends on triadicmemory.c and triadicmemory.h.


#### triadicmemorytest.c and dyadicmemorytest.c

Performance and capacity tests. Results [here](https://github.com/PeterOvermann/TriadicMemory/blob/main/Benchmarks.md)
2 changes: 1 addition & 1 deletion C/deeptemporalmemory.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ deeptemporalmemory.c
Deep Temporal Memory Implementation Template and Command Line Tool Wrapper
https://github.com/PeterOvermann/Writings/blob/main/TriadicMemory.pdf

Copyright (c) 2022 Peter Overmann
Copyright (c) 2022-2024 Peter Overmann

Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the “Software”), to deal in the Software without restriction,
Expand Down
4 changes: 2 additions & 2 deletions C/dyadicmemoryCL.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ dyadicmemoryCL.c
Dyadic Memory Command Line wrapper


Copyright (c) 2022 Peter Overmann
Copyright (c) 2022-2024 Peter Overmann

Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the “Software”), to deal in the Software without restriction,
Expand Down Expand Up @@ -36,7 +36,7 @@ static int VERSIONMAJOR = 2;
static int VERSIONMINOR = 0;


static void print_help()
static void print_help(void)
{
printf("dyadicmemory %d.%d\n\n", VERSIONMAJOR, VERSIONMINOR);
printf("Sparse distributed memory (SDM) for storing associations x->y of sparse binary hypervectors x and y.\n");
Expand Down
49 changes: 22 additions & 27 deletions C/dyadicmemorytest.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,33 +33,31 @@ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "triadicmemory.h"


#define PrintOpsPerSecond printf("%d | ", (int)round((double)items * CLOCKS_PER_SEC / ((double) (clock() - start))) )

int main(int argc, char *argv[])
{
int Nx = 1000; // x dimension
int Ny = 1000; // y dimension
int P = 10; // y sparse population

int size = 100000; // number of items in test data
int iterations = 20;
int items = 100000; // number of items in test data
int iterations = 10;

clock_t start;


int* h = (int *)malloc(items * sizeof(int)); // stores Hamming distances for test set
double meanhammingdistance;

DyadicMemory *T = dyadicmemory_new(Nx, Ny, P);

printf("Dyadic Memory capacity and performance tests\n");
printf("Recall errors are given as the average Hamming distance\n");
printf("Nx = %d, Ny = %d, Py = %d\n\n", Nx, Ny, P);


printf("Dyadic Memory performance and capacity test\n");

SDR **t1 = malloc(size * sizeof(SDR*));
SDR **t2 = malloc(size * sizeof(SDR*));
SDR **out = malloc(size * sizeof(SDR*));
SDR **t1 = malloc(items * sizeof(SDR*));
SDR **t2 = malloc(items * sizeof(SDR*));
SDR **out = malloc(items * sizeof(SDR*));

for (int i = 0; i < size; i++)
for (int i = 0; i < items; i++)
{
t1[i] = sdr_new(Nx);
t2[i] = sdr_new(Ny);
Expand All @@ -68,42 +66,39 @@ int main(int argc, char *argv[])

for ( int iter = 1; iter <= iterations; iter ++)
{
printf("iter %.3d | ", iter);
printf("| iter %.3d | nx=%d | ny=%d | p=%d | %d items | write/sec ", iter, Nx, Ny, P, items);

// create random test data
printf("%d items | ", size);
for (int i = 0; i < size; i++)

for (int i = 0; i < items; i++)
{
t1[i] = sdr_random(t1[i],P);
t2[i] = sdr_random(t2[i],P);
}


// store test data

printf("write ");
start = clock();
for (int i = 0; i < size; i++)
for (int i = 0; i < items; i++)
dyadicmemory_write( T, t1[i], t2[i]);

printf("%.2fs | ", ((double) (clock() - start)) / CLOCKS_PER_SEC);
PrintOpsPerSecond;

// recall test data

printf("read ");
printf("read/sec ");
start = clock();
int h[size];
for (int i = 0; i < size; i++)
for (int i = 0; i < items; i++)
dyadicmemory_read ( T, t1[i], out[i] );

printf("%.2fs | ", ((double) (clock() - start)) / CLOCKS_PER_SEC);
PrintOpsPerSecond;

// calculate hamming distances
for (int i = 0; i < size; i++)
for (int i = 0; i < items; i++)
h[i] = sdr_distance(t2[i], out[i]);
double mh = 0;
for (int i = 0; i < size; i++) mh += h[i];
printf("%.3f err\n", mh/size);

meanhammingdistance = 0; for (int i = 0; i < items; i++) meanhammingdistance += h[i];
printf("%.3f avg dist |\n", meanhammingdistance/items);
}

printf("finished\n");
Expand Down
2 changes: 1 addition & 1 deletion C/temporalmemory.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
temporalmemory.c
Elementary Temporal Memory and Command Line Tool Wrapper

Copyright (c) 2022 Peter Overmann
Copyright (c) 2022-2024 Peter Overmann

Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the “Software”), to deal in the Software without restriction,
Expand Down
40 changes: 27 additions & 13 deletions C/triadicmemory.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
/*
triadicmemory.c

C-language reference implementation of Triadic Memory and related algorithms published in
C-language implementation of Triadic Memory and related algorithms published in

https://github.com/PeterOvermann/Writings/blob/main/TriadicMemory.pdf

This version is based on 1-bit storage locations, as opposed to the reference implementation
which is based on 8-bit memory counters.

Copyright (c) 2022 Peter Overmann
Copyright (c) 2022-2024 Peter Overmann

Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the “Software”), to deal in the Software without restriction,
Expand Down Expand Up @@ -73,7 +77,7 @@ static SDR* binarize (SDR *x, int *response, int pop)



static void srand_init()
static void srand_init(void)
{
static int initialized = 0;
if (! initialized)
Expand Down Expand Up @@ -329,8 +333,8 @@ DyadicMemory *dyadicmemory_new(int nx, int ny, int p)
{
DyadicMemory *D = malloc(sizeof(DyadicMemory));

D->nx = nx; // dimension of nx
D->ny = ny; // dimension of ny
D->nx = nx; // dimension of x
D->ny = ny; // dimension of y
D->p = p; // sparsity target for y

// allocate and initialize nx(nx-1)/2 bit-pair addresses for x
Expand Down Expand Up @@ -363,9 +367,8 @@ void dyadicmemory_write (DyadicMemory *D, SDR *x, SDR *y)
}
}



SDR* dyadicmemory_read (DyadicMemory *D, SDR *x, SDR *y)
static SDR* dm_query (DyadicMemory *D, SDR *x, SDR *y, int p)
{
int* response = (int*)calloc(D->ny, sizeof(int));

Expand All @@ -378,10 +381,21 @@ SDR* dyadicmemory_read (DyadicMemory *D, SDR *x, SDR *y)

}

return binarize(y, response, D->p);
return binarize(y, response, p);
}


SDR* dyadicmemory_read (DyadicMemory *D, SDR *x, SDR *y)
{
return dm_query (D, x, y, D->p);
}

SDR* dyadicmemory_read_p (DyadicMemory *D, SDR *x, SDR *y, int p)
{
return dm_query (D, x, y, p);
}



// ---------- Triadic Memory -- stores triple associations (x,y,z} ----------

Expand All @@ -397,14 +411,14 @@ TriadicMemory *triadicmemory_new3 (int nx, int px, int ny, int py, int nz, int p

TriadicMemory *T = malloc(sizeof(TriadicMemory));

T->nx = nx;
T->nx = nx; // vector dimensions of x, y, and z
T->ny = ny;
T->nz = nz;
T->px = px;
T->px = px; // target sparse populations of x, y, and z
T->py = py;
T->pz = pz;

T->forgetting = 0; // forgetting is an experimental feature, disabled by default
T->forgetting = 0; // random forgetting is an experimental feature, disabled by default

// allocate and initialize the entire storage cube, 1 bit per location
// limitation: malloc may fail for large n, use virtual memory instead in this case
Expand All @@ -414,6 +428,7 @@ TriadicMemory *triadicmemory_new3 (int nx, int px, int ny, int py, int nz, int p
return T;
}


void triadicmemory_write (TriadicMemory *T, SDR *x, SDR *y, SDR *z)
{
int Qx = T->ny * T->nz, Qy = T->nz;
Expand All @@ -427,10 +442,9 @@ void triadicmemory_write (TriadicMemory *T, SDR *x, SDR *y, SDR *z)
}


// the following is not part of the original triadic memory algorithm
// the following is not part of the original triadic memory algorithm and disabled by default
// random forgetting, realized by decrementing the same number of memory locations (but not below zero)
// this has no measurable effect for an almost empty memory
// disabled by default

if (T->forgetting)
{
Expand Down
5 changes: 3 additions & 2 deletions C/triadicmemory.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ triadicmemory.h
C-language reference implementation of Triadic Memory and related algorithms published in
https://github.com/PeterOvermann/Writings/blob/main/TriadicMemory.pdf

Copyright (c) 2022 Peter Overmann
Copyright (c) 2022-2024 Peter Overmann

Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the “Software”), to deal in the Software without restriction,
Expand Down Expand Up @@ -71,7 +71,7 @@ typedef struct
{
byte **C; // pointers to base triangle of half storage "cube"

int nx, ny, // vector dimensions x
int nx, ny, // vector dimensions of x and y
p; // target sparse population of y

} DyadicMemory;
Expand All @@ -81,6 +81,7 @@ DyadicMemory *dyadicmemory_new (int nx, int ny, int p);

void dyadicmemory_write (DyadicMemory *, SDR *, SDR *);
SDR* dyadicmemory_read (DyadicMemory *, SDR *, SDR *);
SDR* dyadicmemory_read_p (DyadicMemory *, SDR *, SDR *, int);



Expand Down
4 changes: 2 additions & 2 deletions C/triadicmemoryCL.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ triadicmemoryCL.c
Triadic Memory Command Line


Copyright (c) 2022 Peter Overmann
Copyright (c) 2022-2024 Peter Overmann

Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the “Software”), to deal in the Software without restriction,
Expand Down Expand Up @@ -37,7 +37,7 @@ static int VERSIONMAJOR = 2;
static int VERSIONMINOR = 0;


static void print_help()
static void print_help(void)
{
printf("triadicmemory %d.%d\n\n", VERSIONMAJOR, VERSIONMINOR);
printf("Sparse distributed memory for storing triple associations {x,y,z} of sparse binary hypervectors.\n");
Expand Down
Loading