etaler / Etaler

A flexable HTM (Hierarchical Temporal Memory) framework with full GPU support.
BSD 3-Clause "New" or "Revised" License
89 stars 14 forks source link

example1 with OpenCL fails on assert #53

Closed alior101 closed 5 years ago

alior101 commented 5 years ago

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

marty1885 commented 5 years ago

Ahh... This is the intended behaviour.

In your code

auto gpu = std::make_shared<OpenCLBackend>();
SpatialPooler sp({128}, {32});
//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);

Since you didn't use setDefaultBackend(). SP is initialized on the CPUBackend. But x1 is on OpenCL. So, it crashes. (This is the same behaviour if you add two tensors on different backends on PyTorch)

alior101 commented 5 years ago

it happens even if I move the sp to gpu with sp.to(gpu.get());

Maybe I'm doing it wrong ?

On Sun, Aug 4, 2019 at 7:59 AM Martin Chang notifications@github.com wrote:

Ahh... This is the intended behaviour.

In your code

auto gpu = std::make_shared(); SpatialPooler sp({128}, {32});//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);

Since you didn't use setDefaultBackend(). SP is initialized on the CPUBackend. But x1 is on OpenCL. So, it crashes. (This is the same behaviour if you add two tensors on different backends on PyTorch)

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/etaler/Etaler/issues/53?email_source=notifications&email_token=AAXET3EY6JOPDCK6LOTVX5LQCZO3VA5CNFSM4IJDTP2KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3P2O7I#issuecomment-517973885, or mute the thread https://github.com/notifications/unsubscribe-auth/AAXET3GAEN2AX7PF3YOZDXLQCZO3VANCNFSM4IJDTP2A .

marty1885 commented 5 years ago

Maybe I'm doing it wrong ?

It is my fault. I didn't read your code closely enough.

You have modified that.

using DefaultBackendType = OpenCLBackend;

So when ever defaultBackend() is called and no backend is available, it creates a new OpenCL backend for you.

Then you called auto gpu = std::make_shared<OpenCLBackend>(); afterwords. Creating a second OpenCL backend. Then the SP is created on the 1st OpenCLBackend, while x.to(gpu) in on the 2nd OpenCLBackend.

The objects are living under a different OpeCL context (think they are on a different server). So it crashes.


Since you have modified defaultBackend() you give you an OpenCLBackend. You don't need to create one yourself. You can leave the code alone and things should work.

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);
}
alior101 commented 5 years ago

working after merge with master