Skip to content
Snippets Groups Projects
Commit df820e6a authored by Noam Zerah's avatar Noam Zerah
Browse files

Adding of backward compatibility for Clip operator

parent 34b83b0d
No related branches found
No related tags found
No related merge requests found
Pipeline #55175 failed
...@@ -31,10 +31,10 @@ class ClipImplForward_cpu ...@@ -31,10 +31,10 @@ class ClipImplForward_cpu
std::tuple<DataType, DataType,DataType>, std::tuple<DataType, DataType,DataType>,
void(const void*, const void*, const void*,const std::size_t, void*)>{}; void(const void*, const void*, const void*,const std::size_t, void*)>{};
/*class ClipImplBackward_cpu class ClipImplBackward_cpu
: public Registrable <ClipImplBackward_cpu, : public Registrable <ClipImplBackward_cpu,
std::tuple<DataType, DataType, DataType>, std::tuple<DataType, DataType, DataType, DataType, DataType>,
void(const float, const float, const std::size_t, const void*, const void*, void*)> {};*/ void(const void*, const void*, const std::size_t, const void*, const void*, void*)> {};
class ClipImpl_cpu : public OperatorImpl { class ClipImpl_cpu : public OperatorImpl {
public: public:
...@@ -48,7 +48,7 @@ public: ...@@ -48,7 +48,7 @@ public:
void forward() override final; void forward() override final;
//void backward() override final; void backward() override final;
}; };
namespace { namespace {
......
...@@ -11,42 +11,39 @@ ...@@ -11,42 +11,39 @@
#ifndef AIDGE_CPU_OPERATOR_CLIPIMPL_BACKWARD_KERNEL_H_ #ifndef AIDGE_CPU_OPERATOR_CLIPIMPL_BACKWARD_KERNEL_H_
#define AIDGE_CPU_OPERATOR_CLIPIMPL_BACKWARD_KERNEL_H_ #define AIDGE_CPU_OPERATOR_CLIPIMPL_BACKWARD_KERNEL_H_
#include <cstddef> // std::size_t
#include "aidge/backend/cpu/operator/ClipImpl.hpp" #include "aidge/backend/cpu/operator/ClipImpl.hpp"
#include "aidge/utils/Registrar.hpp" #include "aidge/utils/Registrar.hpp"
namespace Aidge { namespace Aidge {
template <class I, class GI, class GO> template <class I, class GI, class GO>
void ClipImpl_cpu_backward_kernel( void ClipImpl_cpu_backward_kernel(
const float min_, const void* min_,
const float max_, const void* max_,
const std::size_t length, const std::size_t length,
const void* input_, const void* input_,
const void* grad_output_, const void* grad_output_,
void* grad_input_) void* grad_input_)
{ {
const I min = static_cast<const I>(min_); const I* min = static_cast<const I*>(min_);
const I max = static_cast<const I>(max_); const I* max = static_cast<const I*>(max_);
const I* input = static_cast<const I*>(input_); const I* input = static_cast<const I*>(input_);
const GO* grad_output = static_cast<const GO*>(grad_output_); const GO* grad_output = static_cast<const GO*>(grad_output_);
GI* grad_input = static_cast<GI*>(grad_input_); GI* grad_input = static_cast<GI*>(grad_input_);
for (std::size_t i = 0; i < length; ++i) { for (std::size_t i = 0; i < length; ++i) {
grad_input[i] = ((input[i] > min) && (input[i] < max)) ? grad_output[i] : 0; grad_input[i] = ((input[i] > min[0]) && (input[i] < max[0])) ? grad_output[i] : 0;
} }
} }
namespace { namespace {
static Registrar<ClipImplBackward_cpu> registrarClipImplBackward_cpu_Float32( static Registrar<ClipImplBackward_cpu> registrarClipImplBackward_cpu_Float32(
{DataType::Float32, DataType::Float32, DataType::Float32}, {DataType::Float32, DataType::Float32, DataType::Float32,DataType::Float32,DataType::Float32},
Aidge::ClipImpl_cpu_backward_kernel<float, float, float>); Aidge::ClipImpl_cpu_backward_kernel<float, float, float>);
static Registrar<ClipImplBackward_cpu> registrarClipImplBackward_cpu_Int32( static Registrar<ClipImplBackward_cpu> registrarClipImplBackward_cpu_Int32(
{DataType::Int32, DataType::Int32, DataType::Int32}, {DataType::Int32, DataType::Int32, DataType::Int32, DataType::Int32, DataType::Int32},
Aidge::ClipImpl_cpu_backward_kernel<int, int, int>); Aidge::ClipImpl_cpu_backward_kernel<int, int, int>);
static Registrar<ClipImplBackward_cpu> registrarClipImplBackward_cpu_Float64( static Registrar<ClipImplBackward_cpu> registrarClipImplBackward_cpu_Float64(
{DataType::Float64, DataType::Float64, DataType::Float64}, {DataType::Float64, DataType::Float64, DataType::Float64, DataType::Float64, DataType::Float64},
Aidge::ClipImpl_cpu_backward_kernel<double, double, double>); Aidge::ClipImpl_cpu_backward_kernel<double, double, double>);
} // namespace } // namespace
} // namespace Aidge } // namespace Aidge
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include "aidge/backend/cpu/operator/ClipImpl.hpp" #include "aidge/backend/cpu/operator/ClipImpl.hpp"
#include "aidge/backend/cpu/operator/ClipImpl_forward_kernels.hpp" #include "aidge/backend/cpu/operator/ClipImpl_forward_kernels.hpp"
//#include "aidge/backend/cpu/operator/ClipImpl_backward_kernels.hpp" #include "aidge/backend/cpu/operator/ClipImpl_backward_kernels.hpp"
Aidge::Elts_t Aidge::ClipImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const { Aidge::Elts_t Aidge::ClipImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
// this implementation can be in-place // this implementation can be in-place
...@@ -35,6 +35,9 @@ void Aidge::ClipImpl_cpu::forward() { ...@@ -35,6 +35,9 @@ void Aidge::ClipImpl_cpu::forward() {
std::shared_ptr<Tensor> in2 = op_.getInput(2); std::shared_ptr<Tensor> in2 = op_.getInput(2);
std::shared_ptr<Tensor> out0 = op_.getOutput(0); std::shared_ptr<Tensor> out0 = op_.getOutput(0);
AIDGE_ASSERT(in0, "missing input #0"); AIDGE_ASSERT(in0, "missing input #0");
AIDGE_ASSERT(in1, "missing input #1 -> Min value empty shape Tensor");
AIDGE_ASSERT(in2, "missing input #2 -> Max value empty shape Tensor");
// Find the correct kernel type // Find the correct kernel type
auto kernelFunc = Registrar<ClipImplForward_cpu>::create({ auto kernelFunc = Registrar<ClipImplForward_cpu>::create({
...@@ -53,10 +56,12 @@ void Aidge::ClipImpl_cpu::forward() { ...@@ -53,10 +56,12 @@ void Aidge::ClipImpl_cpu::forward() {
); );
} }
/*void Aidge::ClipImpl_cpu::backward() { void Aidge::ClipImpl_cpu::backward() {
const Clip_Op& op_ = dynamic_cast<const Clip_Op&>(mOp); const Clip_Op& op_ = dynamic_cast<const Clip_Op&>(mOp);
std::shared_ptr<Tensor> in0 = op_.getInput(0); std::shared_ptr<Tensor> in0 = op_.getInput(0);
std::shared_ptr<Tensor> in1min = op_.getInput(1);
std::shared_ptr<Tensor> in2max = op_.getInput(2);
std::shared_ptr<Tensor> out0 = op_.getOutput(0); std::shared_ptr<Tensor> out0 = op_.getOutput(0);
std::shared_ptr<Tensor> gra_in0 = op_.getInput(0)->grad(); std::shared_ptr<Tensor> gra_in0 = op_.getInput(0)->grad();
std::shared_ptr<Tensor> gra_out0 = op_.getOutput(0)->grad(); std::shared_ptr<Tensor> gra_out0 = op_.getOutput(0)->grad();
...@@ -64,6 +69,8 @@ void Aidge::ClipImpl_cpu::forward() { ...@@ -64,6 +69,8 @@ void Aidge::ClipImpl_cpu::forward() {
// Find the correct kernel type // Find the correct kernel type
auto kernelFunc = Registrar<ClipImplBackward_cpu>::create({ auto kernelFunc = Registrar<ClipImplBackward_cpu>::create({
in1min->dataType(),
in2max->dataType(),
in0->dataType(), in0->dataType(),
gra_in0->dataType(), gra_in0->dataType(),
gra_out0->dataType() gra_out0->dataType()
...@@ -71,11 +78,11 @@ void Aidge::ClipImpl_cpu::forward() { ...@@ -71,11 +78,11 @@ void Aidge::ClipImpl_cpu::forward() {
// Call kernel // Call kernel
kernelFunc( kernelFunc(
op_.min(), getCPUPtr(in1min),
op_.max(), getCPUPtr(in2max),
gra_in0->size(), gra_in0->size(),
getCPUPtr(in0), getCPUPtr(in0),
getCPUPtr(gra_out0), getCPUPtr(gra_out0),
getCPUPtr(gra_in0) getCPUPtr(gra_in0)
); );
}*/ }
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include <chrono> #include <chrono>
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <algorithm>
#include <iomanip>
#include <memory> #include <memory>
#include <random> // std::random_device, std::mt19937, std::uniform_real_distribution #include <random> // std::random_device, std::mt19937, std::uniform_real_distribution
...@@ -23,13 +25,32 @@ ...@@ -23,13 +25,32 @@
#include "aidge/operator/OperatorTensor.hpp" #include "aidge/operator/OperatorTensor.hpp"
#include "aidge/utils/TensorUtils.hpp" #include "aidge/utils/TensorUtils.hpp"
#include "aidge/backend/cpu.hpp" #include "aidge/backend/cpu.hpp"
void prettyPrint(float* tensor, std::string tensor_name) {
std::cout << "Printing formatted tensor: " <<tensor_name << std::endl;
namespace Aidge { for (int i = 0; i < 3; ++i) {
int azertBpoint() for (int j = 0; j < 3; ++j) {
{ std::cout << std::setw(10) << std::setprecision(4) << tensor[i * 3 + j] << " ";
return 0; }
std::cout << std::endl;
}
} }
TEST_CASE("[cpu/operator] Clip(forward)", "[Clip][CPU]") { void applyMask(const std::vector<float>& vec1, std::vector<float>& vec2, float min, float max) {
if (vec1.size() != vec2.size()) {
std::cerr << "Les vecteurs doivent être de la même taille." << std::endl;
return;
}
for (size_t i = 0; i < vec1.size(); ++i) {
if (vec1[i] < min || vec1[i] > max) {
vec2[i] = 0.0f;
}
}
}
namespace Aidge
{
TEST_CASE("[cpu/operator] Clip", "[Clip][CPU]")
{
const std::uint16_t NBTRIALS = 10; const std::uint16_t NBTRIALS = 10;
// Create a random number generator // Create a random number generator
std::random_device rd; std::random_device rd;
...@@ -42,7 +63,6 @@ TEST_CASE("[cpu/operator] Clip(forward)", "[Clip][CPU]") { ...@@ -42,7 +63,6 @@ TEST_CASE("[cpu/operator] Clip(forward)", "[Clip][CPU]") {
// Create MatMul Operator // Create MatMul Operator
std::shared_ptr<Node> myClip = Aidge::Clip("nop"); std::shared_ptr<Node> myClip = Aidge::Clip("nop");
azertBpoint();
auto op = std::static_pointer_cast<OperatorTensor>(myClip -> getOperator()); auto op = std::static_pointer_cast<OperatorTensor>(myClip -> getOperator());
// To measure execution time of 'MatMul_Op::forward()' member function call // To measure execution time of 'MatMul_Op::forward()' member function call
...@@ -50,7 +70,7 @@ TEST_CASE("[cpu/operator] Clip(forward)", "[Clip][CPU]") { ...@@ -50,7 +70,7 @@ TEST_CASE("[cpu/operator] Clip(forward)", "[Clip][CPU]") {
std::chrono::time_point<std::chrono::system_clock> end; std::chrono::time_point<std::chrono::system_clock> end;
std::chrono::duration<double, std::micro> duration; std::chrono::duration<double, std::micro> duration;
SECTION("2-D Tensors") { SECTION("Simple clamp test [Forward]") {
std::size_t totalComputation = 0; std::size_t totalComputation = 0;
for (std::uint16_t trial = 0; trial < NBTRIALS; ++trial) { for (std::uint16_t trial = 0; trial < NBTRIALS; ++trial) {
// generate Tensors dimensions // generate Tensors dimensions
...@@ -64,213 +84,136 @@ TEST_CASE("[cpu/operator] Clip(forward)", "[Clip][CPU]") { ...@@ -64,213 +84,136 @@ TEST_CASE("[cpu/operator] Clip(forward)", "[Clip][CPU]") {
Array[i] = dis(gen); // Generate random float value Array[i] = dis(gen); // Generate random float value
} }
// Convert bigArray1 to Tensor // Convert Input to Tensor
std::shared_ptr<Tensor> TInput = std::make_shared<Tensor>(DataType::Float32); std::shared_ptr<Tensor> TInput = std::make_shared<Tensor>(DataType::Float32);
TInput -> resize({dim0,dim1}); TInput -> resize({dim0,dim1});
TInput -> setBackend("cpu"); TInput -> setBackend("cpu");
TInput -> getImpl() -> setRawPtr(Array, dim0*dim1); TInput -> getImpl() -> setRawPtr(Array, dim0*dim1);
// Convert bigArray2 to Tensor
float a = dismin(gen); float min = dismin(gen);
std::shared_ptr<Tensor> Tmin = std::make_shared<Tensor>(DataType::Float32); std::shared_ptr<Tensor> Tmin = std::make_shared<Tensor>(DataType::Float32);
Tmin -> resize({}); Tmin -> resize({});
Tmin -> setBackend("cpu"); Tmin -> setBackend("cpu");
Tmin -> getImpl() -> setRawPtr(&a,1); Tmin -> getImpl() -> setRawPtr(&min,1);
float b = dismax(gen); float max = dismax(gen);
std::shared_ptr<Tensor> Tmax = std::make_shared<Tensor>(DataType::Float32); std::shared_ptr<Tensor> Tmax = std::make_shared<Tensor>(DataType::Float32);
Tmax -> resize({}); Tmax -> resize({});
Tmax -> setBackend("cpu"); Tmax -> setBackend("cpu");
Tmax -> getImpl() -> setRawPtr(&b,1); Tmax -> getImpl() -> setRawPtr(&max,1);
// convert res to Tensor // convert res to Tensordf
std::vector<float> GT(Array, Array + (dim0*dim1)); std::vector<float> GT(Array, Array + (dim0*dim1));
for (float& val : GT)
std::for_each(GT.begin(), GT.end(),a,b {
valeur = std::clamp(valeur,a,b);
});
// Affichage des éléments du vecteur pour vérifier le clampage
for (const auto& valeur : GT)
{ {
std::cout << valeur << " "; val = std::max(min, std::min(val, max));
} }
float* gt_raw = GT.data(); std::shared_ptr<Tensor> Tres = std::make_shared<Tensor>(DataType::Float32);
//std::shared_ptr<Tensor> Tres = std::make_shared<Tensor>(DataType::Float32); Tres -> resize({dim0,dim1});
Tres -> setBackend("cpu");
Tres -> getImpl() -> setRawPtr(GT.data(), dim0*dim1);
op->associateInput(0, TInput); op->associateInput(0, TInput);
op->associateInput(1, Tmin); op->associateInput(1, Tmin);
op->associateInput(2, Tmax); op->associateInput(2, Tmax);
op->setDataType(DataType::Float32); op->setDataType(DataType::Float32);
azertBpoint();
op->setBackend("cpu"); op->setBackend("cpu");
op->forwardDims(); op->forwardDims();
start = std::chrono::system_clock::now(); start = std::chrono::system_clock::now();
myClip->forward(); myClip->forward();
end = std::chrono::system_clock::now(); end = std::chrono::system_clock::now();
duration += std::chrono::duration_cast<std::chrono::microseconds>(end - start); duration += std::chrono::duration_cast<std::chrono::microseconds>(end - start);
REQUIRE(approxEq<float>(*(op->getOutput(0)), gt_raw)); REQUIRE(approxEq<float>(*(op->getOutput(0)), *Tres));
} }
std::cout << "multiplications over time spent: " << totalComputation/duration.count() << std::endl; std::cout << "multiplications over time spent: " << totalComputation/duration.count() << std::endl;
std::cout << "total time: " << duration.count() << std::endl; std::cout << "total time: " << duration.count() << std::endl;
} }
/* SECTION("3-D Tensors") { SECTION("Simple clamp test [Backward]") {
std::size_t totalComputation = 0; std::size_t totalComputation = 0;
duration = std::chrono::duration<double, std::micro>::zero(); duration = std::chrono::duration<double, std::micro>::zero();
for (std::uint16_t trial = 0; trial < NBTRIALS; ++trial) {
std::size_t totalComputation = 0;
for (std::uint16_t trial = 0; trial < NBTRIALS; ++trial) { for (std::uint16_t trial = 0; trial < NBTRIALS; ++trial) {
// generate Tensors dimensions // generate Tensors dimensions
const std::size_t dimNb = distNbMatrix(gen);
const std::size_t dim0 = distDims(gen); const std::size_t dim0 = distDims(gen);
const std::size_t dim1 = distDims(gen); const std::size_t dim1 = distDims(gen);
const std::size_t dim2 = distDims(gen);
totalComputation += dim0*dim1*dim2*dimNb; totalComputation += dim0*dim1;
// Create and populate the array with random float values // Create and populate the array with random float values
float* bigArray1 = new float[dimNb*dim0*dim1]; float* Array = new float[dim0*dim1];
for (std::size_t i = 0; i < dimNb*dim0*dim1; ++i) { float* gradArray = new float[dim0*dim1];
bigArray1[i] = dis(gen); // Generate random float value for (int i = 0; i < dim0*dim1; ++i) {
} Array[i] = dis(gen); // Generate random float value
float* bigArray2 = new float[dimNb*dim1*dim2]; gradArray[i] = dis(gen);
for (int i = 0; i < dimNb*dim1*dim2; ++i) {
bigArray2[i] = dis(gen); // Generate random float value
}
float* res = new float[dimNb*dim0*dim2];
for (std::size_t n = 0; n < dimNb; ++n) {
for (int i = 0; i < dim0; ++i) {
for (int j = 0; j < dim2; ++j) {
float sum = 0.0;
for (int k = 0; k < dim1; ++k) {
sum += bigArray1[n*dim0*dim1 + i*dim1 + k] * bigArray2[n*dim2*dim1+k*dim2+j];
}
res[n*dim0*dim2+i*dim2+j] = sum;
}
}
} }
// Convert bigArray1 to Tensor
std::shared_ptr<Tensor> T1 = std::make_shared<Tensor>(DataType::Float32);
T1 -> resize({dimNb,dim0,dim1});
T1 -> setBackend("cpu");
T1 -> getImpl() -> setRawPtr(bigArray1, dimNb*dim0*dim1);
// Convert bigArray2 to Tensor
std::shared_ptr<Tensor> T2 = std::make_shared<Tensor>(DataType::Float32);
T2 -> resize({dimNb,dim1,dim2});
T2 -> setBackend("cpu");
T2 -> getImpl() -> setRawPtr(bigArray2, dimNb*dim1*dim2);
// convert res to Tensor
std::shared_ptr<Tensor> Tres = std::make_shared<Tensor>(DataType::Float32);
Tres -> resize({dimNb,dim0,dim2});
Tres -> setBackend("cpu");
Tres -> getImpl() -> setRawPtr(res, dimNb*dim0*dim2);
op->associateInput(0, T1);
op->associateInput(1, T2);
op->setDataType(DataType::Float32);
op->setBackend("cpu");
op->forwardDims();
start = std::chrono::system_clock::now();
myMatMul->forward();
end = std::chrono::system_clock::now();
duration += std::chrono::duration_cast<std::chrono::microseconds>(end - start);
REQUIRE(approxEq<float>(*(op->getOutput(0)), *Tres)); std::shared_ptr<Tensor> TGrad = std::make_shared<Tensor>(DataType::Float32);
} TGrad -> resize({dim0,dim1});
std::cout << "multiplications over time spent: " << totalComputation/duration.count() << std::endl; TGrad -> setBackend("cpu");
std::cout << "total time: " << duration.count() << std::endl; TGrad -> getImpl() -> setRawPtr(gradArray, dim0*dim1);
}
SECTION("4-D Tensors") { // Convert Input to Tensor
std::size_t totalComputation = 0; std::shared_ptr<Tensor> TInput = std::make_shared<Tensor>(DataType::Float32);
duration = std::chrono::duration<double, std::micro>::zero(); TInput -> resize({dim0,dim1});
for (std::uint16_t trial = 0; trial < NBTRIALS; ++trial) { TInput -> setBackend("cpu");
// generate Tensors dimensions TInput -> getImpl() -> setRawPtr(Array, dim0*dim1);
const std::size_t dimNb1 = distNbMatrix(gen);
const std::size_t dimNb2 = distNbMatrix(gen); float min = dismin(gen);
const std::size_t dim0 = distDims(gen); std::shared_ptr<Tensor> Tmin = std::make_shared<Tensor>(DataType::Float32);
const std::size_t dim1 = distDims(gen); Tmin -> resize({});
const std::size_t dim2 = distDims(gen); Tmin -> setBackend("cpu");
totalComputation += dim0*dim1*dim2*dimNb1*dimNb2; Tmin -> getImpl() -> setRawPtr(&min,1);
// Create and populate the array with random float values float max = dismax(gen);
float* bigArray1 = new float[dimNb1*dimNb2*dim0*dim1]; std::shared_ptr<Tensor> Tmax = std::make_shared<Tensor>(DataType::Float32);
for (std::size_t i = 0; i < dimNb1*dimNb2*dim0*dim1; ++i) { Tmax -> resize({});
bigArray1[i] = dis(gen); // Generate random float value Tmax -> setBackend("cpu");
} Tmax -> getImpl() -> setRawPtr(&max,1);
float* bigArray2 = new float[dimNb1*dimNb2*dim1*dim2]; // convert res to Tensordf
for (std::size_t i = 0; i < dimNb1*dimNb2*dim1*dim2; ++i) { std::vector<float> GT(Array, Array + (dim0*dim1));
bigArray2[i] = dis(gen); // Generate random float value for (float& val : GT)
} {
float* res = new float[dimNb1*dimNb2*dim0*dim2]; val = std::max(min, std::min(val, max));
for (std::size_t n1 = 0; n1 < dimNb1; ++n1) {
for (std::size_t n2 = 0; n2 < dimNb2; ++n2) {
for (int i = 0; i < dim0; ++i) {
for (int j = 0; j < dim2; ++j) {
float sum = 0.0;
for (int k = 0; k < dim1; ++k) {
sum += bigArray1[n1*dimNb2*dim0*dim1+n2*dim0*dim1+i*dim1+k] * bigArray2[n1*dimNb2*dim1*dim2+n2*dim1*dim2+k*dim2+j];
}
res[n1*dimNb2*dim0*dim2+n2*dim0*dim2+i*dim2+j] = sum;
}
}
}
} }
// Convert bigArray1 to Tensor
std::shared_ptr<Tensor> T1 = std::make_shared<Tensor>(DataType::Float32);
T1 -> resize({dimNb1,dimNb2,dim0,dim1});
T1 -> setBackend("cpu");
T1 -> getImpl() -> setRawPtr(bigArray1, dimNb1*dimNb2*dim0*dim1);
// Convert bigArray2 to Tensor
std::shared_ptr<Tensor> T2 = std::make_shared<Tensor>(DataType::Float32);
T2 -> resize({dimNb1,dimNb2,dim1,dim2});
T2 -> setBackend("cpu");
T2 -> getImpl() -> setRawPtr(bigArray2, dimNb1*dimNb2*dim1*dim2);
// convert res to Tensor
std::shared_ptr<Tensor> Tres = std::make_shared<Tensor>(DataType::Float32); std::shared_ptr<Tensor> Tres = std::make_shared<Tensor>(DataType::Float32);
Tres -> resize({dimNb1,dimNb2,dim0,dim2}); Tres -> resize({dim0,dim1});
Tres -> setBackend("cpu"); Tres -> setBackend("cpu");
Tres -> getImpl() -> setRawPtr(res, dimNb1*dimNb2*dim0*dim2); Tres -> getImpl() -> setRawPtr(GT.data(), dim0*dim1);
op->associateInput(0, T1); op->associateInput(0, TInput);
op->associateInput(1, T2); op->associateInput(1, Tmin);
op->associateInput(2, Tmax);
op->setDataType(DataType::Float32); op->setDataType(DataType::Float32);
op->setBackend("cpu"); op->setBackend("cpu");
op->forwardDims(); op->forwardDims();
myClip->forward();
op->getOutput(0)->setGrad(TGrad);
start = std::chrono::system_clock::now(); start = std::chrono::system_clock::now();
myMatMul->forward(); REQUIRE_NOTHROW(myClip->backward());
end = std::chrono::system_clock::now(); end = std::chrono::system_clock::now();
auto GradTensor = op->getInput(0)->grad();
float* BackwardTensor = (float*)GradTensor->getImpl()->rawPtr();
std::cout << "Range of clip is: [min:" << min << "->max: " << max << "]\n";
prettyPrint(Array,"Input");
prettyPrint(gradArray,"Gradient Input");
prettyPrint(BackwardTensor,"final TENSOR");
std::vector<float> GT0(Array,Array+(dim0*dim1));
std::vector<float> GT1(gradArray,gradArray+(dim0*dim1));
std::vector<float> BackwardTensorVec(BackwardTensor,BackwardTensor+(dim0*dim1));
applyMask(GT0,GT1,min,max);
duration += std::chrono::duration_cast<std::chrono::microseconds>(end - start); duration += std::chrono::duration_cast<std::chrono::microseconds>(end - start);
REQUIRE(approxEq<float>(*(op->getOutput(0)), *Tres)); REQUIRE(GT1 == BackwardTensorVec);
} }
std::cout << "multiplications over time spent: " << totalComputation/duration.count() << std::endl; std::cout << "multiplications over time spent: " << totalComputation/duration.count() << std::endl;
std::cout << "total time: " << duration.count() << std::endl; std::cout << "total time: " << duration.count() << std::endl;
} }
}
SECTION("+2-D / 1-D") { }
// allows to test both computation with a 1-D Tensor and broadcasting } // namespace Aidge
// input_0 \ No newline at end of file
std::shared_ptr<Tensor> T0 = std::make_shared<Tensor>();
op->associateInput(0,T0);
const std::size_t dim0 = distNbMatrix(gen);
const std::size_t dim1 = distNbMatrix(gen) + 1;
const std::size_t dim2 = distNbMatrix(gen);
const std::size_t dim3 = distNbMatrix(gen);
T0->resize({dim0,dim1,dim2,dim3});
T0->setDataType(DataType::Float32);
T0->setBackend("cpu");
// input_1
std::shared_ptr<Tensor> T1 = std::make_shared<Tensor>();
op -> associateInput(1,T1);
T1->resize({dim3});
T1->setDataType(DataType::Float32);
T1->setBackend("cpu");
op->setDataType(DataType::Float32);
op->setBackend("cpu");
op->forwardDims();
myMatMul->forward();
}*/
}
} // namespace Aidge
\ 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