Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • mszczep/aidge_backend_cpu
  • eclipse/aidge/aidge_backend_cpu
  • hrouis/aidge_backend_cpu
  • oantoni/aidge_backend_cpu
  • raphaelmillet/aidge_backend_cpu
  • cguillon/aidge_backend_cpu
  • jeromeh/aidge_backend_cpu
  • axelfarr/aidge_backend_cpu
  • noamzerah/aidge_backend_cpu
  • silvanosky/aidge_backend_cpu
  • maab05/aidge_backend_cpu
  • lucaslopez/aidge_backend_cpu_ll
  • farnez/aidge_backend_cpu
  • mick94/aidge_backend_cpu
14 results
Show changes
Commits on Source (13)
Showing
with 274 additions and 78 deletions
......@@ -13,9 +13,10 @@ class test_scheduler(unittest.TestCase):
pass
def test_relu_forward(self):
values = np.arange(6) - 3
input_node = aidge_core.Producer(aidge_core.Tensor(values), "Input")
t = aidge_core.Tensor(np.arange(6, dtype=np.int32) - 3)
input_node = aidge_core.Producer(t)
relu = aidge_core.ReLU()
input_node.add_child(relu)
......@@ -34,7 +35,7 @@ class test_scheduler(unittest.TestCase):
out_tensor = relu.get_operator().get_output(0)
expected_out = [0,0,0,0,1,2]
for i in range(len(expected_out)):
self.assertEqual(expected_out[i], out_tensor[i])
self.assertEqual(expected_out[i], out_tensor[i], f"On idx {i}")
def test_sequential_scheduling(self):
input_data = np.array([0]).astype(np.float32)
......@@ -69,7 +70,7 @@ class test_scheduler(unittest.TestCase):
aidge_core.Producer(input_tensor, "X"),
aidge_core.FC(1, 50, name='0'),
aidge_core.parallel([aidge_core.FC(50, 50, name='1'), aidge_core.FC(50, 50, name='3')]),
aidge_core.Add(2, name='2'),
aidge_core.Add(name='2'),
])
EXPECTED_SCHEDULE = [['0', '1', '3', '2'], ['0', '3', '1', '2']] # Both scheduling are valid !
......
......@@ -15,6 +15,8 @@
#include "aidge/backend/cpu/operator/AbsImpl.hpp"
#include "aidge/backend/cpu/operator/AddImpl.hpp"
#include "aidge/backend/cpu/operator/AndImpl.hpp"
#include "aidge/backend/cpu/operator/AtanImpl.hpp"
#include "aidge/backend/cpu/operator/ArgMaxImpl.hpp"
#include "aidge/backend/cpu/operator/AvgPoolingImpl.hpp"
#include "aidge/backend/cpu/operator/MaxPoolingImpl.hpp"
......
/********************************************************************************
* Copyright (c) 2023 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#ifndef AIDGE_CPU_OPERATOR_ATAN_H_
#define AIDGE_CPU_OPERATOR_ATAN_H_
#include "aidge/backend/cpu/operator/OperatorImpl.hpp"
#include "aidge/operator/Atan.hpp"
#include "aidge/utils/Registrar.hpp"
#include "aidge/utils/Types.h"
#include "aidge/backend/cpu/data/GetCPUPtr.h"
#include <memory>
#include <vector>
namespace Aidge {
// Operator implementation entry point for the backend
using AtanImpl_cpu = OperatorImpl_cpu<Atan_Op,
void(const std::size_t, const void*, void*),
void(const std::size_t, const void*, const void*, void*)>;
// Implementation entry point registration to Operator
REGISTRAR(Atan_Op, "cpu", Aidge::AtanImpl_cpu::create);
} // namespace Aidge
#endif /* AIDGE_CPU_OPERATOR_ATAN_H_ */
/********************************************************************************
* Copyright (c) 2023 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#ifndef AIDGE_CPU_OPERATOR_ATANIMPL_KERNELS_H_
#define AIDGE_CPU_OPERATOR_ATANIMPL_KERNELS_H_
#include "aidge/utils/Registrar.hpp"
#include "aidge/backend/cpu/operator/AtanImpl.hpp"
#include <cmath> // For atan()
namespace Aidge {
template <class I, class O>
void AtanImpl_cpu_forward_kernel(std::size_t inputLenght,
const void* input_,
void* output_) {
const I* input = static_cast<const I*>(input_);
O* output = static_cast<O*>(output_);
for (size_t i = 0; i < inputLenght; ++i) {
output[i] = static_cast<O>(atan(input[i]));
}
}
template <class O, class GI, class GO>
void AtanImpl_cpu_backward_kernel(const std::size_t inputLenght,
const void* output_, const void* grad_output_,
void* grad_input_) {
const O* output = static_cast<const O*>(output_);
const GO* grad_output = static_cast<const GO*>(grad_output_);
GI* grad_input = static_cast<GI*>(grad_input_);
// Apply the derivative of atan for each element in the input array
for (size_t i = 0; i < inputLenght; ++i) {
// dx = dy * (1 / (1 + x^2))
grad_input[i] = grad_output[i] * static_cast<O>(1.0 / (1.0 + output[i] * output[i]));
}
}
// Kernels registration to implementation entry point
REGISTRAR(AtanImpl_cpu,
{DataType::Float32},
{ProdConso::inPlaceModel, Aidge::AtanImpl_cpu_forward_kernel<float, float>, Aidge::AtanImpl_cpu_backward_kernel<float, float, float>});
REGISTRAR(AtanImpl_cpu,
{DataType::Float64},
{ProdConso::inPlaceModel, Aidge::AtanImpl_cpu_forward_kernel<double, double>, Aidge::AtanImpl_cpu_backward_kernel<double, double, double>});
} // namespace Aidge
#endif /* AIDGE_CPU_OPERATOR_ATANIMPL_KERNELS_H_ */
......@@ -137,6 +137,7 @@ void ConvDepthWiseImpl2D_cpu_forward_kernel(const std::array<DimSize_t, 2>& stri
const std::size_t oxSize =
static_cast<std::size_t>(std::floor(static_cast<float>(inputDims[2] - dilated_kernel_x + strideDims[0]) /
static_cast<float>(strideDims[0])));
// output W size
const DimSize_t dilated_kernel_y = dilationDims[1]*(kernelDims[1] - 1) + 1;
const std::size_t oySize =
......
......@@ -96,11 +96,11 @@ void GridSampleImpl1D_cpu_forward_kernel(const GridSample_Op& op,
const std::shared_ptr<Tensor>& in1,
const std::shared_ptr<Tensor>& out)
{
const I* const input = static_cast<const I * const>(in0->getImpl()->rawPtr());
const I* const input = static_cast<const I *>(in0->getImpl()->rawPtr());
const I* input_ptr = input;
float* const grid = static_cast<float* const>(in1->getImpl()->rawPtr());
float* const grid = static_cast<float*>(in1->getImpl()->rawPtr());
float* grid_ptr = grid;
O* const output = static_cast<O* const>(out->getImpl()->rawPtr());
O* const output = static_cast<O*>(out->getImpl()->rawPtr());
O* output_ptr = output;
const std::size_t N = in0->dim(0);
......@@ -243,9 +243,9 @@ void GridSampleImpl2D_cpu_forward_kernel(const GridSample_Op& op,
{
const I* input = static_cast<const I *>(in0->getImpl()->rawPtr());
const I* input_ptr = input;
float* const grid = static_cast<float* const>(in0->getImpl()->rawPtr());
float* const grid = static_cast<float*>(in0->getImpl()->rawPtr());
float* grid_ptr = grid;
O* const output = static_cast<O* const>(out->getImpl()->rawPtr());
O* const output = static_cast<O*>(out->getImpl()->rawPtr());
const std::size_t N = in0->dim(0);
const std::size_t C = in0->dim(1);
......
......@@ -38,8 +38,10 @@ public:
return impl.prodConso(mOp);
}
virtual std::set<ImplSpec> getAvailableImplSpecs() const override {
return Registrar<OperatorImpl_cpu>::getKeys();
virtual std::vector<ImplSpec> getAvailableImplSpecs() const override {
// return Registrar<OperatorImpl_cpu>::getKeys(); // Note: cannot return set due to python binding
std::set<ImplSpec> implSpecsSet = Registrar<OperatorImpl_cpu>::getKeys();
return std::vector<ImplSpec>(implSpecsSet.begin(), implSpecsSet.end());
}
void forward() override;
......
/********************************************************************************
* Copyright (c) 2023 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#include <cassert>
#include <chrono> // std::chrono::milliseconds
#include <numeric> // std::accumulate
#include <thread> // std::this_thread::sleep_for
#include <vector>
#include "aidge/operator/Atan.hpp"
#include "aidge/utils/Types.h"
#include "aidge/backend/cpu/data/GetCPUPtr.h"
#include "aidge/backend/cpu/operator/AtanImpl.hpp"
#include "aidge/backend/cpu/operator/AtanImpl_kernels.hpp"
template <>
void Aidge::AtanImpl_cpu::forward() {
const Atan_Op& op_ = dynamic_cast<const Atan_Op&>(mOp);
std::shared_ptr<Tensor> in0 = op_.getInput(0);
std::shared_ptr<Tensor> out0 = op_.getOutput(0);
AIDGE_ASSERT(in0, "missing input #0");
// Find the correct kernel type
const auto impl = Registrar<AtanImpl_cpu>::create(getBestMatch(getRequiredSpec()));
// Call kernel
impl.forward(in0->size(),
getCPUPtr(mOp.getRawInput(0)),
getCPUPtr(mOp.getRawOutput(0)));
}
template <>
void Aidge::AtanImpl_cpu::backward() {
const Atan_Op& op_ = dynamic_cast<const Atan_Op&>(mOp);
std::shared_ptr<Tensor> out0 = op_.getOutput(0);
std::shared_ptr<Tensor> gra_int0 = op_.getInput(0)->grad();
std::shared_ptr<Tensor> gra_out0 = op_.getOutput(0)->grad();
AIDGE_ASSERT(out0, "missing output #0 for current {} operator", op_.type());
// Find the correct kernel type
const auto impl = Registrar<AtanImpl_cpu>::create(getBestMatch(getRequiredSpec()));
// Call kernel
impl.backward(gra_int0->size(), getCPUPtr(out0), getCPUPtr(gra_out0), getCPUPtr(gra_int0));
}
......@@ -35,7 +35,7 @@ TEST_CASE("Test addition of Tensors","[TensorImpl][Add]") {
std::uniform_int_distribution<int> boolDist(0,1);
// Create MatMul Operator
std::shared_ptr<Node> mySub = Add(2);
std::shared_ptr<Node> mySub = Add();
auto op = std::static_pointer_cast<OperatorTensor>(mySub-> getOperator());
op->setDataType(DataType::Float32);
op->setBackend("cpu");
......
......@@ -39,17 +39,6 @@ TEST_CASE("[cpu/operator] Add(forward)", "[Add][CPU]") {
} //
}); //
SECTION("One input") {
std::shared_ptr<Node> myAdd = Add(1);
auto op = std::static_pointer_cast<OperatorTensor>(myAdd -> getOperator());
op->associateInput(0, input1);
op->setBackend("cpu");
op->setDataType(DataType::Int32);
myAdd->forward();
REQUIRE(*(op->getOutput(0)) == *input1);
}
SECTION("Two inputs") {
std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>(Array4D<int,3,3,3,2> {
{
......@@ -71,7 +60,7 @@ TEST_CASE("[cpu/operator] Add(forward)", "[Add][CPU]") {
}
});
std::shared_ptr<Node> myAdd = Add(2);
std::shared_ptr<Node> myAdd = Add();
auto op = std::static_pointer_cast<OperatorTensor>(myAdd -> getOperator());
op->associateInput(0, input1);
op->associateInput(1, input1);
......@@ -82,39 +71,6 @@ TEST_CASE("[cpu/operator] Add(forward)", "[Add][CPU]") {
REQUIRE(*(op->getOutput(0)) == *expectedOutput);
}
SECTION("Three inputs") {
std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>(Array4D<int,3,3,3,2> {
{
{
{{ 60, 141},{ 63, 144},{ 66, 147}},
{{ 69, 150},{ 72, 153},{ 75, 156}},
{{ 78, 159},{ 81, 162},{ 84, 165}}
},
{
{{ 87, 168},{ 90, 171},{ 93, 174}},
{{ 96, 177},{ 99, 180},{102, 183}},
{{105, 186},{108, 189},{111, 192}}
},
{
{{114, 195},{117, 198},{120, 201}},
{{123, 204},{126, 207},{129, 210}},
{{132, 213},{135, 216},{138, 219}}
}
}
});
std::shared_ptr<Node> myAdd = Add(3);
auto op = std::static_pointer_cast<OperatorTensor>(myAdd -> getOperator());
op->associateInput(0, input1);
op->associateInput(1, input1);
op->associateInput(2, input1);
op->setDataType(DataType::Int32);
op->setBackend("cpu");
myAdd->forward();
REQUIRE(*op->getOutput(0) == *expectedOutput);
}
SECTION("Broadcasting") {
std::shared_ptr<Tensor> input_0 = std::make_shared<Tensor>(Array4D<int,3,1,3,2> {
{ //
......@@ -139,7 +95,7 @@ TEST_CASE("[cpu/operator] Add(forward)", "[Add][CPU]") {
} //
}); //
std::shared_ptr<Tensor> input_2 = std::make_shared<Tensor>(Array1D<int,2> {{100,200}});
std::shared_ptr<Tensor> input_2 = std::make_shared<Tensor>(Array1D<int,2> {{100,200}});
std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>(Array4D<int,3,3,3,2> {
{ //
{ //
......@@ -160,16 +116,23 @@ TEST_CASE("[cpu/operator] Add(forward)", "[Add][CPU]") {
} //
}); //
std::shared_ptr<Node> myAdd = Add(3);
auto op = std::static_pointer_cast<OperatorTensor>(myAdd -> getOperator());
op->associateInput(0, input_0);
op->associateInput(1, input_1);
op->associateInput(2, input_2);
op->setDataType(DataType::Int32);
op->setBackend("cpu");
myAdd->forward();
op->getOutput(0)->print();
std::shared_ptr<Node> myAdd_0 = Add();
std::shared_ptr<Node> myAdd_1 = Add();
auto op_0 = std::static_pointer_cast<OperatorTensor>(myAdd_0 -> getOperator());
auto op_1 = std::static_pointer_cast<OperatorTensor>(myAdd_1 -> getOperator());
op_0->associateInput(0, input_0);
op_0->associateInput(1, input_1);
op_1->associateInput(0, input_2);
op_1->associateInput(1, op_0->getOutput(0));
op_0->setDataType(DataType::Int32);
op_1->setDataType(DataType::Int32);
op_0->setBackend("cpu");
op_1->setBackend("cpu");
myAdd_0->forward();
myAdd_1->forward();
op_1->getOutput(0)->print();
expectedOutput->print();
REQUIRE(*op->getOutput(0) == *expectedOutput);
REQUIRE(*op_1->getOutput(0) == *expectedOutput);
}
}
\ No newline at end of file
/********************************************************************************
* Copyright (c) 2023 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#include <catch2/catch_test_macros.hpp>
#include "aidge/data/Tensor.hpp"
#include "aidge/operator/Atan.hpp"
#include "aidge/backend/cpu.hpp"
#include <memory>
using namespace Aidge;
TEST_CASE("[cpu/operator] Atan(forward)") {
SECTION("1D Tensor") {
std::shared_ptr<Tensor> input0 =
std::make_shared<Tensor>(Array1D<float, 10>{
{0.41384590, 0.43120754, 0.93762982, 0.31049860, 0.77547199,
0.09514862, 0.16145366, 0.42776686, 0.43487436, 0.41170865}});
std::shared_ptr<Tensor> expectedOutput =
std::make_shared<Tensor>(Array1D<float, 10>{
{0.39238522, 0.40711672, 0.75322037, 0.30106049, 0.65960488,
0.09486303, 0.16007232, 0.40421187, 0.4102045, 0.39055911}});
std::shared_ptr<Node> myAtan = Atan();
auto op = std::static_pointer_cast<OperatorTensor>(myAtan->getOperator());
op->associateInput(0, input0);
op->setDataType(DataType::Float32);
op->setBackend("cpu");
myAtan->forward();
float* resPtr = static_cast<float*>(op->getOutput(0)->getImpl()->rawPtr());
float* expectedPtr =
static_cast<float*>(expectedOutput->getImpl()->rawPtr());
for (std::size_t i = 0; i < expectedOutput->size(); ++i) {
REQUIRE(std::abs(resPtr[i] - expectedPtr[i]) < 0.00001);
}
}
SECTION("3D Tensor") {
std::shared_ptr<Tensor> input0 = std::make_shared<Tensor>(
Array3D<float, 2, 2, 3>{{{
{0.97037154, 0.86208081, 0.77767169},
{0.38160080, 0.11422747, 0.77284443},
},
{{0.51592529, 0.72543722, 0.54641193},
{0.93866944, 0.97767913, 0.34172094}}}});
std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>(
Array3D<float, 2, 2, 3>{{{{0.77036231, 0.71146592, 0.66097706},
{0.36454508, 0.11373451, 0.65796196}},
{{0.47630652, 0.62759472, 0.50008428},
{0.75377332, 0.77411225, 0.32928031}}}});
std::shared_ptr<Node> myAtan = Atan();
auto op = std::static_pointer_cast<OperatorTensor>(myAtan->getOperator());
op->associateInput(0, input0);
op->setDataType(DataType::Float32);
op->setBackend("cpu");
myAtan->forward();
float* resPtr = static_cast<float*>(op->getOutput(0)->getImpl()->rawPtr());
float* expectedPtr =
static_cast<float*>(expectedOutput->getImpl()->rawPtr());
for (std::size_t i = 0; i < expectedOutput->size(); ++i) {
REQUIRE(std::abs(resPtr[i] - expectedPtr[i]) < 0.00001);
}
}
}
......@@ -22,12 +22,12 @@
using namespace Aidge;
TEST_CASE("[ConstantFolding] test") {
TEST_CASE("[ConstantFolding] forward", "[ConstantFolding][forward][CPU]") {
// generate the original GraphView
auto matmul0 = MatMul("matmul0");
auto add0 = Add(2, "add0");
auto add0 = Add("add0");
auto matmul1 = MatMul("matmul1");
auto add1 = Add(2, "add1");
auto add1 = Add("add1");
auto b0 = Producer(std::make_shared<Tensor>(Array1D<float,5>{{1, 2, 3, 4, 5}}), "B0", true);
auto w0 = Producer(std::make_shared<Tensor>(Array2D<float,5,5>{{{1, 2, 3, 4, 5}, {6, 7, 8, 9, 0}, {1, 2, 3, 4, 5}, {6, 7, 8, 9, 0}, {1, 2, 3, 4, 5}}}), "W0", true);
......
......@@ -147,10 +147,13 @@ TEST_CASE("[cpu/scheduler] SequentialScheduler(forward)") {
std::shared_ptr<GraphView> g =
Sequential({Conv(1, 3, {3, 3}, "inputConv"),
Parallel({
Conv(3, 3, {1, 1}, "conv1.1"),
Conv(3, 3, {1, 1}, "conv1.2"),
Sequential({
Parallel({
Conv(3, 3, {1, 1}, "conv1.1"),
Conv(3, 3, {1, 1}, "conv1.2")}),
Add("add1")}),
Conv(3, 3, {1, 1}, "conv1.3")}),
Add(3, "add1"),
Add("add2"),
Conv(3, 2, {1, 1}, "conv2"),
FC(18, 5, false, "out")});
......@@ -216,9 +219,9 @@ TEST_CASE("[cpu/scheduler] SequentialScheduler(forward)") {
std::shared_ptr<Tensor> biasTensor = std::make_shared<Tensor>(
Array2D<int, 2, 3>{{{2, 0, 0}, {1, 0, 0}}});
auto add1 = Add(2, "add1");
auto add1 = Add("add1");
auto mem = Memorize(3, "mem1");
auto add2 = Add(2, "add2");
auto add2 = Add("add2");
auto bias = Producer(biasTensor, "bias");
auto init = Producer(initTensor, "init");
auto input = Producer(in, "input");
......@@ -260,9 +263,9 @@ TEST_CASE("[cpu/scheduler] SequentialScheduler(forward)") {
std::shared_ptr<Tensor> biasTensor = std::make_shared<Tensor>(
Array2D<int, 2, 3>{{{2, 0, 0}, {1, 0, 0}}});
auto add1 = Add(2, "add1");
auto add1 = Add("add1");
auto mem = Memorize(3, "mem1");
auto add2 = Add(2, "add2");
auto add2 = Add("add2");
auto bias = Producer(biasTensor, "bias");
auto init = Producer(initTensor, "init");
auto input = Producer(in, "input");
......