Skip to content
Snippets Groups Projects
Commit 67a6da5c authored by Olivier BICHLER's avatar Olivier BICHLER
Browse files

Merged with dev

parents d6870770 07d50e6a
No related branches found
No related tags found
2 merge requests!50version 0.2.0,!45Improved scheduling
Pipeline #42534 failed
This commit is part of merge request !45. Comments created here will be created in the context of that merge request.
...@@ -9,27 +9,29 @@ ...@@ -9,27 +9,29 @@
* *
********************************************************************************/ ********************************************************************************/
#include <cassert> #include "aidge/backend/cpu/operator/GatherImpl.hpp"
#include <chrono> // std::chrono::milliseconds
#include <numeric> // std::accumulate #include <memory>
#include <thread> // std::this_thread::sleep_for
#include <vector> #include <vector>
#include "aidge/backend/cpu/operator/GatherImpl_forward_kernels.hpp"
#include "aidge/data/Data.hpp"
#include "aidge/data/Tensor.hpp"
#include "aidge/operator/Gather.hpp" #include "aidge/operator/Gather.hpp"
#include "aidge/utils/Types.h" #include "aidge/utils/Types.h"
#include "aidge/backend/cpu/operator/GatherImpl.hpp"
#include "aidge/backend/cpu/operator/GatherImpl_forward_kernels.hpp"
void Aidge::GatherImpl_cpu::forward() { void Aidge::GatherImpl_cpu::forward() {
const Gather_Op& op = static_cast<const Gather_Op&>(mOp);
auto kernelFunc = Registrar<GatherImplForward_cpu>::create({ auto kernelFunc = Registrar<GatherImplForward_cpu>::create({
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dataType(), op.getInput(0)->dataType(),
std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->dataType()}); op.getOutput(0)->dataType()
});
// Call kernel // Call kernel
kernelFunc(dynamic_cast<const Gather_Op&>(mOp).getStaticAttributes(), kernelFunc(dynamic_cast<const Gather_Op&>(mOp).getStaticAttributes(),
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dims(), op.getInput(0)->dims(),
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(), op.getInput(0)->getImpl()->rawPtr(),
std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr()); op.getOutput(0)->getImpl()->rawPtr()
);
} }
...@@ -10,17 +10,17 @@ ...@@ -10,17 +10,17 @@
********************************************************************************/ ********************************************************************************/
#include <cassert> #include <cassert>
#include <chrono> // std::chrono::milliseconds
#include <numeric> // std::accumulate
#include <thread> // std::this_thread::sleep_for
#include <vector> #include <vector>
#include "aidge/data/Tensor.hpp"
#include "aidge/operator/LeakyReLU.hpp" #include "aidge/operator/LeakyReLU.hpp"
#include "aidge/utils/Types.h" #include "aidge/utils/Types.h"
#include "aidge/utils/Registrar.hpp"
#include "aidge/backend/cpu/data/GetCPUPtr.h" #include "aidge/backend/cpu/data/GetCPUPtr.h"
#include "aidge/backend/cpu/operator/LeakyReLUImpl.hpp" #include "aidge/backend/cpu/operator/LeakyReLUImpl.hpp"
#include "aidge/backend/cpu/operator/LeakyReLUImpl_forward_kernels.hpp" #include "aidge/backend/cpu/operator/LeakyReLUImpl_forward_kernels.hpp"
#include "aidge/backend/cpu/operator/LeakyReLUImpl_backward_kernels.hpp"
Aidge::Elts_t Aidge::LeakyReLUImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const { Aidge::Elts_t Aidge::LeakyReLUImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
// this implementation can be in-place // this implementation can be in-place
...@@ -28,16 +28,38 @@ Aidge::Elts_t Aidge::LeakyReLUImpl_cpu::getNbRequiredProtected(const Aidge::IOIn ...@@ -28,16 +28,38 @@ Aidge::Elts_t Aidge::LeakyReLUImpl_cpu::getNbRequiredProtected(const Aidge::IOIn
} }
void Aidge::LeakyReLUImpl_cpu::forward() { void Aidge::LeakyReLUImpl_cpu::forward() {
assert(std::static_pointer_cast<Tensor>(mOp.getRawInput(0)) && "missing input #0"); const LeakyReLU_Op& op_ = dynamic_cast<const LeakyReLU_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 // Find the correct kernel type
auto kernelFunc = Registrar<LeakyReLUImplForward_cpu>::create({ auto kernelFunc = Registrar<LeakyReLUImplForward_cpu>::create({
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dataType(), in0->dataType(),
std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->dataType()}); out0->dataType()});
// Call kernel // Call kernel
kernelFunc(dynamic_cast<const LeakyReLU_Op&>(mOp).getStaticAttributes(), kernelFunc(dynamic_cast<const LeakyReLU_Op&>(mOp).getStaticAttributes(),
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->size(), in0->size(),
getCPUPtr(mOp.getRawInput(0)), getCPUPtr(mOp.getRawInput(0)),
getCPUPtr(mOp.getRawOutput(0))); getCPUPtr(mOp.getRawOutput(0)));
} }
void Aidge::LeakyReLUImpl_cpu::backward() {
// reversing in and out Data for backprop
const LeakyReLU_Op& op_ = dynamic_cast<const LeakyReLU_Op&>(mOp);
std::shared_ptr<Tensor> in0 = op_.getOutput(0)->grad();
std::shared_ptr<Tensor> out0 = op_.getInput(0)->grad();
AIDGE_ASSERT(in0, "missing input #0");
// Find the correct kernel type
auto kernelFunc = Registrar<LeakyReLUImplForward_cpu>::create({
in0->dataType(),
out0->dataType()});
// Call kernel
kernelFunc(dynamic_cast<const LeakyReLU_Op&>(mOp).getStaticAttributes(),
in0->size(),
getCPUPtr(in0),
getCPUPtr(out0));
}
\ No newline at end of file
...@@ -48,3 +48,25 @@ void Aidge::PowImpl_cpu::forward() { ...@@ -48,3 +48,25 @@ void Aidge::PowImpl_cpu::forward() {
getCPUPtr(mOp.getRawInput(1)), getCPUPtr(mOp.getRawInput(1)),
getCPUPtr(mOp.getRawOutput(0))); getCPUPtr(mOp.getRawOutput(0)));
} }
void Aidge::PowImpl_cpu::backward() {
// Find the correct kernel type
const Pow_Op& op_ = dynamic_cast<const Pow_Op&>(mOp);
auto kernelFunc = Registrar<PowImplForward_cpu>::create({
op_.getOutput(0)->grad()->dataType(),
op_.getInput(0)->grad()->dataType(),
op_.getInput(1)->grad()->dataType()});
const std::vector<std::size_t> input0gradDims = getBroadcastedDims(op_.getInput(0)->grad()->dims(),
op_.getOutput(0)->grad()->dims());
const std::vector<std::size_t> input1gradDims = getBroadcastedDims(op_.getInput(1)->grad()->dims(),
op_.getOutput(0)->grad()->dims());
// Call kernel
kernelFunc(op_.getOutput(0)->grad()->dims(),
input0gradDims,
input1gradDims,
getCPUPtr(mOp.getRawOutput(0)),
getCPUPtr(mOp.getRawInput(0)),
getCPUPtr(mOp.getRawInput(1)));
}
\ No newline at end of file
...@@ -9,18 +9,18 @@ ...@@ -9,18 +9,18 @@
* *
********************************************************************************/ ********************************************************************************/
#include <cassert> #include <memory>
#include <chrono> // std::chrono::milliseconds
#include <numeric> // std::accumulate
#include <thread> // std::this_thread::sleep_for
#include <vector> #include <vector>
#include "aidge/data/Tensor.hpp"
#include "aidge/operator/ReLU.hpp" #include "aidge/operator/ReLU.hpp"
#include "aidge/utils/Types.h" #include "aidge/utils/Types.h"
#include "aidge/backend/cpu/data/GetCPUPtr.h" #include "aidge/backend/cpu/data/GetCPUPtr.h"
#include "aidge/utils/ErrorHandling.hpp"
#include "aidge/backend/cpu/operator/ReLUImpl.hpp" #include "aidge/backend/cpu/operator/ReLUImpl.hpp"
#include "aidge/backend/cpu/operator/ReLUImpl_forward_kernels.hpp" #include "aidge/backend/cpu/operator/ReLUImpl_forward_kernels.hpp"
#include "aidge/backend/cpu/operator/ReLUImpl_backward_kernels.hpp"
Aidge::Elts_t Aidge::ReLUImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const { Aidge::Elts_t Aidge::ReLUImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
// this implementation can be in-place // this implementation can be in-place
...@@ -28,15 +28,33 @@ Aidge::Elts_t Aidge::ReLUImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t ...@@ -28,15 +28,33 @@ Aidge::Elts_t Aidge::ReLUImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t
} }
void Aidge::ReLUImpl_cpu::forward() { void Aidge::ReLUImpl_cpu::forward() {
assert(std::static_pointer_cast<Tensor>(mOp.getRawInput(0)) && "missing input #0"); std::shared_ptr<Tensor> in0 = std::static_pointer_cast<Tensor>(mOp.getRawInput(0));
AIDGE_ASSERT(in0, "missing input #0");
// Find the correct kernel type // Find the correct kernel type
auto kernelFunc = Registrar<ReLUImplForward_cpu>::create({ auto kernelFunc = Registrar<ReLUImplForward_cpu>::create({
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dataType(), in0->dataType(),
std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->dataType()}); std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->dataType()});
// Call kernel // Call kernel
kernelFunc(std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->size(), kernelFunc(in0->size(),
getCPUPtr(mOp.getRawInput(0)), getCPUPtr(mOp.getRawInput(0)),
getCPUPtr(mOp.getRawOutput(0))); getCPUPtr(mOp.getRawOutput(0)));
} }
void Aidge::ReLUImpl_cpu::backward() {
// reversing in and out Tensors
const ReLU_Op& op_ = dynamic_cast<const ReLU_Op&>(mOp);
std::shared_ptr<Tensor> in0 = op_.getOutput(0)->grad();
std::shared_ptr<Tensor> out0 = op_.getInput(0)->grad();
AIDGE_ASSERT(out0, "current {} operator output#0 has not gradient Tensor.", op_.type());
// Find the correct kernel type
auto kernelFunc = Registrar<ReLUImplBackward_cpu>::create({
in0->dataType(),
out0->dataType()
});
// Call kernel
kernelFunc(in0->size(), getCPUPtr(in0), getCPUPtr(out0));
}
...@@ -9,59 +9,70 @@ ...@@ -9,59 +9,70 @@
* *
********************************************************************************/ ********************************************************************************/
#include <cassert> #include "aidge/backend/cpu/operator/ReduceMeanImpl.hpp"
#include <chrono> // std::chrono::milliseconds
#include <numeric> // std::accumulate #include <memory>
#include <thread> // std::this_thread::sleep_for
#include <vector> #include <vector>
#include "aidge/utils/Types.h" #include "aidge/utils/Types.h"
#include "aidge/operator/ReduceMean.hpp" #include "aidge/operator/ReduceMean.hpp"
#include "aidge/backend/cpu/operator/ReduceMeanImpl.hpp"
#include "aidge/backend/cpu/operator/ReduceMeanImpl_forward_kernels.hpp" #include "aidge/backend/cpu/operator/ReduceMeanImpl_forward_kernels.hpp"
void Aidge::ReduceMeanImpl1D_cpu::forward() { void Aidge::ReduceMeanImpl_cpu::forward() {
const ReduceMean_Op& op_ = dynamic_cast<const ReduceMean_Op&>(mOp);
// Find the correct kernel type // Find the correct kernel type
auto kernelFunc = auto kernelFunc = Registrar<ReduceMeanImplForward_cpu>::create({
Registrar<ReduceMeanImpl1DForward_cpu>::create({ op_.getInput(0)->dataType(),
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dataType(), op_.getOutput(0)->dataType()});
std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->dataType()});
// Call kernel // Call kernel
kernelFunc(dynamic_cast<const ReduceMean_Op<1>&>(mOp).getStaticAttributes(), kernelFunc(op_.getStaticAttributes(),
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dims(), op_.getInput(0)->dims(),
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(), op_.getInput(0)->getImpl()->rawPtr(),
std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr()); op_.getOutput(0)->getImpl()->rawPtr());
} }
void Aidge::ReduceMeanImpl2D_cpu::forward() { // void Aidge::ReduceMeanImpl1D_cpu::forward() {
// Find the correct kernel type // // Find the correct kernel type
auto kernelFunc = // auto kernelFunc =
Registrar<ReduceMeanImpl2DForward_cpu>::create({ // Registrar<ReduceMeanImpl1DForward_cpu>::create({
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dataType(), // std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dataType(),
std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->dataType()}); // std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->dataType()});
// Call kernel // // Call kernel
kernelFunc(dynamic_cast<const ReduceMean_Op<2>&>(mOp).getStaticAttributes(), // kernelFunc(dynamic_cast<const ReduceMean_Op<1>&>(mOp).getStaticAttributes(),
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dims(), // std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dims(),
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(), // std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr()); // std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
} // }
void Aidge::ReduceMeanImpl3D_cpu::forward() { // void Aidge::ReduceMeanImpl2D_cpu::forward() {
// Find the correct kernel type // // Find the correct kernel type
auto kernelFunc = // auto kernelFunc =
Registrar<ReduceMeanImpl3DForward_cpu>::create({ // Registrar<ReduceMeanImpl2DForward_cpu>::create({
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dataType(), // std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dataType(),
std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->dataType()}); // std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->dataType()});
// Call kernel // // Call kernel
kernelFunc(dynamic_cast<const ReduceMean_Op<3>&>(mOp).getStaticAttributes(), // kernelFunc(dynamic_cast<const ReduceMean_Op<2>&>(mOp).getStaticAttributes(),
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dims(), // std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dims(),
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(), // std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr()); // std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
} // }
\ No newline at end of file
// void Aidge::ReduceMeanImpl3D_cpu::forward() {
// // Find the correct kernel type
// auto kernelFunc =
// Registrar<ReduceMeanImpl3DForward_cpu>::create({
// std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dataType(),
// std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->dataType()});
// // Call kernel
// kernelFunc(dynamic_cast<const ReduceMean_Op<3>&>(mOp).getStaticAttributes(),
// std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dims(),
// std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
// std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
// }
\ No newline at end of file
...@@ -9,13 +9,13 @@ ...@@ -9,13 +9,13 @@
* *
********************************************************************************/ ********************************************************************************/
#include <cassert> #include "aidge/backend/cpu/operator/ReshapeImpl.hpp"
#include "aidge/backend/cpu/operator/ReshapeImpl_forward_kernels.hpp"
#include "aidge/data/Tensor.hpp"
#include "aidge/operator/Reshape.hpp" #include "aidge/operator/Reshape.hpp"
#include "aidge/utils/Types.h" #include "aidge/utils/Types.h"
#include "aidge/utils/ErrorHandling.hpp"
#include "aidge/backend/cpu/operator/ReshapeImpl.hpp"
#include "aidge/backend/cpu/operator/ReshapeImpl_forward_kernels.hpp"
Aidge::Elts_t Aidge::ReshapeImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const { Aidge::Elts_t Aidge::ReshapeImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
// this implementation can be in-place // this implementation can be in-place
...@@ -23,17 +23,17 @@ Aidge::Elts_t Aidge::ReshapeImpl_cpu::getNbRequiredProtected(const Aidge::IOInde ...@@ -23,17 +23,17 @@ Aidge::Elts_t Aidge::ReshapeImpl_cpu::getNbRequiredProtected(const Aidge::IOInde
} }
void Aidge::ReshapeImpl_cpu::forward() { void Aidge::ReshapeImpl_cpu::forward() {
assert(std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->size() == const Reshape_Op& op_ = static_cast<const Reshape_Op&>(mOp);
std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->size() AIDGE_ASSERT(op_.getInput(0)->size() == op_.getOutput(0)->size(),
&& "input must have the same overall size as shape"); "input must have the same overall size as shape");
// Find the correct kernel type // Find the correct kernel type
auto kernelFunc = Registrar<ReshapeImplForward_cpu>::create({ auto kernelFunc = Registrar<ReshapeImplForward_cpu>::create({
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dataType(), op_.getInput(0)->dataType(),
std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->dataType()}); op_.getOutput(0)->dataType()});
// Call kernel // Call kernel
kernelFunc(std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->size(), kernelFunc(op_.getInput(0)->size(),
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(), op_.getInput(0)->getImpl()->rawPtr(),
std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr()); op_.getOutput(0)->getImpl()->rawPtr());
} }
...@@ -9,18 +9,18 @@ ...@@ -9,18 +9,18 @@
* *
********************************************************************************/ ********************************************************************************/
#include <cassert> #include <memory>
#include <chrono> // std::chrono::milliseconds
#include <numeric> // std::accumulate
#include <thread> // std::this_thread::sleep_for
#include <vector> #include <vector>
#include "aidge/backend/cpu/data/GetCPUPtr.h"
#include "aidge/data/Tensor.hpp"
#include "aidge/operator/Sqrt.hpp" #include "aidge/operator/Sqrt.hpp"
#include "aidge/utils/ErrorHandling.hpp"
#include "aidge/utils/Types.h" #include "aidge/utils/Types.h"
#include "aidge/backend/cpu/data/GetCPUPtr.h"
#include "aidge/backend/cpu/operator/SqrtImpl.hpp" #include "aidge/backend/cpu/operator/SqrtImpl.hpp"
#include "aidge/backend/cpu/operator/SqrtImpl_forward_kernels.hpp" #include "aidge/backend/cpu/operator/SqrtImpl_forward_kernels.hpp"
#include "aidge/backend/cpu/operator/SqrtImpl_backward_kernels.hpp"
Aidge::Elts_t Aidge::SqrtImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const { Aidge::Elts_t Aidge::SqrtImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
// this implementation can be in-place // this implementation can be in-place
...@@ -28,15 +28,35 @@ Aidge::Elts_t Aidge::SqrtImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t ...@@ -28,15 +28,35 @@ Aidge::Elts_t Aidge::SqrtImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t
} }
void Aidge::SqrtImpl_cpu::forward() { void Aidge::SqrtImpl_cpu::forward() {
assert(std::static_pointer_cast<Tensor>(mOp.getRawInput(0)) && "missing input #0"); std::shared_ptr<Tensor> in0 = std::static_pointer_cast<Tensor>(mOp.getRawInput(0));
std::shared_ptr<Tensor> out0 = std::static_pointer_cast<Tensor>(mOp.getRawOutput(0));
AIDGE_ASSERT(in0, "missing input #0");
// Find the correct kernel type // Find the correct kernel type
auto kernelFunc = Registrar<SqrtImplForward_cpu>::create({ auto kernelFunc = Registrar<SqrtImplForward_cpu>::create({
std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dataType(), in0->dataType(),
std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->dataType()}); out0->dataType()});
// Call kernel // Call kernel
kernelFunc(std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->size(), kernelFunc(in0->size(),
getCPUPtr(mOp.getRawInput(0)), getCPUPtr(mOp.getRawInput(0)),
getCPUPtr(mOp.getRawOutput(0))); getCPUPtr(mOp.getRawOutput(0)));
}
void Aidge::SqrtImpl_cpu::backward() {
// reversing in and out Data for backprop
const Sqrt_Op& op_ = dynamic_cast<const Sqrt_Op&>(mOp);
std::shared_ptr<Tensor> out0grad = op_.getOutput(0)->grad();
std::shared_ptr<Tensor> in0grad = op_.getInput(0)->grad();
AIDGE_ASSERT(out0grad, "missing output #0");
// Find the correct kernel type
auto kernelFunc = Registrar<SqrtImplForward_cpu>::create({
out0grad->dataType(),
in0grad->dataType()});
// Call kernel
kernelFunc(out0grad->size(),
getCPUPtr(out0grad),
getCPUPtr(in0grad));
} }
\ 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 <cstddef> // std::size_t
#include <cstdint> // std::uint16_t
#include <chrono>
#include <iostream>
#include <memory>
#include <numeric> // std::accumulate
#include <random> // std::random_device, std::mt19937, std::uniform_real_distribution
#include "aidge/data/Tensor.hpp"
#include "aidge/backend/cpu/data/TensorImpl.hpp"
#include "aidge/operator/Add.hpp"
#include "aidge/backend/cpu/operator/AddImpl.hpp"
namespace Aidge {
TEST_CASE("Test addition of Tensors","[TensorImpl][Add]") {
constexpr std::uint16_t NBTRIALS = 10;
// Create a random number generator
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<float> valueDist(0.1f, 1.1f); // Random float distribution between 0 and 1
std::uniform_int_distribution<std::size_t> dimSizeDist(std::size_t(2), std::size_t(10));
std::uniform_int_distribution<int> boolDist(0,1);
// Create MatMul Operator
std::shared_ptr<Node> mySub = Add(2);
auto op = std::static_pointer_cast<OperatorTensor>(mySub-> getOperator());
op->setDataType(DataType::Float32);
op->setBackend("cpu");
// Create 2 input Tensors
std::shared_ptr<Tensor> T0 = std::make_shared<Tensor>();
op->associateInput(0,T0);
T0->setDataType(DataType::Float32);
T0->setBackend("cpu");
std::shared_ptr<Tensor> T1 = std::make_shared<Tensor>();
op -> associateInput(1,T1);
T1->setDataType(DataType::Float32);
T1->setBackend("cpu");
// Create results Tensor
Tensor Tres{};
Tres.setDataType(DataType::Float32);
Tres.setBackend("cpu");
// To measure execution time of 'MatMul_Op::forward()' member function call
std::chrono::time_point<std::chrono::system_clock> start;
std::chrono::time_point<std::chrono::system_clock> end;
std::chrono::duration<double, std::micro> duration{};
std::size_t number_of_operation = 0;
for (std::uint16_t trial = 0; trial < NBTRIALS; ++trial) {
// generate 2 random Tensors
// handle dimensions, replace some dimensions with '1' to get broadcasting
constexpr std::size_t nbDims = 4;
std::vector<std::size_t> dims;
for (std::size_t i = 0; i < nbDims; ++i) {
dims.push_back(dimSizeDist(gen));
}
std::vector<std::size_t> dims0 = dims;
std::vector<std::size_t> dims1 = dims;
std::vector<std::size_t> dimsOut = dims;
for (std::size_t i = 0; i < nbDims; ++i) {
if (boolDist(gen)) {
dims0[i] = 1;
}
if (boolDist(gen)) {
dims1[i] = 1;
}
dimsOut[i] = (dims0[i] == 1) ? dims1[i] : dims0[i];
}
// create arrays and fill them with random values
float* array0 = new float[dims0[0]*dims0[1]*dims0[2]*dims0[3]];
float* array1 = new float[dims1[0]*dims1[1]*dims1[2]*dims1[3]];
float* result = new float[dimsOut[0]*dimsOut[1]*dimsOut[2]*dimsOut[3]];
for (std::size_t i = 0; i < dims0[0]*dims0[1]*dims0[2]*dims0[3]; ++i) {
array0[i] = valueDist(gen);
}
for (std::size_t i = 0; i < dims1[0]*dims1[1]*dims1[2]*dims1[3]; ++i) {
array1[i] = valueDist(gen);
}
// compute true result
const std::size_t strides0[nbDims] = {dims0[1]*dims0[2]*dims0[3], dims0[2]*dims0[3], dims0[3], 1};
const std::size_t strides1[nbDims] = {dims1[1]*dims1[2]*dims1[3], dims1[2]*dims1[3], dims1[3], 1};
for (std::size_t a = 0; a < dimsOut[0]; ++a) {
for (std::size_t b = 0; b < dimsOut[1]; ++b) {
const std::size_t idx0_0 = strides0[0] * ((dims0[0] > 1) ? a : 0)
+ strides0[1] * ((dims0[1] > 1) ? b : 0);
const std::size_t idx1_0 = strides1[0] * ((dims1[0] > 1) ? a : 0)
+ strides1[1] * ((dims1[1] > 1) ? b : 0);
for (std::size_t c = 0; c < dimsOut[2]; ++c) {
const std::size_t idx_out = dimsOut[3] * (c + dimsOut[2] * (b + dimsOut[1] * a));
for (std::size_t d = 0; d < dimsOut[3]; ++d) {
std::size_t idx0 = idx0_0
+ strides0[2] * ((dims0[2] > 1) ? c : 0)
+ ((dims0[3] > 1) ? d : 0);
std::size_t idx1 = idx1_0
+ strides1[2] * ((dims1[2] > 1) ? c : 0)
+ ((dims1[3] > 1) ? d : 0);
result[idx_out + d] = array0[idx0] + array1[idx1];
// std::cout << "(" << idx0 << ", " << idx1 << ") -> " << array0[idx0] << " - " << array1[idx1] << " -> " << idx_out + d << std::endl;
}
}
}
}
// conversion to Aidge::Tensors
// input0
T0->resize(dims0);
T0->getImpl() -> setRawPtr(array0, dims0[0]*dims0[1]*dims0[2]*dims0[3]);
// input1
T1->resize(dims1);
T1->getImpl() -> setRawPtr(array1, dims1[0]*dims1[1]*dims1[2]*dims1[3]);
// results
Tres.resize(dimsOut);
Tres.getImpl() -> setRawPtr(result, dimsOut[0]*dimsOut[1]*dimsOut[2]*dimsOut[3]);
Tensor T2 = *T0 + *T1;
REQUIRE(T2 == Tres);
// no implementation
Tensor T3(T1->dims());
REQUIRE_THROWS(*T0 + T3);
// // wrong backend
// static Registrar<Add_Op> registrarAddImpl_custom("custom", [](const Add_Op& op) { return std::make_unique<AddImpl_cpu>(op); } );
// static Registrar<Tensor> registrarTensorImpl_custom_Int32({"custom", DataType::Int32},
// [] (DeviceIdx_t device, std::vector<DimSize_t> dims) {
// return std::make_shared<TensorImpl_cpu<int>>(device, dims);
// }
// );
// T1.setBackend("custom");
// REQUIRE_THROWS(T0 + T1);
// wrong datatype
Tensor T4(T1->dims());
T4.setDataType(DataType::Float64);
REQUIRE_THROWS(*T0 + T4);
}
}
TEST_CASE("Test substraction of Tensors","[TensorImpl][Sub]") {
Tensor T0 = Array3D<int, 2, 2, 2>{{{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}}};
Tensor T1 = Array3D<int, 2, 2, 2>{{{{7, 1}, {3, 7}}, {{54, 0}, {7, 12}}}};
Tensor T2 = T0 - T1;
T2.print();
REQUIRE(T2 == Tensor(Array3D<int, 2, 2, 2>{{{{-6,1},{0,-3}},{{-49,6},{0,-4}}}}));
Tensor T3(T1.dims());
REQUIRE_THROWS(T0 - T3);
}
TEST_CASE("Test multiplication of Tensors","[TensorImpl][Mul]") {
Tensor T0 = Array3D<int, 2, 2, 2>{{{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}}};
Tensor T1 = Array3D<int, 2, 2, 2>{{{{7, 2}, {3, 7}}, {{5, 6}, {7, 8}}}};
Tensor T2 = T0 * T1;
T2.print();
REQUIRE(T2 == Tensor(Array3D<int, 2, 2, 2>{{{{7,4},{9,28}},{{25,36},{49,64}}}}));
Tensor T3(T1.dims());
REQUIRE_THROWS(T0 * T3);
}
TEST_CASE("Test division of Tensors","[TensorImpl][Div]") {
Tensor T0 = Array3D<int, 2, 2, 2>{{{{7,4},{9,28}},{{25,36},{49,64}}}};
Tensor T1 = Array3D<int, 2, 2, 2>{{{{7, 2}, {3, 7}}, {{5, 6}, {7, 8}}}};
Tensor T2 = T0 / T1;
T2.print();
REQUIRE(T2 == Tensor(Array3D<int, 2, 2, 2>{{{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}}}));
Tensor T3(T1.dims());
REQUIRE_THROWS(T0 / T3);
}
} // namespace Aidge
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "aidge/operator/Conv.hpp" #include "aidge/operator/Conv.hpp"
#include "aidge/backend/cpu.hpp" #include "aidge/backend/cpu.hpp"
#include "aidge/utils/TensorUtils.hpp"
using namespace Aidge; using namespace Aidge;
...@@ -138,35 +139,60 @@ TEST_CASE("[cpu/operator] ReduceMean(forward)", "[ReduceMean][CPU]") { ...@@ -138,35 +139,60 @@ TEST_CASE("[cpu/operator] ReduceMean(forward)", "[ReduceMean][CPU]") {
} }
SECTION("all_axes") { SECTION("all_axes") {
std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(Array3D<float,3,2,2> { SECTION("1") {
{ std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(Array3D<float,3,2,2> {
{
{ 5.0, 1.0 },
{ 20.0, 2.0 }
},
{
{ 30.0, 1.0 },
{ 40.0, 2.0 }
},
{ {
{ 55.0, 1.0 }, {
{ 60.0, 2.0 } { 5.0, 1.0 },
{ 20.0, 2.0 }
},
{
{ 30.0, 1.0 },
{ 40.0, 2.0 }
},
{
{ 55.0, 1.0 },
{ 60.0, 2.0 }
}
} }
} });
}); std::shared_ptr<Tensor> myOutput = std::make_shared<Tensor>(Array1D<float,1> {
std::shared_ptr<Tensor> myOutput = std::make_shared<Tensor>(Array1D<float,1> { {18.25}
{18.25} });
});
std::shared_ptr<Node> myReduceMean = ReduceMean({0, 1, 2}, 0); std::shared_ptr<Node> myReduceMean = ReduceMean({0, 1, 2}, 0);
auto op = std::static_pointer_cast<OperatorTensor>(myReduceMean -> getOperator()); auto op = std::static_pointer_cast<OperatorTensor>(myReduceMean -> getOperator());
op->associateInput(0,myInput); op->associateInput(0,myInput);
op->setDataType(DataType::Float32); op->setDataType(DataType::Float32);
op->setBackend("cpu"); op->setBackend("cpu");
op->computeOutputDims(); op->computeOutputDims();
myReduceMean->forward(); myReduceMean->forward();
op->getOutput(0)->print(); op->getOutput(0)->print();
REQUIRE(*(op->getOutput(0)) == *myOutput); REQUIRE(*(op->getOutput(0)) == *myOutput);
}
SECTION("2") {
std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(Array2D<float,5,4> {
{{ 0.004232f, 0.105120f, 0.045124f, 0.009205f},
{ 0.000766f, 0.272162f, 0.503560f, 0.044163f},
{ 0.049755f, 0.000305f, 0.143634f, 0.013253f},
{ 0.096258f, 0.311231f, 0.358143f, 0.000452f},
{ 0.468617f, 0.015693f, 0.145316f, 0.000105f}}
});
std::shared_ptr<Tensor> myOutput = std::make_shared<Tensor>(Array1D<float,1> {
{0.1293547f}
});
std::shared_ptr<Node> myReduceMean = ReduceMean({0, 1}, 0);
auto op = std::static_pointer_cast<OperatorTensor>(myReduceMean -> getOperator());
op->associateInput(0,myInput);
op->setDataType(DataType::Float32);
op->setBackend("cpu");
op->computeOutputDims();
myReduceMean->forward();
op->getOutput(0)->print();
// approxEq<float>(*(op->getOutput(0)), *myOutput);
REQUIRE(approxEq<float>(*(op->getOutput(0)), *myOutput));
}
} }
} }
\ No newline at end of file
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "aidge/scheduler/ParallelScheduler.hpp" #include "aidge/scheduler/ParallelScheduler.hpp"
#include "aidge/backend/cpu.hpp" #include "aidge/backend/cpu.hpp"
#include "aidge/recipes/GraphViewHelper.hpp"
using namespace Aidge; using namespace Aidge;
...@@ -346,7 +347,7 @@ TEST_CASE("[cpu/scheduler] SequentialScheduler(forward)") { ...@@ -346,7 +347,7 @@ TEST_CASE("[cpu/scheduler] SequentialScheduler(forward)") {
std::vector<std::shared_ptr<Aidge::Tensor>> dataIn = {inputTensor}; std::vector<std::shared_ptr<Aidge::Tensor>> dataIn = {inputTensor};
REQUIRE_NOTHROW(scheduler.forward(true, dataIn)); REQUIRE_NOTHROW(scheduler.forward(true, dataIn));
scheduler.saveSchedulingDiagram("schedulingSequential"); scheduler.saveSchedulingDiagram("schedulingSequential");
std::shared_ptr<Tensor> expectedOutput1 = std::make_shared<Tensor>(Array4D<int, 2, 3, 3, 3>{ std::shared_ptr<Tensor> expectedOutput1 = std::make_shared<Tensor>(Array4D<int, 2, 3, 3, 3>{
...@@ -391,4 +392,45 @@ TEST_CASE("[cpu/scheduler] SequentialScheduler(forward)") { ...@@ -391,4 +392,45 @@ TEST_CASE("[cpu/scheduler] SequentialScheduler(forward)") {
bool equal4 = (*other4 == expectedOutput4); bool equal4 = (*other4 == expectedOutput4);
REQUIRE(equal4); REQUIRE(equal4);
} }
}
TEST_CASE("[cpu/scheduler] SequentialScheduler(backward)", "[scheduler][backward]") {
// create GraphView
std::shared_ptr<GraphView> gv = Sequential({ReLU("relu0"), Sqrt("srqt0"), ReLU("relu1")});
std::shared_ptr<Tensor> inputTensor =
std::make_shared<Tensor>(Array4D<float, 2, 1, 5, 5>{{{{{0.0f, 1.0f, 2.0f, 3.0f, 4.0f},
{5.0f, 6.0f, 7.0f, 8.0f, 9.0f},
{10.0f, 11.0f, 12.0f, 13.0f, 14.0f},
{15.0f, 16.0f, 17.0f, 18.0f, 19.0f},
{20.0f, 21.0f, 22.0f, 23.0f, 24.0f}}},
{{{25.0f, 26.0f, 27.0f, 28.0f, 29.0f},
{30.0f, 31.0f, 32.0f, 33.0f, 34.0f},
{35.0f, 36.0f, 37.0f, 38.0f, 39.0f},
{40.0f, 41.0f, 42.0f, 43.0f, 44.0f},
{45.0f, 46.0f, 47.0f, 48.0f, 49.0f}}}}});
auto label = inputTensor;
// implem already set to default
auto myProd = Producer(inputTensor, "prod");
myProd -> addChild(gv);
gv -> compile("cpu", DataType::Float32);
compile_gradient(gv);
SequentialScheduler scheduler(gv);
scheduler.forward();
auto predictedOutput = gv->getOrderedOutputs()[0].first;
std::shared_ptr<Tensor> targetOutput =
std::make_shared<Tensor>(Array4D<float, 2, 1, 5, 5>{{{{{0.0f, 1.0f, 1.0f, 2.0f, 2.0f},
{2.0f, 2.0f, 3.0f, 3.0f, 3.0f},
{3.0f, 3.0f, 3.0f, 4.0f, 4.0f},
{4.0f, 4.0f, 4.0f, 4.0f, 4.0f},
{4.0f, 5.0f, 5.0f, 5.0f, 5.0f}}},
{{{5.0f, 5.0f, 5.0f, 5.0f, 5.0f},
{5.0f, 6.0f, 6.0f, 6.0f, 6.0f},
{6.0f, 6.0f, 6.0f, 6.0f, 6.0f},
{6.0f, 6.0f, 6.0f, 7.0f, 7.0f},
{7.0f, 7.0f, 7.0f, 7.0f, 7.0f}}}}});
REQUIRE_NOTHROW(scheduler.backward({targetOutput}));
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment