Giter VIP home page Giter VIP logo

etaler's Introduction




Etaler is a library for machine intelligence based on HTM theory. Providing two main features.

  • HTM algorithms with modern API
  • A minimal cross-platform (CPU, GPU, etc..) Tensor implementation

You can now explore HTM with modern, easy to use API and enjoy the performance boost by the GPU.

More about Etaler

A GPU ready HTM library

Unlike most previous HTM implementations, Etaler is designed from the ground up to work with GPUs and allows almost seamless data transfer between CPU and GPUs.

Etaler provides HTM algorithms and a minimal Tensor implementation that operates on both CPU and GPU. You can choose what works best for you and switch between them with ease.

Total front-end /back-end separation

Etaler is written in a way that the front-end businesses (Tensor operation calls, HTM APIs, layer save/load) are totally separated from the backend, where all the computation and memory management happens. This allows Etaler to be easily expanded and optimized. Have multiple GPUs? Just spawn multiple GPU backends! Thou shell not need any black-magic.

Why the name?

Etaler is named after the inverse of the word "relate" for no specific reason.

Examples

See the examples folder for more information. For a quick feel on how Etaler works.

Creating and printing a tensor

float arr[] = {1, 2, 3, 4};
Tensor t = Tensor(/*shape=*/{4}
                ,/*data=*/arr);

std::cout << t << std::endl;

Encode a scalar

Tensor t = encoder::scalar(0.1);

Using the GPU

auto gpu = std::make_shared<OpenCLBackend>();
Tensor t = encoder::scalar(0.1);

//Transfer data to GPU
Tensot q = t.to(gpu);

SpatialPooler sp = SpatialPooler(/*Spatial Pooler params here*/).to(gpu);
//SpatialPooler sp(/*Spatial Pooler params here*/, gpu.get()); //Alternativelly
Tensor r = sp.compute(q);

Saving layers

save(sp.states(), "sp.cereal");

Documentation

Documents are avalible online on Read the Docs.

Building and platform support

OS/Backend CPU OpenCL
Linux Yes Yes
OS X Yes Yes
Windows Yes Yes
FreeBSD Yes *Yes
  • Build with GCC and libstdc++ on OS X 10.11.
  • Clang should work after OS X 10.14. See BuildOnOSX.md
  • Build with Visual Studio 2019 on Windows. See BuildOnMSVC.md
  • OpenCL on FreeBSD is tested using POCL. Which has know bugs preventing Etaler to fully function on ARM.

Dependencies

  • Required

  • OpenCL Backend

    • OpenCL and OpenCL C++ wrapper
    • OpenCL 1.2 capable GPU
  • Tests

Notes:

  1. Make sure to setup a TBBROOT environment variable to point to the binary installation directory of TBB. And the TBB tbbvars.sh file has been modified correctly and run, before running cmake.
  2. cereal can be git cloned into the Etaler/Etaler/3rdparty directory.
  3. Only the catch.hpp file is required from Catch2, and that file can be placed into the Etaler/tests directory.

Building from source

Clone the repository. Then after fulfilling the dependencies. Execute cmake and then run whatever build system you're using.

For example, on Linux.

mkdir build
cd build
cmake ..
make -j8

Some cmake options are available:

option description default
CMAKE_BUILD_TYPE Debug or Release build Release
ETALER_ENABLE_OPENCL Enable the OpenCL backend OFF
ETALER_BUILD_EXAMPLES Build the examples ON
ETALER_BUILD_TESTS Build the tests ON
ETALER_BUILD_DOCS Build the documents OFF
ETALER_ENABLE_SIMD Enable SIMD for CPU backend OFF
ETALER_NATIVE_BUILD Enable compiler optimize for the host CPU OFF

There are also packages available for the following distributions:

Building in Docker/VSC

Open the folder in VSC with remote docker extension ( ext install ms-vscode-remote.remote-containers ) - the docker image and container will start automatically. If CMake Tools extension are also installed, the building will be done automaticaly also. Otherwhise, do the regular cmake procedure inside Etaler dir.

LICENSE

Etaler is licensed under BSD 3-Clause License. So use it freely!

Be aware that Numenta holds the rights to HTM related patents. And only allows free (as "free beers" free) use of their patents for non-commercial purpose. If you are using Etaler commercially; please contact Numenta for licensing.
(tl;dr Etaler is free for any purpose. But HTM is not for commercial use.)

Contribution

HTM Theory is in it's young age and as we are growing. We'd like to get contributions from you to accelerate the development of Etaler! Just fork, make changes and launch a PR!

See CONTRIBUTION.md

Notes

  • NVIDIA's OpenCL implementation might not report error correctly. It can execute kernels with a invalid memory object without telling you and crash a random thing the next time. If you are encountering weird behaviors. Please try POCL with the CUDA backend or use an AMD card. However the OpenCL kernels haven't been optimized against vector processors like AMD's. They should work but you might experience performance drops doing so.

  • Due to the nature of HTM. The OpenCL backend uses local memory extensively. And thus you will experience lower than expected performance on processors that uses global memory to emulate local memory. This includes but not limited to (and non of them are tested): ARM Mali GPUs, VideoCore IV GPU, any CPU.

  • By default Etaler saves to a portable binary file. If you want to save your data as JSON, Etaler automatically saves as JSON when you specified a .json file extension. But note that JSON is fat compared to the binary format and grows fast. Make sure you know what you are doing.

  • FPGA based OpenCL are not supported for now. FPGA platforms don't provide online (API callable) compilers that Etaler uses for code generation.

  • DSP/CPU/Xeon Phi based OpenCL should work out of the box. But we didn't test that.

For NuPIC users

Etaler tho provides basically the same feature, is very different from Numenta's NuPIC. Some noticeable ones are:

  • Data Orientated Design instead of Object Orientated
  • No Network API (planned in the future, by another repo)
  • SDR is handled as a Tensor instead of a sparse matrix
  • Swarming is not supported nor planned

Testing

If you have the tests builded. Run tests/etaler_test.

We are still thinking about weather a CI is worth the trouble. C++ projects takes too long to build on most CIs so it drags the development speed.

Cite us

We're happy that you can use the library and are having fun. Please attribute us by linking to etaler at https://github.com/etaler/Etaler. For scientific publications, we suggest the following BibTex citation.

@misc{etaler2019,
	abstract = "Implementation of Hierarchical Temporal Memory and related algorithms in C++ and OpenCL",
	author = "An-Pang Clang",
	commit = {0226cdac1f03a642a4849ad8b9d4574ef35c943c},
	howpublished = "\url{https://github.com/etaler/Etaler}",
	journal = "GitHub repository",
	keywords = "HTM; Hierarchical Temporal Memory; Numenta; NuPIC; cortical; sparse distributed representation; SDR; anomaly; prediction; bioinspired; neuromorphic",
	publisher = "Github",
	title = "{Etaler implementation of Hierarchical Temporal Memory}",
	year = "2019"
}

Note: The commit number, publication year shown above are the ones when we last update the citation. You can update the fields to match the version you uses.

etaler's People

Contributors

alior101 avatar danielpwarren avatar marty1885 avatar mewmew avatar rcrowder avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

etaler's Issues

NUMA aware CPUBackend

Currently CPUBackend is not NUMA aware, so Etaler might run slower on a NUMA system (Multi-socket servers/ AMD 1st gen EPYC/ AMD ThreadRipper). Binding threads on NUMA nodes. allocating memory on NUMA local memory and running separate backends on NUMA nodes should allow Etaler to run fast on NUMA systems.

Yet since TBB is not NUMA aware. So we might need to drop TBB to support NUMA.

Spatial Pooler w Topology having weird connecties

From #68 . Quote alior.

So, if I understand correctly the kernel size is the potential pool size ?
If so, I think it should indeed follow a topological connection with
input.. For example output cell 0 should have a potential pool of input
cells 0-31 while output cell N (the last one) should have a potential pool
of 95-127 ... Is that the case ? From my little experiment all output cells
are randomly drawn from 0-31 which doesn't make sense biologically since
the SP have a receptive field of input cells that are "below" the layers
topologically ? What do you think?

setDefaultBackend undefined

Modifying example1 to have a default OpenCL backend fails compilation:

int main()
{
	//Create a SP that takes in 128 input bits and generates 32 bit representation
	auto gpu = std::make_shared<OpenCLBackend>();
	setDefaultBackend(std::make_shared<OpenCLBackend>());
	SpatialPooler sp({128}, {32});

[build] Starting build
[proc] Executing command: /usr/bin/cmake --build /workspaces/Etaler/build --config Debug --target example1 -- -j 6
[build] [ 80%] Built target Etaler
[build] Scanning dependencies of target example1
[build] [ 80%] Building CXX object examples/CMakeFiles/example1.dir/example1.cpp.o
[build] [100%] Linking CXX executable example1
[build] CMakeFiles/example1.dir/example1.cpp.o: In function `et::setDefaultBackend(std::shared_ptr<et::Backend>)':
[build] /workspaces/Etaler/./Etaler/Core/DefaultBackend.hpp:14: undefined reference to `et::g_default_backend_hold'
[build] collect2: error: ld returned 1 exit status
[build] make[3]: *** [examples/example1] Error 1
[build] examples/CMakeFiles/example1.dir/build.make:96: recipe for target 'examples/example1' failed
[build] CMakeFiles/Makefile2:187: recipe for target 'examples/CMakeFiles/example1.dir/all' failed
[build] CMakeFiles/Makefile2:199: recipe for target 'examples/CMakeFiles/example1.dir/rule' failed
[build] make[2]: *** [examples/CMakeFiles/example1.dir/all] Error 2
[build] make[1]: *** [examples/CMakeFiles/example1.dir/rule] Error 2
[build] make: *** [example1] Error 2
[build] Makefile:190: recipe for target 'example1' failed
[build] Build finished with exit code 2

Optimize inference and learning process using mirror connections.

In the Bachelor project by Ali Kaan Sungar, Hierarchical Temporal Memory Software Agent section 5.4.3. He purposes that mirrored synapses (maintaining 2 sets of identical synapses but running in the opposite direction) are a major optimization. Allowing a vastly reduced computation requirement.

The same tech can be also used in Etaler to enhance the performance further. But maintaining 2 lists of synapses is complicated under Etaler's DOD/functional API.

SpatialPooler constructor confusion

So, this problem shows up when I'm building my final project for my univ.

A SpatialPooler is designed to be easily construct-able. And the default format of the constructor is: SpatialPooler(input_shape, output_shape).
So, when you call the constructor like so, SpatialPooler({128}, {32}) you'll expect a SP that takes in 128 bits and generates a 32bit output. But no, in fact this calls to the alternative constructor for topology. i.e. SpatialPooler(input_shape, kernel_size).

This is super confusing, We'll have to fix this.

Difficult to build visualoizer on Windows

@alior101

May I add a switch in the build system to disable building the Visualizer? I found it pretty difficult to build the visualizer on Windows. So I expect most windows user will need help building the project by default.

Print Tensor, Shape and other essential object via cling

Cling supports printing object description when declaring/calling functions. But now useless message is printed. (Even though Etaler can pretty print via std::cout)

For example:

root [0] #pragma cling load("/usr/local/lib/libEtaler.so")
root [1] #include <Etaler/Etaler.hpp>
root [2] using namespace et;
root [3] Tensor t = ones({2,2})
(et::Tensor &) @0x7fdb47567010
root [4] cout << t << '\n';
{{ 1, 1}, 
 { 1, 1}}

It would be great if Etaler can do something like Python:

>>> import numpy as np
>>> np.ones([2,2])
array([[1., 1.],
       [1., 1.]])

Show both active and predictive cells in visualzer

I'm now debugging a weird behavior in the TM, but tmviz was built for tiny-htm so it won't work on Etaler.

@alior101 Your visualizer have been very helpful in the process. Would you mind spending a minute making the visualizer also show cells in the predictive state?

Adding backtraces into et_assert

It is quite annoying to have assertion failures, explain to you what happens but doesn't have a back trace. So we should add one! How is a problem tho.

How could we add back trace without overhead?

Python wrapper when?!!!

Hi Marty,

       Congrat for being a brilliant C++ programmer and getting Etaler to this stage.  For most users and including me, we need a Python Wrapper in order to use HTM due to other "data input" requirements.  If you could get a similar Jupyter Notebook going or making yours to work with like in this Notebook: "https://github.com/psdyer/NuPIC-Algorithm-API-Example", that will open up a lot of users.  

     Looking forward to your reply.

Samuel

Boosting on CPU is slow

Due to tensor operators only running on one core, and boosting is implemented as a composition of tensor ops. Boosting is slow.

example1 with OpenCL fails on assert

I modified SP to have opencl default backend

Backend* et::defaultBackend()
{
	using DefaultBackendType = OpenCLBackend;
	if(g_default_backend == nullptr) {
		//std::cerr << "Error: defaultBackend() called before setting the default backend.\n";
		//abort();
		if((bool)g_default_backend_hold == false)
			g_default_backend_hold = std::make_shared<DefaultBackendType>();

		g_default_backend = g_default_backend_hold.get();
	}
	return g_default_backend;
}

and then modified example1

int main()
{
	//std::shared_ptr<Backend> backend = std::make_shared<OpenCLBackend>();
	//setDefaultBackend(backend);

	//Create a SP that takes in 128 input bits and generates 32 bit representation
	auto gpu = std::make_shared<OpenCLBackend>();

	SpatialPooler sp({128}, {32});
	//sp.to(gpu.get());

	//Encode the value 0.1 into a 32 bit SDR
	Tensor x = encoder::scalar(0.1, 0, 1, 128, 12);
	Tensor x1 = x.to(gpu);

	std::cout << sp.compute(x1) << std::endl;

	auto state = sp.states();
	sp.loadState(state);
}

running it fails on sp.compute with

Assertion connections->backend() == this failed

Build process can't find Catch2

I'm attempting to build Etaler with:

TBBROOT=/usr
export TBBROOT

cp ../Catch2/include/catch.hpp tests/.
cp -r ../cereal/. Etaler/3rdparty/.

mkdir build
cd build
cmake ..
make -j1

But I quickly get the following error:

-- Performing Test HAVE_CXA_DEMANGLE
-- Performing Test HAVE_CXA_DEMANGLE - Success
CMake Error at tests/CMakeLists.txt:4 (find_package):
By not providing "FindCatch2.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "Catch2", but
CMake did not find one.

Could not find a package configuration file provided by "Catch2" with any
of the following names:

Catch2Config.cmake
catch2-config.cmake

Add the installation prefix of "Catch2" to CMAKE_PREFIX_PATH or set
"Catch2_DIR" to a directory containing one of the above files. If "Catch2"
provides a separate development package or SDK, be sure it has been
installed.

-- Configuring incomplete, errors occurred!
See also "/home/dstromberg/src/etaler/src/build/CMakeFiles/CMakeOutput.log".

Am I putting Catch2 in the wrong place?

Thanks!

Build failed in OSX

Replicate: Build by following the instructions in building from source.

  • Install libraries

mkdir build
cd build
cmake ..
make -j8

Expected: Build should pass.

Observed: Build failed.

[ 6%] Building CXX object Etaler/CMakeFiles/Etaler.dir/Backends/CPUBackend.cpp.o
clang: error: no such file or directory: '/DNOMINMAX'
make[2]: *** [Etaler/CMakeFiles/Etaler.dir/Backends/CPUBackend.cpp.o] Error 1
make[1]: *** [Etaler/CMakeFiles/Etaler.dir/all] Error 2
make: *** [all] Error 2

Environment

  • OSX/Mojave/10.14.2
  • Apple LLVM version 10.0.0 (clang-1000.10.44.4)

Deep Learning support in Etaler

Related to htm-community/htm.core#680

Well, here we go

Why

The SDRClassifer in NuPIC/HTM.core ins infect a simple 2 layer MLP but Etaler implements it as a CLAClassifer/KNN. CLAClassifer is deprecated from HTM.core and is inferior to the MLP; both performance and accuracy wise. It is beneficial to have an actual SDRClassifer implementation. Also, as community member @Thanh-Binh mentioned. Better neural network architecture can help HTM generate better predictions.

Why not

This is a very steep slippery slope. Etaler's core design is very similar to a DL framework. We have tensors, operators, etc... while autograd and lazy evaluation can be implemented easily by extending the current system. As far as I can tell, if implemented, Etaler will be the only framework supporting DL via OpenCL with a proper tensor system. We might gain traction, but from the DL community and thus most development will be focused on DL instead of HTM.

How

Writing matrix operations from scratch is doable, but we'll never even beat NumPy at performance, and it'll take forever. We might want to use libraries like NNPACK and clDNN to perform the calculations. Besides that, we need to modify the current Tensor system to support autograd and (hopefully) operation fusing. We also need to rethink how the et namespace is used. How should we separate HTM and NN algorithms and how can we use them together.

Optimize data transfer between OpenCL devices.

Currently copying data between 2 OpenCL backends are done by

  1. Allocating a temporary buffer
  2. Copy data from GPU1 to buffer
  3. Copy data from buffer to GPU2
  4. release the buffer

Which is slow. There are other more optimized routes. But the mechanism to trigger it is yet to determined.

Sol 1: Using clEnqueueMapBuffer

  1. Map the memory from GPU1 to CPU (a pre-pinned DMA transfer)
  2. Copy data from buffer to GPU2
  3. unmap buffer

Sol 2: With OpenCL 2.0's Shared Virtual Memory. Host memory is not touched, super fast.

  1. Allocate Tensors as SVM buffers
  2. Ask GPU2 to copy data from GPU1

They should make multi-gpu faster.

Enable hardware fp16 on ARM

Related to #23 #44. Aarch64 processors support FP16 to FP32 conversions natively. This could greatly enhance the performance of FP16 on ARM devices.

Strange SP initial connections

I think - (but I'm not 100% sure) that there is a bug in the SP initial connection tensor.. I'm still trying to understand why, but for example1, for example, each of the 128 output cells is making connections only to 1-32 first input cells. I was expecting 32 * 0.75 random connections receptive field from the entire 128 input population.
Am I missing something ?

in spatialpooler init I'm printing the connections as in
connections_.view(write_loc) = Tensor({(intmax_t)potential_pool_size}, conns.data()); std::cout << "Connections_ for cell " << i << " are " << Tensor({(intmax_t)potential_pool_size}, conns.data()) << std::endl;
and this is what I get

Connections_ for cell 0 are { 3 , 4 , 5 , 6 , 8 , 10, 11, 12, 14, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31} Connections_ for cell 1 are { 0 , 1 , 2 , 3 , 4 , 5 , 8 , 9 , 10, 11, 12, 15, 16, 17, 19, 20, 21, 22, 24, 25, 26, 27, 28, 30} Connections_ for cell 2 are { 0 , 2 , 3 , 4 , 5 , 7 , 8 , 9 , 10, 11, 12, 13, 14, 16, 17, 18, 19, 21, 23, 24, 25, 26, 28, 30} Connections_ for cell 3 are { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 11, 12, 17, 18, 19, 20, 22, 23, 24, 27, 28, 29, 30, 31} Connections_ for cell 4 are { 0 , 1 , 2 , 4 , 5 , 7 , 8 , 9 , 10, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 24, 25, 27, 30, 31} Connections_ for cell 5 are { 0 , 1 , 2 , 4 , 5 , 6 , 7 , 9 , 12, 13, 14, 16, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 31} Connections_ for cell 6 are { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 10, 11, 13, 14, 15, 17, 18, 19, 20, 21, 22, 24, 26, 27, 29, 30} Connections_ for cell 7 are { 0 , 1 , 2 , 3 , 6 , 8 , 9 , 10, 11, 12, 14, 15, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 31} Connections_ for cell 8 are { 0 , 1 , 3 , 4 , 5 , 6 , 7 , 8 , 10, 11, 13, 14, 15, 16, 17, 19, 20, 22, 24, 26, 27, 28, 29, 30} Connections_ for cell 9 are { 0 , 1 , 2 , 3 , 4 , 6 , 7 , 8 , 9 , 10, 12, 15, 16, 17, 18, 19, 20, 22, 23, 24, 26, 27, 29, 30} Connections_ for cell 10 are { 0 , 1 , 2 , 3 , 4 , 8 , 9 , 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 26, 28, 29, 30, 31} Connections_ for cell 11 are { 0 , 2 , 3 , 4 , 7 , 9 , 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 22, 23, 25, 26, 27, 28, 29, 30} Connections_ for cell 12 are { 1 , 2 , 3 , 4 , 7 , 8 , 9 , 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 25, 26, 28, 30, 31} Connections_ for cell 13 are { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 11, 13, 15, 16, 17, 18, 19, 21, 23, 24, 27, 29, 30, 31} Connections_ for cell 14 are { 0 , 1 , 2 , 3 , 5 , 6 , 7 , 8 , 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 22, 23, 24, 27, 28, 31} Connections_ for cell 15 are { 3 , 4 , 6 , 7 , 8 , 10, 11, 12, 13, 14, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31} Connections_ for cell 16 are { 0 , 1 , 2 , 3 , 4 , 5 , 7 , 8 , 10, 11, 12, 13, 14, 16, 17, 18, 19, 21, 23, 24, 25, 27, 30, 31} Connections_ for cell 17 are { 0 , 3 , 4 , 5 , 6 , 7 , 8 , 10, 11, 12, 13, 14, 17, 18, 19, 20, 21, 22, 23, 24, 26, 29, 30, 31} Connections_ for cell 18 are { 0 , 2 , 5 , 6 , 7 , 8 , 9 , 11, 12, 13, 14, 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 29, 30, 31} Connections_ for cell 19 are { 0 , 1 , 2 , 3 , 5 , 6 , 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 24, 25, 27, 28, 29, 30, 31} Connections_ for cell 20 are { 0 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 10, 11, 12, 13, 14, 16, 17, 21, 22, 24, 26, 27, 28, 29, 30, 31} Connections_ for cell 21 are { 0 , 2 , 3 , 4 , 5 , 6 , 7 , 9 , 10, 11, 12, 13, 14, 17, 20, 21, 22, 24, 25, 26, 28, 29, 30, 31} Connections_ for cell 22 are { 0 , 1 , 3 , 4 , 5 , 6 , 7 , 8 , 10, 11, 12, 14, 15, 16, 17, 19, 21, 22, 25, 26, 27, 28, 29, 31} Connections_ for cell 23 are { 1 , 2 , 3 , 4 , 6 , 7 , 8 , 9 , 10, 12, 13, 14, 16, 18, 19, 20, 21, 22, 24, 25, 28, 29, 30, 31} Connections_ for cell 24 are { 0 , 1 , 4 , 5 , 6 , 8 , 9 , 10, 11, 14, 15, 16, 17, 18, 19, 21, 22, 25, 26, 27, 28, 29, 30, 31} Connections_ for cell 25 are { 0 , 1 , 2 , 3 , 5 , 7 , 8 , 9 , 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 23, 25, 26, 27, 28, 31} Connections_ for cell 26 are { 1 , 3 , 4 , 6 , 8 , 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 22, 23, 24, 25, 26, 28, 29, 30, 31} Connections_ for cell 27 are { 0 , 1 , 2 , 3 , 7 , 8 , 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 28, 30, 31} Connections_ for cell 28 are { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 9 , 10, 11, 12, 14, 15, 17, 18, 19, 20, 21, 22, 24, 26, 28, 30} Connections_ for cell 29 are { 0 , 1 , 2 , 3 , 6 , 7 , 8 , 9 , 10, 11, 13, 14, 16, 17, 18, 19, 20, 21, 22, 25, 26, 28, 29, 30} Connections_ for cell 30 are { 0 , 1 , 2 , 3 , 4 , 8 , 9 , 10, 11, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, 30} Connections_ for cell 31 are { 0 , 1 , 2 , 4 , 5 , 6 , 7 , 8 , 9 , 11, 12, 14, 15, 16, 17, 18, 20, 25, 26, 27, 28, 29, 30, 31} Connections_ for cell 32 are { 2 , 3 , 4 , 6 , 7 , 8 , 10, 12, 13, 14, 16, 18, 19, 20, 21, 22, 23, 25, 26, 27, 28, 29, 30, 31} Connections_ for cell 33 are { 0 , 1 , 2 , 3 , 6 , 7 , 8 , 9 , 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 23, 26, 27, 28, 29} Connections_ for cell 34 are { 1 , 3 , 5 , 8 , 9 , 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 25, 26, 27, 28, 29, 30, 31} Connections_ for cell 35 are { 0 , 1 , 3 , 4 , 5 , 7 , 9 , 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 27, 28, 29, 31} Connections_ for cell 36 are { 0 , 1 , 2 , 4 , 5 , 6 , 8 , 9 , 10, 11, 12, 13, 14, 16, 17, 18, 19, 21, 23, 24, 25, 26, 27, 28} Connections_ for cell 37 are { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10, 12, 13, 15, 16, 17, 19, 20, 21, 22, 23, 24, 26, 28, 31} Connections_ for cell 38 are { 0 , 1 , 2 , 4 , 5 , 6 , 9 , 10, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 24, 25, 26, 27, 30, 31} Connections_ for cell 39 are { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 10, 11, 12, 14, 16, 17, 18, 19, 21, 22, 24, 25, 26, 29, 30, 31} Connections_ for cell 40 are { 0 , 1 , 2 , 4 , 5 , 6 , 7 , 8 , 10, 12, 14, 15, 16, 17, 18, 20, 21, 22, 23, 26, 27, 28, 29, 30} Connections_ for cell 41 are { 0 , 2 , 3 , 6 , 7 , 8 , 9 , 10, 11, 12, 13, 15, 16, 17, 19, 20, 21, 22, 23, 25, 28, 29, 30, 31} Connections_ for cell 42 are { 0 , 1 , 2 , 4 , 5 , 6 , 8 , 9 , 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 24, 26, 28, 31} Connections_ for cell 43 are { 1 , 2 , 3 , 5 , 6 , 9 , 10, 11, 12, 14, 15, 18, 19, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31} Connections_ for cell 44 are { 0 , 1 , 2 , 3 , 4 , 7 , 8 , 9 , 11, 13, 14, 15, 17, 18, 20, 22, 23, 25, 26, 27, 28, 29, 30, 31} Connections_ for cell 45 are { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 10, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 24, 26, 27, 28, 29} Connections_ for cell 46 are { 0 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10, 11, 12, 13, 15, 16, 18, 20, 21, 22, 23, 25, 26, 27, 28, 30} Connections_ for cell 47 are { 0 , 1 , 2 , 3 , 5 , 6 , 7 , 8 , 9 , 12, 15, 16, 17, 18, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31} Connections_ for cell 48 are { 0 , 1 , 2 , 3 , 4 , 5 , 7 , 8 , 9 , 10, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 25, 26, 27, 31} Connections_ for cell 49 are { 0 , 3 , 4 , 6 , 7 , 9 , 10, 11, 13, 14, 15, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 30, 31} Connections_ for cell 50 are { 1 , 3 , 4 , 6 , 7 , 10, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 31} Connections_ for cell 51 are { 0 , 1 , 2 , 3 , 6 , 7 , 8 , 9 , 10, 12, 14, 15, 16, 17, 18, 20, 21, 23, 24, 25, 26, 27, 28, 30} Connections_ for cell 52 are { 0 , 1 , 2 , 5 , 7 , 8 , 9 , 10, 12, 14, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31} Connections_ for cell 53 are { 0 , 1 , 2 , 3 , 4 , 7 , 8 , 9 , 10, 11, 13, 15, 16, 17, 19, 20, 22, 24, 25, 27, 28, 29, 30, 31} Connections_ for cell 54 are { 0 , 1 , 2 , 4 , 5 , 6 , 7 , 10, 11, 12, 14, 15, 16, 18, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31} Connections_ for cell 55 are { 0 , 2 , 3 , 4 , 5 , 6 , 8 , 9 , 10, 11, 12, 14, 16, 17, 18, 19, 20, 21, 22, 24, 26, 27, 28, 30} Connections_ for cell 56 are { 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 28, 29} Connections_ for cell 57 are { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 9 , 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 31} Connections_ for cell 58 are { 0 , 2 , 3 , 6 , 7 , 8 , 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 24, 25, 26, 27, 29} Connections_ for cell 59 are { 0 , 2 , 4 , 5 , 6 , 7 , 10, 11, 12, 13, 14, 15, 17, 18, 20, 21, 22, 23, 24, 25, 26, 28, 30, 31} Connections_ for cell 60 are { 0 , 1 , 2 , 3 , 4 , 5 , 7 , 9 , 11, 12, 13, 14, 15, 19, 20, 21, 22, 23, 24, 26, 27, 29, 30, 31} Connections_ for cell 61 are { 0 , 1 , 5 , 6 , 7 , 8 , 9 , 10, 11, 12, 14, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 31} Connections_ for cell 62 are { 0 , 2 , 3 , 4 , 5 , 7 , 8 , 9 , 10, 11, 12, 14, 15, 17, 20, 21, 23, 25, 26, 27, 28, 29, 30, 31} Connections_ for cell 63 are { 1 , 2 , 3 , 4 , 5 , 8 , 9 , 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 27, 28, 29, 30} Connections_ for cell 64 are { 0 , 1 , 2 , 5 , 7 , 8 , 9 , 10, 11, 13, 14, 15, 17, 19, 20, 21, 22, 24, 25, 26, 27, 29, 30, 31} Connections_ for cell 65 are { 0 , 1 , 2 , 4 , 5 , 6 , 7 , 9 , 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21, 24, 27, 28, 29, 30} Connections_ for cell 66 are { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 8 , 10, 11, 12, 13, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 29, 30} Connections_ for cell 67 are { 0 , 1 , 3 , 5 , 6 , 7 , 8 , 9 , 10, 12, 13, 14, 15, 16, 18, 19, 21, 23, 24, 25, 26, 28, 29, 30} Connections_ for cell 68 are { 1 , 2 , 3 , 4 , 5 , 8 , 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 27, 28, 29, 30, 31} Connections_ for cell 69 are { 0 , 1 , 2 , 3 , 5 , 6 , 7 , 8 , 11, 13, 14, 15, 16, 17, 20, 21, 22, 24, 25, 26, 27, 28, 30, 31} Connections_ for cell 70 are { 0 , 1 , 2 , 3 , 4 , 6 , 7 , 8 , 9 , 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 24, 25, 27, 28, 31} Connections_ for cell 71 are { 0 , 1 , 2 , 4 , 6 , 7 , 8 , 9 , 10, 11, 12, 13, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28, 29} Connections_ for cell 72 are { 1 , 2 , 3 , 4 , 6 , 7 , 8 , 9 , 10, 11, 15, 16, 17, 19, 20, 23, 24, 25, 26, 27, 28, 29, 30, 31} Connections_ for cell 73 are { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10, 11, 12, 13, 14, 18, 20, 21, 23, 24, 25, 26, 29, 30} Connections_ for cell 74 are { 1 , 2 , 3 , 4 , 6 , 7 , 8 , 9 , 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 24, 25, 28, 29} Connections_ for cell 75 are { 0 , 1 , 2 , 3 , 4 , 6 , 7 , 8 , 9 , 10, 11, 13, 14, 16, 17, 19, 20, 21, 22, 24, 25, 27, 29, 30} Connections_ for cell 76 are { 0 , 2 , 4 , 5 , 6 , 7 , 8 , 9 , 10, 11, 12, 14, 15, 16, 18, 20, 21, 22, 25, 26, 27, 28, 29, 30} Connections_ for cell 77 are { 0 , 1 , 2 , 3 , 4 , 5 , 7 , 9 , 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 25, 26, 30, 31} Connections_ for cell 78 are { 0 , 1 , 2 , 3 , 5 , 7 , 8 , 9 , 10, 11, 12, 13, 14, 15, 17, 19, 20, 21, 22, 23, 24, 26, 30, 31} Connections_ for cell 79 are { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10, 11, 14, 15, 17, 18, 19, 20, 21, 25, 28, 29, 30, 31} Connections_ for cell 80 are { 0 , 1 , 3 , 4 , 5 , 6 , 7 , 9 , 10, 13, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 28, 30, 31} Connections_ for cell 81 are { 1 , 2 , 3 , 4 , 5 , 6 , 8 , 9 , 12, 13, 14, 15, 16, 17, 18, 21, 22, 23, 24, 25, 26, 29, 30, 31} Connections_ for cell 82 are { 1 , 2 , 3 , 4 , 6 , 7 , 9 , 10, 12, 14, 15, 16, 17, 18, 19, 20, 22, 23, 25, 26, 27, 29, 30, 31} Connections_ for cell 83 are { 1 , 2 , 3 , 4 , 5 , 7 , 8 , 10, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, 31} Connections_ for cell 84 are { 0 , 1 , 3 , 5 , 7 , 9 , 10, 12, 13, 15, 16, 17, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31} Connections_ for cell 85 are { 0 , 1 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10, 11, 13, 14, 15, 17, 18, 19, 20, 21, 26, 27, 28, 29, 30} Connections_ for cell 86 are { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 9 , 10, 11, 13, 17, 19, 20, 21, 22, 23, 24, 25, 27, 28, 30, 31} Connections_ for cell 87 are { 1 , 3 , 5 , 6 , 8 , 9 , 11, 12, 13, 14, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, 30, 31} Connections_ for cell 88 are { 0 , 1 , 2 , 5 , 6 , 8 , 10, 11, 12, 13, 14, 15, 18, 19, 20, 21, 23, 24, 25, 26, 27, 29, 30, 31} Connections_ for cell 89 are { 0 , 1 , 2 , 3 , 4 , 5 , 8 , 9 , 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 23, 24, 25, 27, 29, 31} Connections_ for cell 90 are { 0 , 1 , 3 , 5 , 6 , 7 , 8 , 9 , 10, 12, 13, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28} Connections_ for cell 91 are { 2 , 3 , 4 , 5 , 8 , 9 , 10, 11, 12, 13, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 27, 28, 30, 31} Connections_ for cell 92 are { 0 , 2 , 3 , 4 , 6 , 7 , 8 , 9 , 11, 12, 13, 14, 16, 17, 18, 20, 21, 22, 23, 24, 25, 27, 28, 29} Connections_ for cell 93 are { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 12, 13, 15, 16, 18, 19, 20, 22, 24, 27, 28, 29, 30, 31} Connections_ for cell 94 are { 0 , 1 , 2 , 3 , 4 , 6 , 7 , 8 , 9 , 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28} Connections_ for cell 95 are { 0 , 1 , 2 , 3 , 5 , 8 , 9 , 10, 11, 12, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 27, 28, 29, 30} Connections_ for cell 96 are { 0 , 2 , 3 , 4 , 6 , 7 , 8 , 9 , 11, 13, 14, 15, 16, 17, 18, 19, 20, 23, 24, 25, 26, 27, 29, 30} input: { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} connections: {{ 24 , -1 , ...., 1 , 0 }, { 21 , 0 , ...., 1.43632e+09 , 21845 }, { 19 , 21845 , ...., 1.43495e+09 , 21845 }, .... { 20 , -1 , ...., 0 , 0 }, { 21 , -1 , ...., 1.43401e+09 , 21845 }, { 20 , 21845 , ...., 1.43478e+09 , 21845 }} permanences: {{ 1 , 3.06114e-41 , ...., 9.95847e+32 , 945.487 }, { 0.484771 , 0 , ...., 1.82847e+13 , 3.06114e-41 }, { 0 , 3.06114e-41 , ...., 2.38172e+13 , 3.06114e-41 }, .... { 0 , 3.06114e-41 , ...., 0 , 0 }, { 0.166686 , 3.06114e-41 , ...., 9.95847e+32 , 949.488 }, { 0.826219 , 0 , ...., 0 , 0 }} terminate called after throwing an instance of 'et::EtError' what(): Cannot find any open-able cellActivity.cl in search paths

Version 0.1.1 release.

Well... I guess it is time for another release. It's arbitrary. A new version will be released soon as there are many features added since last release.

Please comment if you have any comments, ideas.

Move encoders to backend.

One of the bottleneck Etaler have is that encoding is done in the frontend. Which is easy to implement. You encode the SDR into an array and call Tensor() to copy whatever data is in that array into a real Tensor. But this is very slow. On CPU, there is at least one extra array copy and memory allocation. One GPU, the current code path copies the entire array over PCIe to the GPU.

So the obvious solution is to move the responsibility of encoding data to the backend. But could we do so in an elegant way? And we need to maintain the high expandability.

Optimize Tensor-scalar operations by not relying on brodcasting

The current way Etaler handles Tensor-scalar operations is by supply constructors that converts scalar values into Tensors of shape {1}. Then rely on broadcasting to process the entire Tensor. This works and is only a few lines of code. But is very slow (Have to read from memory every operations, can't put the scalar in a register). We'll need another solution to make this fast.

Providing operator [] for et::Tensor (or at least a better way to handle tensor subscription)

Numpy's way of doing ND array subscription is widely accepted and straight forward.

ex:

>>> a = np.zeros(4,4)
>>> a[:2, :2]

Due to the fact that C++'s operator [] can only take one argument. I ended up implementing a view() method to perform subscription.

ex:

[cling]$ auto a = ones({4,4})
[cling]$ a.view({range(2), range(2)})

But TBH, it gets annoying when I start to write more code with it. It would be great to have a [] equivalent in Etaler. We have a few solution.

  1. make Tensor Tensor::operator [] (svector<Range>)

Which will allow us to do

[cling]$ auto a = ones({4,4})
[cling]$ a[{range(2), range(2)})]

There is an extra bracket around the parameters.

  1. make Tensor Tensor::operator [] (svector<Range>) and overload Range::operator , ()

Which allows us to

[cling]$ auto a = ones({4,4})
[cling]$ a[range(2), range(2))]

It gives us the syntax we want. But messes with how C++ evaluates values.

  1. Use operator ()

This is ArrayFire's solution. It feels weird to subscript using () instead of [].

[cling]$ auto a = ones({4,4})
[cling]$ a(range(2), range(2)))

It feels like calling a function....

Any ideas?

Does not build without TBBConfig

#17 introduces a better way to link to TBB. Unfortunately when merging, I didn't check that the code path using FindTBB works. So now if both TBBCondig and FindTBB does not exist. The following occurs (Since find_package can't find the requested package). And thus the fallback path of letting the linker solve the problem itself can't be invoked.

CMake Warning at CMakeLists.txt:59 (find_package):
  By not providing "FindTBB.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "TBB", but
  CMake did not find one.

  Could not find a package configuration file provided by "TBB" with any of
  the following names:

    TBBConfig.cmake
    tbb-config.cmake

I'm working on a fix.

Printing Tensor on Cling prompt is broken.

Printing the contents of tensors on cling (not ROOT) is broken for some reason. For example

▶ cling -std=c++17
[cling]$ #include <Etaler/Etaler.hpp>
[cling]$ #pragma cling load("/usr/local/lib/libEtaler.so")
[cling]$ #include <Etaler/Encoders/Scalar.hpp>
[cling]$ using namespace et;
[cling]$ auto x = encoder::scalar(0.1, 0, 1, 128, 12);
[cling]$ x
(et::Tensor &) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}@$IDXe�O�O�XdXd��O�O��b�b��a�aU�O�O>P�P�"`�`�����������Q��@pX��������00-�D���
�������� ������1�v	.rodata1���cling-module-5!b@� 010Tecling-module-6qE0i�O_ZN13llvm_vecsmall15SmallVectorImplIlE6assignESt16initializer_listIlE
...

But it does work on ROOT (at least on 6.16.00)

▶ root -b
root [0] #include <Etaler/Etaler.hpp>
root [1] #pragma cling load("/usr/local/lib/libEtaler.so")
root [2] #include <Etaler/Encoders/Scalar.hpp>
root [3] using namespace et;
root [4] auto x = encoder::scalar(0.1, 0, 1, 128, 12);
root [5] x
(et::Tensor &) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

Build test for OpenCL by default when OpenCL is enabled.

For now, Etaler only builds the testing application for CPU by default and testing OpenCL have to be by manually switching backend in main.cpp. This can be improved. And will also allow tests for OpenCL specific functions.

Share OpenCL context across OpenCLBackends

Now each OpenCLBackend owns their own OpenCL Context. But for efficient data transfer between OpenCL devices (i.e. #15 ), all devices mush share the same context. Context sharing is done by manually initializing a context and initialize backends using said context. An automatic way should be implemented.

Better tutorial and documents

Related to #45.
We definitely need better documents and tutorials for new comers to join easily. How and in what kinds of tutorial and documents do we need?

SpatialPooler and TemporalMemory API change.

(This issue is also a not for myself.) As I mentioned in #45 . I'm preparing an API update.

What's the problem

The current API loosely follows the one in NuPIC. Where (in NuPIC) if you want to switch between global inhibition and local inhibition. You call sp.setGlobalInhibition(bool). And set the parameters via setGlobalDensity/setLocalXXX. Which is not elegant and stores a lot of state variables inside the layer. (You need to store variables even you don't need them).

This sort of APIs also is very not flexible. Ex, no global inhibition on a TM, can't extract the confident of TM predictions, etc... There is also the problem that layers are objects, there is no chance for a functional one.

Purposed solution

My proposed solution is to have a PyTorch like API. Where the actual operation is implemented in the et::F namespace and the layer object in the et::htm namespace.

For example

SpatialPooler sp(in_shape, out_shape);
sp.setGloablDensity(0.1); //Enable global inhibition and set density to 0.1
Tensor y = sp.compute(x);

becomes

htm::SpatialPooler sp(in_shape, out_shape);
Tensor y = F::globalInhibition(sp.compute(x), 0);

This have the advantage that we can switch between local/global inhibition easily.

In NuPIC-like API.

bool use_local = true;

if(use_local) {
    sp.setGlobalInhibition(false);
    set.setLocalAreaDensity(0.10);
}
else {
    sp.setGlobalInhibition(true);
    sp.setGlobalDensity(0.1);
}

auto out = sp.compute(x);

becomes

bool use_local = true;

Tensor y = [&](){
    if(use_local) return F::localInhibition(sp.compute(x), 0.1);
    else return F::globalInhibition(sp.compute(x), 0.1);
}();

Test for ARM CPU compablity

Finally back from my final exam hell. Now my friend an I are perching a quite powerful ARM development board for other research and (hopefully) an ARM Navi GPU. So we can test how well Etaler ran on ARM.

VSC remote error

Replicate: Open .devcontainer in VSC

Expected: Build the image and use VSC remote container

Observed: Error when building.

Screen Shot 2019-08-07 at 12 11 44 pm

Environment:

  • OSX/Mojave/10.14.2
  • VSC/1.36.1
  • ms-vscode-remote.remote-containers / 0.66.0

tbb.h deprecated warning

Newer versions of TBB is now warning that tbb.h (used in CPUBackend.cpp) is deprecated.

In file included from /home/marty/Documents/Etaler/Etaler/Backends/CPUBackend.cpp:9:
/usr/include/tbb/tbb.h:21:154: note: #pragma message: TBB Warning: tbb.h contains deprecated functionality. For details, please see Deprecated Features appendix in the TBB reference manual.
   21 | #pragma message("TBB Warning: tbb.h contains deprecated functionality. For details, please see Deprecated Features appendix in the TBB reference manual.")
      |     

Windows support.

Currently Etaler is build-able on Windows using 64bit MSYS2. But the resulting library and test applications crash immediately after loading. It may be me mixing up 32-bit and 64-bit DLLs or an actual compiler bug. But I'm out of time for this. 😢

Possible solutions:

  • Build on MSVC/Visual Studio
  • Use Cygwin
  • Retry MSYS2 carefully.

Migrating to C++20

(When C++20 finally get released and compilers got support of it) I think we should move to C++20, making a lot of stuff easier:

  • No more "blablabal" + std::to_string(foo) + "blablabla" + std::to_string(bar)
    • string formatting solves the problem
  • Contracts, making the code faster
  • etc...

Migrating from OpenCL 1.0 to 1.2

The current OpenCL backend requires us to specify which kernel is needed from the .cl programs. Which can be automatically detected using OpenCL 1.2's CL_PROGRAM_KERNEL_NAMES feature. But This might cause Etaler not working on mobile/ARM devices like TI's DSP.

Use less accurate types to store synapse permances.

Since HTM is very resistant to noise and the permanence are limited to between 0~1. There is no real reason besides convention to store them as floats. a half, unsigned short or even unsigned char can be enough.

Storing permanence using less bits should make things faster quite a bit.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.