[BUG] munmap_chunk(): invalid pointer

Open
#381 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
25/100
Issue type
Bug
Clarity
Needs clarification
Activity status
Stale
Tech stack
rust
Domain
backend

Research direction

Start by reproducing the long-running program under the OpenCL backend with AF_TRACE=all and AF_PRINT_ERRORS=1. Inspect the referenced src/backend/opencl/jit.cpp and src/backend/opencl/Kernel.hpp paths around the logged kernel launches, and confirm the invalid-pointer failure no longer occurs.

Written by the indexing model from the issue text.

Description

Bug

Description

  1. I installed ArrayFire using AUR
  2. I am experiencing this on OpenCL
  3. No, I do not have a workaround.
  4. The bug can be reproduced if the program is left running for a long enough time. However, the exact time that it happens tends to be random.
  5. Most Recent Console Output:
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching philoxGenerator
[kernel][1736790336][2966] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [25,256,1,1] Global: [32,256,1] Local: [32,1,1] threads: 8192
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2966] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching reduce_first_kernel
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2966] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching philoxGenerator
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching philoxGenerator
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching philoxGenerator
[kernel][1736790336][2966] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [6400,1,1,1] Global: [6400,1,1] Local: [128,1,1] threads: 6400
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2966] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [25,256,1,1] Global: [32,256,1] Local: [32,1,1] threads: 8192
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching memCopy
[kernel][1736790336][2966] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [6400,1,1,1] Global: [6400,1,1] Local: [128,1,1] threads: 6400
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching memCopy
[kernel][1736790336][2966] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [6400,1,1,1] Global: [6400,1,1] Local: [128,1,1] threads: 6400
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching memCopy
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [1,1,1,1] Global: [128,1,1] Local: [128,1,1] threads: 128
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching memCopy
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching memCopy
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching memCopy
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching reduce_first_kernel
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching memCopy
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching memCopy
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching memCopy
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [1,1,1,1] Global: [128,1,1] Local: [128,1,1] threads: 128
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [1,1,1,1] Global: [128,1,1] Local: [128,1,1] threads: 128
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching reduce_first_kernel
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching reduce_first_kernel
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,1,1,1] Global: [256,1,1] Local: [128,1,1] threads: 256
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [25,256,1,1] Global: [32,256,1] Local: [32,1,1] threads: 8192
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching reduce_first_kernel
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching philoxGenerator
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [25,256,1,1] Global: [32,256,1] Local: [32,1,1] threads: 8192
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching reduce_first_kernel
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [6400,1,1,1] Global: [6400,1,1] Local: [128,1,1] threads: 6400
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching philoxGenerator
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [25,256,1,1] Global: [32,256,1] Local: [32,1,1] threads: 8192
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [6400,1,1,1] Global: [6400,1,1] Local: [128,1,1] threads: 6400
[kernel][1736790336][2965] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [6400,1,1,1] Global: [6400,1,1] Local: [128,1,1] threads: 6400
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [6400,1,1,1] Global: [6400,1,1] Local: [128,1,1] threads: 6400
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [25,256,1,1] Global: [32,256,1] Local: [32,1,1] threads: 8192
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [6400,1,1,1] Global: [6400,1,1] Local: [128,1,1] threads: 6400
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [6400,1,1,1] Global: [6400,1,1] Local: [128,1,1] threads: 6400
[kernel][1736790336][2966] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,256,1,1] Global: [256,128,1] Local: [128,1,1] threads: 32768
[kernel][1736790336][2966] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching reduce_first_kernel
[kernel][1736790336][2966] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching philoxGenerator
[kernel][1736790336][2966] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching identity_kernel
[kernel][1736790336][2966] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [65536,1,1,1] Global: [65536,1,1] Local: [128,1,1] threads: 65536
[kernel][1736790336][2966] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,256,1,1] Global: [256,128,1] Local: [128,1,1] threads: 32768
[kernel][1736790336][2966] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [65536,1,1,1] Global: [65536,1,1] Local: [128,1,1] threads: 65536
[kernel][1736790336][2966] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [65536,1,1,1] Global: [65536,1,1] Local: [128,1,1] threads: 65536
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [25,256,1,1] Global: [32,256,1] Local: [32,1,1] threads: 8192
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching reduce_first_kernel
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [256,256,1,1] Global: [256,128,1] Local: [128,1,1] threads: 32768
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching philoxGenerator
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching reduce_first_kernel
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching philoxGenerator
[kernel][1736790336][2967] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/jit.cpp:469 ] Launching : Dims: [6400,1,1,1] Global: [6400,1,1] Local: [128,1,1] threads: 6400
munmap_chunk(): invalid pointer
[kernel][1736790336][2968] [ /usr/src/debug/arrayfire/arrayfire-full-3.8.3/src/backend/opencl/Kernel.hpp:34 ] Launching identity_kernel
Aborted (core dumped)

Reproducible Code and/or Steps

This is what I believe might be causing the bug, but I am not exactly sure. Let me know if the full source code is needed.

/// A probabilistic implementation of the STDP algorithm for a bitwise linear layer.
pub fn probabilistic_bitwise_stdp<I: BitVolume, O: BitVolume>(
    synaptic_layers:              &mut [BitwiseLinear<I, O>],
    self_connected:               bool,
    presynaptic_trace:            &af::Array<f32>,
    dominant_postsynaptic_spikes: &af::Array<bool>,
    dopamine:                     f32,
    alpha:                        f32,
    learning_rate:                f32
    ) {

    // TODO:
    // When arrayfire supports 8-bit signed integers, migrate to that instead of 16-bit integers.

    // Go through each synaptic layer and modify its weights.
    let connections: usize = synaptic_layers.len();
    for (layer_idx, layer) in synaptic_layers.iter_mut().enumerate() {

        // Get the excitatory and inhibitory weights, and convert it to a trinary layer.
        let (excitatory, inhibitory): (af::Array<bool>, af::Array<bool>) = layer.weights_as_array();

        let mut weights: af::Array<i16> = af::constant(0, excitatory.dims());
                weights                 = af::selectl( 1.0, &excitatory, &weights);
                weights                 = af::selectl(-1.0, &inhibitory, &weights);

        // Normalize the trace and compute the LTP and LTD components.
        let trace_norm: af::Array<f32> = if connections == 1 {
            presynaptic_trace / af::max_all(presynaptic_trace).0
        } else {
            let sequences:   &[af::Seq<i32>] = &[af::Seq::default(), af::Seq::default(), af::Seq::default(), af::Seq::new(layer_idx as i32, layer_idx as i32, 1)];
            let trace_layer: af::Array<f32>  = af::index(presynaptic_trace, sequences);

            &trace_layer / af::max_all(&trace_layer).0
        };

        let ltp_trace: af::Array<f32> = af::exp(&trace_norm) - alpha;
        let ltd_trace: af::Array<f32> = af::exp(&(1.0f32 - &trace_norm)) - alpha;

        // Calculate update probabilities.
        let p_update_prob: af::Array<f32> = (ltp_trace - ltd_trace) * learning_rate * dopamine;
        let n_update_prob: af::Array<f32> = &p_update_prob * -1f32;

        // Generate random values for probabilistic update.
        // We use a uniform distribution to have an equal chance for all values to be generated.
        //
        // Using the random values, we'll then create a mask for different weight updates (positive and
        // negative).
        let random_values: af::Array<f32> = af::randu(weights.dims());

        let increase_mask: af::Array<bool> = af::lt(&random_values, &p_update_prob, false) & af::lt(&weights, & 1i16, false);
        let decrease_mask: af::Array<bool> = af::lt(&random_values, &n_update_prob, false) & af::gt(&weights, &-1i16, false);

        // Calculate delta weights
        let delta_weights: af::Array<i16> = increase_mask.cast::<i16>() - decrease_mask.cast::<i16>();

        // Apply winner_mask and identity_mask to delta_weights.
        let winner_mask:          af::Array<bool> = af::tile(&dominant_postsynaptic_spikes, af::dim4!(1, I::FSIZE as u64, 1, 1));
        let masked_delta_weights: af::Array<i16>  = if self_connected {
            let identity_mask: af::Array<i16> = (1f32 - af::identity::<i16>(af::dim4!(1, I::FSIZE as u64, O::FSIZE as u64, 1))).cast();

            &delta_weights 
                * &winner_mask.cast::<i16>() 
                * &identity_mask
        } else {
            &delta_weights
                * &winner_mask.cast::<i16>()
        };

        // Apply the masked delta weights to the weights.
        weights += masked_delta_weights;
        weights  = af::clamp(&weights, &-1i16, &1i16, true);

        // Deconstruct the weights back into their excitatory and inhibitory counterparts and export it
        // back into the layer.
        let excitatory: af::Array<bool> = af::eq(&weights, & 1, false);
        let inhibitory: af::Array<bool> = af::eq(&weights, &-1, false);

        layer.update_weights(excitatory, inhibitory);
    }
}
    /// Returns the weights as an arrayfire array of the dimensions (1, input size, output size).
    /// Arrays are returned in the order of excitatory and inhibitory weights.
    pub fn weights_as_array(&self) -> (af::Array<bool>, af::Array<bool>) {
        (
            af::Array::new(
                &self.neurons.par_iter()
                    .flat_map(|neuron| neuron.weight_excitatory.to_flattened_bits())
                    .collect::<Vec<_>>(),
                af::dim4!(1, I::FSIZE as u64, O::FSIZE as u64)
            ),
            af::Array::new(
                &self.neurons.par_iter()
                    .flat_map(|neuron| neuron.weight_inhibitory.to_flattened_bits())
                    .collect::<Vec<_>>(),
                af::dim4!(1, I::FSIZE as u64, O::FSIZE as u64)
            )
        )
    }

    /// Updates the weights from an arrayfire array of the dimensions (input size, output size).
    pub fn update_weights(&mut self, updated_excitatory: af::Array<bool>, updated_inhibitory: af::Array<bool>) {
        let mut excitatory_weights: Vec<bool> = vec![false; (I::FSIZE * O::FSIZE) as usize];
        let mut inhibitory_weights: Vec<bool> = vec![false; (I::FSIZE * O::FSIZE) as usize];

        updated_excitatory.host(&mut excitatory_weights);
        updated_inhibitory.host(&mut inhibitory_weights);

        self.neurons.par_iter_mut().enumerate().for_each(|(i, neuron)| {
            let start: usize = i     * I::FSIZE as usize;
            let end:   usize = start + I::FSIZE as usize;

            let excitatory_slice: &[bool] = &excitatory_weights[start..end];
            let inhibitory_slice: &[bool] = &inhibitory_weights[start..end];

            neuron.weight_excitatory = I::from_flattened_bits(excitatory_slice).unwrap();
            neuron.weight_inhibitory = I::from_flattened_bits(inhibitory_slice).unwrap();
        });
    }

System Information

  1. Arrayfire 3.8.3
  2. I have an NVidia 3050 RTX laptop GPU
  3. Output as follows:
LSB Version:	n/a
Distributor ID:	Arch
Description:	Arch Linux
Release:	rolling
Codename:	n/a
name, memory.total [MiB], driver_version
NVIDIA GeForce RTX 3050 Laptop GPU, 4096 MiB, 565.57.01
rocm-smi not found.
clinfo not found.

Checklist

  • Using the latest available ArrayFire release
  • GPU drivers are up to date
Dominant language
Rust
Stars
827
Forks
59
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from arrayfire/arrayfire-rust

All issues in arrayfire/arrayfire-rust

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.