Skip to content
Merged
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
1 change: 0 additions & 1 deletion knp/backends/cpu/cpu-library/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ file(GLOB_RECURSE ${PROJECT_NAME}_headers include/knp/backends/cpu-library/*.h)

knp_add_library("${PROJECT_NAME}"
INTERFACE
include/knp/backends/cpu-library/impl/synaptic_resource_stdp_impl.h
${${PROJECT_NAME}_headers})
add_library(KNP::Backends::CPU::Library ALIAS "${PROJECT_NAME}")

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* @file altai_lif_population.h
* @kaspersky_support Vartenkov A.
* @date 01.04.2025
* @license Apache 2.0
* @copyright © 2024 AO Kaspersky Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <knp/backends/cpu-library/impl/altai_lif_population_impl.h>
#include <knp/backends/cpu-library/impl/lif_population_impl.h>
#include <knp/core/message_endpoint.h>
#include <knp/core/messaging/messaging.h>
#include <knp/core/population.h>

#include <optional>


/**
* @brief Namespace for CPU backends.
*/
namespace knp::backends::cpu
{

/**
* @brief Calculate LIF population step.
* @tparam LifNeuron LIF neuron type.
* @param population population to be calculated.
* @param endpoint endpoint for message exchange.
* @param step_n current step.
* @return message if a message was sent by function.
*/
template <class LifNeuron>
std::optional<knp::core::messaging::SpikeMessage> calculate_lif_population(
knp::core::Population<LifNeuron> &population, knp::core::MessageEndpoint &endpoint, size_t step_n)
{
return calculate_lif_population_impl(population, endpoint, step_n);
}
Comment thread
artiomn marked this conversation as resolved.
} // namespace knp::backends::cpu
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
* @kaspersky_support A. Vartenkov
* @date 07.11.2023
* @license Apache 2.0
* @copyright © 2024 AO Kaspersky Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* @copyright © 2024 AO Kaspersky Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
Expand All @@ -39,7 +39,7 @@ template <class BlifatLikeNeuron>
std::optional<core::messaging::SpikeMessage> calculate_blifat_population(
knp::core::Population<BlifatLikeNeuron> &population, knp::core::MessageEndpoint &endpoint, size_t step_n)
{
return calculate_blifat_population_impl(population, endpoint, step_n);
return calculate_blifat_like_population_impl(population, endpoint, step_n);
}


Expand All @@ -60,7 +60,7 @@ std::optional<core::messaging::SpikeMessage> calculate_resource_stdp_population(
ProjectionContainer &container, knp::core::MessageEndpoint &endpoint, size_t step_n)
{
using StdpSynapseType = synapse_traits::STDP<synapse_traits::STDPSynapticResourceRule, BaseSynapseType>;
auto message_opt = calculate_blifat_population_impl(population, endpoint, step_n);
auto message_opt = calculate_blifat_like_population_impl(population, endpoint, step_n);
auto working_projections = find_projection_by_type_and_postsynaptic<StdpSynapseType, ProjectionContainer>(
container, population.get_uid(), true);
do_STDP_resource_plasticity(population, working_projections, message_opt, step_n);
Expand All @@ -82,7 +82,7 @@ std::optional<knp::core::messaging::SpikeMessage> calculate_blifat_population(
knp::core::Population<BlifatLikeNeuron> &population, knp::core::MessageEndpoint &endpoint, size_t step_n,
std::mutex &mutex)
{
return calculate_blifat_population_impl(population, endpoint, step_n, mutex);
return calculate_blifat_like_population_impl(population, endpoint, step_n, mutex);
}

} // namespace knp::backends::cpu
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
* @kaspersky_support Artiom N.
* @date 21.08.2023
* @license Apache 2.0
* @copyright © 2024 AO Kaspersky Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* @copyright © 2024 AO Kaspersky Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
Expand Down Expand Up @@ -65,7 +65,8 @@ class STDPFormula
}

[[nodiscard]] float stdp_delta_w(
const std::vector<uint32_t> &presynaptic_spikes, const std::vector<uint32_t> &postsynaptic_spikes) const
const std::vector<knp::core::Step> &presynaptic_spikes,
const std::vector<knp::core::Step> &postsynaptic_spikes) const
{
// Gerstner and al. 1996, Kempter et al. 1999.

Expand All @@ -85,7 +86,8 @@ class STDPFormula
}

[[nodiscard]] float operator()(
const std::vector<uint32_t> &presynaptic_spikes, const std::vector<uint32_t> &postsynaptic_spikes) const
const std::vector<knp::core::Step> &presynaptic_spikes,
const std::vector<knp::core::Step> &postsynaptic_spikes) const
{
return stdp_delta_w(presynaptic_spikes, postsynaptic_spikes);
}
Expand All @@ -101,8 +103,8 @@ class STDPFormula
template <class DeltaLikeSynapse>
inline void append_spike_times(
knp::core::Projection<knp::synapse_traits::AdditiveSTDPDeltaSynapse> &projection, const SpikeMessage &message,
const std::function<std::vector<size_t>(uint32_t)> &synapse_index_getter,
std::vector<uint32_t> knp::synapse_traits::STDPAdditiveRule<DeltaLikeSynapse>::*spike_queue)
const std::function<std::vector<size_t>(knp::core::messaging::SpikeIndex)> &synapse_index_getter,
std::vector<knp::core::Step> knp::synapse_traits::STDPAdditiveRule<DeltaLikeSynapse>::*spike_queue)
{
// Fill synapses spike queue.
for (auto neuron_index : message.neuron_indexes_)
Expand All @@ -125,7 +127,7 @@ inline void append_spike_times(
inline void append_spike_times(
knp::core::Projection<knp::synapse_traits::AdditiveSTDPDeltaSynapse> &projection,
const std::vector<SpikeMessage> &spikes, const std::function<std::vector<size_t>(uint32_t)> &syn_index_getter,
std::vector<uint32_t> knp::synapse_traits::STDPAdditiveRule<knp::synapse_traits::DeltaSynapse>::*spike_queue)
std::vector<knp::core::Step> knp::synapse_traits::STDPAdditiveRule<knp::synapse_traits::DeltaSynapse>::*spike_queue)
{
for (const auto &msg : spikes)
{
Expand Down Expand Up @@ -237,12 +239,14 @@ struct WeightUpdateSTDP<synapse_traits::STDP<synapse_traits::STDPAdditiveRule, D
{
using Synapse = synapse_traits::STDP<synapse_traits::STDPAdditiveRule, DeltaLikeSynapse>;
static void init_projection(
knp::core::Projection<Synapse> &projection, std::vector<SpikeMessage> &all_messages, uint64_t step)
knp::core::Projection<Synapse> &projection, std::vector<SpikeMessage> &all_messages, knp::core::Step step)
{
register_additive_stdp_spikes(projection, all_messages);
}

static void init_synapse(const knp::synapse_traits::synapse_parameters<Synapse> &projection, uint64_t step) {}
static void init_synapse(const knp::synapse_traits::synapse_parameters<Synapse> &projection, knp::core::Step step)
Comment thread
artiomn marked this conversation as resolved.
{
}

static void modify_weights(knp::core::Projection<Synapse> &projection)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**
* @file altai_lif_population_impl.h
* @kaspersky_support Vartenkov A.
* @date 07.04.2025
* @license Apache 2.0
* @copyright © 2024 AO Kaspersky Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <knp/core/messaging/messaging.h>
#include <knp/core/population.h>
#include <knp/neuron-traits/altai_lif.h>

#include <vector>

#include "lif_population_impl.h"


namespace knp::backends::cpu
{

// TODO: Maybe make this a .cpp and change library type from INTERFACE to STATIC later
Comment thread
artiomn marked this conversation as resolved.
template <>
void calculate_pre_input_state_lif<knp::neuron_traits::AltAILIF>(
knp::core::Population<knp::neuron_traits::AltAILIF> &population)
{
for (auto &neuron : population)
{
neuron.potential_ = std::round(neuron.potential_);

neuron.potential_ = neuron.do_not_save_ ? static_cast<float>(neuron.potential_reset_value_) : neuron.potential_;
}
}


void leak_potential(knp::core::Population<knp::neuron_traits::AltAILIF> &population)
{
for (auto &neuron : population)
{
// -1 if leak_rev is true and potential < 0, 1 otherwise.
const int sign = (neuron.leak_rev_ && neuron.potential_ < 0) ? -1 : 1;
neuron.potential_ += neuron.potential_leak_ * sign;
}
}


template <>
void process_inputs_lif<knp::neuron_traits::AltAILIF>(
knp::core::Population<knp::neuron_traits::AltAILIF> &population,
const std::vector<knp::core::messaging::SynapticImpactMessage> &messages)
{
for (const auto &msg : messages)
{
for (const auto &impact : msg.impacts_)
{
population[impact.postsynaptic_neuron_index_].potential_ += impact.impact_value_;
}
}
leak_potential(population);
}


template <>
knp::core::messaging::SpikeData calculate_spikes_lif<knp::neuron_traits::AltAILIF>(
knp::core::Population<knp::neuron_traits::AltAILIF> &population)
{
knp::core::messaging::SpikeData spikes;
for (knp::core::messaging::SpikeIndex i = 0; i < population.size(); ++i)
{
bool was_reset = false;
auto &neuron = population[i];
if (neuron.potential_ >= neuron.activation_threshold_)
{
spikes.push_back(i);
if (neuron.is_diff_) neuron.potential_ -= neuron.activation_threshold_;
if (neuron.is_reset_)
{
neuron.potential_ = neuron.potential_reset_value_;
was_reset = true;
}
}
if (neuron.potential_ <= -static_cast<float>(neuron.negative_activation_threshold_) && !was_reset)
{
// Might probably want a negative spike, but we don't have any of the sort in KNP. Not a large problem,
// just requires some conversion.
if (neuron.saturate_)
{
neuron.potential_ = -static_cast<float>(neuron.negative_activation_threshold_);
continue;
}
if (neuron.is_reset_)
neuron.potential_ = -neuron.potential_reset_value_;
else if (neuron.is_diff_)
neuron.potential_ += neuron.negative_activation_threshold_;
}
}
return spikes;
}

} // namespace knp::backends::cpu
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void process_spiking_neurons(
* @note We might want to impact a neuron with a whole message if it continues to have shared values.
*/
template <class BlifatLikeNeuron>
void impact_neuron(
void impact_blifat_like_neuron(
typename knp::core::Population<BlifatLikeNeuron>::NeuronParameters &neuron,
const knp::synapse_traits::OutputType &synapse_type, float impact_value)
{
Expand Down Expand Up @@ -126,7 +126,7 @@ void process_inputs(
for (const auto &impact : message.impacts_)
{
auto &neuron = population[impact.postsynaptic_neuron_index_];
impact_neuron<BlifatLikeNeuron>(neuron, impact.synapse_type_, impact.impact_value_);
impact_blifat_like_neuron<BlifatLikeNeuron>(neuron, impact.synapse_type_, impact.impact_value_);
if constexpr (has_dopamine_plasticity<BlifatLikeNeuron>())
{
if (impact.synapse_type_ == synapse_traits::OutputType::EXCITATORY)
Expand Down Expand Up @@ -322,7 +322,7 @@ void calculate_neurons_post_input_state_part(
* @return indexes of spiked neurons.
*/
template <class BlifatLikeNeuron>
knp::core::messaging::SpikeData calculate_blifat_population_data(
knp::core::messaging::SpikeData calculate_blifat_like_population_data(
knp::core::Population<BlifatLikeNeuron> &population, knp::core::MessageEndpoint &endpoint)
{
SPDLOG_DEBUG("Calculating BLIFAT population {}...", std::string{population.get_uid()});
Expand All @@ -339,10 +339,10 @@ knp::core::messaging::SpikeData calculate_blifat_population_data(


template <class BlifatLikeNeuron>
std::optional<core::messaging::SpikeMessage> calculate_blifat_population_impl(
std::optional<core::messaging::SpikeMessage> calculate_blifat_like_population_impl(
knp::core::Population<BlifatLikeNeuron> &population, knp::core::MessageEndpoint &endpoint, size_t step_n)
{
auto neuron_indexes{calculate_blifat_population_data(population, endpoint)};
auto neuron_indexes{calculate_blifat_like_population_data(population, endpoint)};
std::optional<knp::core::messaging::SpikeMessage> message_opt = {};
if (!neuron_indexes.empty())
{
Expand All @@ -364,11 +364,11 @@ std::optional<core::messaging::SpikeMessage> calculate_blifat_population_impl(
* @return indexes of spiked neurons.
*/
template <class BlifatLikeNeuron>
std::optional<knp::core::messaging::SpikeMessage> calculate_blifat_population_impl(
std::optional<knp::core::messaging::SpikeMessage> calculate_blifat_like_population_impl(
knp::core::Population<BlifatLikeNeuron> &population, knp::core::MessageEndpoint &endpoint, size_t step_n,
std::mutex &mutex)
{
auto neuron_indexes{calculate_blifat_population_data(population, endpoint)};
auto neuron_indexes{calculate_blifat_like_population_data(population, endpoint)};
if (!neuron_indexes.empty())
{
knp::core::messaging::SpikeMessage res_message{{population.get_uid(), step_n}, neuron_indexes};
Expand Down
Loading
Loading