Skip to content
Snippets Groups Projects
Commit 7a16625d authored by Maxence Naud's avatar Maxence Naud
Browse files

Revert "[Add] Slice implementation, not tested yet"

This reverts commit 3b8417ed
parent 3b8417ed
No related branches found
No related tags found
No related merge requests found
......@@ -13,7 +13,6 @@
#define AIDGE_CPU_IMPORTS_H_
#include "aidge/backend/cpu/data/TensorImpl.hpp"
#include "aidge/backend/cpu/operator/AddImpl.hpp"
#include "aidge/backend/cpu/operator/AvgPoolingImpl.hpp"
#include "aidge/backend/cpu/operator/MaxPoolingImpl.hpp"
......@@ -25,8 +24,7 @@
#include "aidge/backend/cpu/operator/MatMulImpl.hpp"
#include "aidge/backend/cpu/operator/ProducerImpl.hpp"
#include "aidge/backend/cpu/operator/ReLUImpl.hpp"
#include "aidge/backend/cpu/operator/ScalingImpl.hpp"
#include "aidge/backend/cpu/operator/SliceImpl.hpp"
#include "aidge/backend/cpu/operator/SoftmaxImpl.hpp"
#include "aidge/backend/cpu/operator/ScalingImpl.hpp"
#endif /* AIDGE_CPU_IMPORTS_H_ */
\ 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
*
********************************************************************************/
#ifndef AIDGE_CPU_OPERATOR_SLICEIMPL_H_
#define AIDGE_CPU_OPERATOR_SLICEIMPL_H_
#include "aidge/backend/OperatorImpl.hpp"
#include "aidge/operator/Slice.hpp"
#include "aidge/utils/Registrar.hpp"
#include "aidge/utils/Types.h"
#include <memory>
#include <vector>
namespace Aidge {
// class Slice_Op;
// compute kernel registry for forward and backward
template <DimIdx_t DIM>
class SliceImplForward_cpu
: public Registrable<SliceImplForward_cpu<DIM>, std::tuple<DataType>, void(std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, const void*, void*)> {
};
template <DimIdx_t DIM>
class SliceImplBackward_cpu
: public Registrable<SliceImplBackward_cpu<DIM>, std::tuple<DataType>, void(std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, const void*, void*)> {
};
template <DimIdx_t DIM>
class SliceImpl_cpu : public OperatorImpl {
private:
const Slice_Op<DIM>& mOp;
std::array<NbElts_t, 1> mNbConsumedData;
std::array<NbElts_t, 1> mNbProducedData;
public:
SliceImpl_cpu(const Slice_Op<DIM>& op) : mOp(op), mNbConsumedData({0}), mNbProducedData({0}) {}
static std::unique_ptr<SliceImpl_cpu> create(const Slice_Op<DIM>& op) {
return std::make_unique<SliceImpl_cpu>(op);
}
public:
NbElts_t getNbRequiredData(const IOIndex_t /*inputIdx*/) const override final {
assert(mOp.getInput(0) && "requires valid input");
// Requires the whole tensors
const auto& inputDims = mOp.getInput(0)->dims();
return std::accumulate(inputDims.begin(), inputDims.end(),
static_cast<NbElts_t>(1), std::multiplies<NbElts_t>());
}
NbElts_t getNbRequiredProtected(const IOIndex_t /*inputIdx*/) const override final {
return 0;
}
NbElts_t getRequiredMemory(const IOIndex_t outputIdx, const std::vector<DimSize_t>& inputsSize) const override final {
(void) outputIdx;
(void) inputsSize;
const auto& outputDims = mOp.getOutput(0)->dims();
return std::accumulate(outputDims.begin(), outputDims.end(),
static_cast<NbElts_t>(1), std::multiplies<NbElts_t>());
}
NbElts_t getNbConsumedData(const IOIndex_t /*inputIdx*/) const override final {
return mNbConsumedData[0];
}
NbElts_t getNbProducedData(const IOIndex_t outputIdx) const override final {
return mNbProducedData[0];
}
void updateConsummerProducer() override final {
mNbConsumedData[0]+= getNbRequiredData(0); // each input is consumed by the minimum amount for a forward pass
mNbProducedData[0]+= getRequiredMemory(0, {});
}
void forward() {
// FIXME: uncomment the following code once memory handling will work
assert(mOp.getInput(0) && "missing input #0");
// Find the correct kernel type
auto kernelFunc = Registrar<SliceImplForward_cpu<DIM>>::create({
mOp.getInput(0)->dataType(),
mOp.getOutput(0)->dataType()});
// Call kernel
kernelFunc(mOp->getInput(0)->dims(),
mOp->template getAttr<SliceAttr::SliceDims>(),
mOp.getInput(0)->getImpl()->rawPtr(),
mOp.getOutput(0)->getImpl()->rawPtr());
mNbConsumedData[0]+= getNbRequiredData(0); // each input is consumed by the minimum amount for a forward pass
mNbProducedData[0]+= getRequiredMemory(0, {});
}
void backward() {
printf("Not implemented yet.\n");
}
};
namespace {
template <DimIdx_t DIM>
static Registrar<Slice_Op<DIM>> registrarSliceImpl_cpu("cpu", Aidge::SliceImpl_cpu<DIM>::create);
}
} // namespace Aidge
#endif /* AIDGE_CPU_OPERATOR_LEAKYRELUIMPL_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_SLICEIMPL_FORWARD_KERNEL_H_
#define AIDGE_CPU_OPERATOR_SLICEIMPL_FORWARD_KERNEL_H_
#include "aidge/utils/Registrar.hpp"
#include <array>
#include <cstddef>
#include "aidge/backend/cpu/operator/SliceImpl.hpp"
namespace Aidge {
template <class I, class O, std::size_t DIM>
void SliceImpl_cpu_forward_kernel(const std::array<std::size_t, DIM> inputDims,
const std::array<std::size_t, DIM> slicedDims,
const void* input_,
void* output_) {
const I* input = static_cast<const I*>(input_);
O* output = static_cast<O*>(output_);
// for inputDims = {4,5,5,3} & slicedDims = {3,2,2,1}, substractDims = {1,5,5,3}
std::array<std::size_t, DIM> substractedDims;
for (std::size_t i = 0; i < DIM; ++i) {
substractedDims[i] = inputDims[i] - slicedDims[i];
}
// for slicedDims = {3,2,2,1}, prodSlicedDims = {12,4,2,1}
std::array<std::size_t, DIM> prodSlicedDims;
std::array<std::size_t, DIM+1> prodInputDims;
prodSlicedDims[DIM - 1] = slicedDims[DIM - 1];
prodInputDims[DIM - 1] = inputDims[DIM - 1];
prodInputDims[DIM] = 1;
for (std::size_t i = 2; i < DIM; ++i) {
prodSlicedDims[DIM - i] = prodSlicedDims[DIM - i + 1]*slicedDims[DIM - i];
prodInputDims[DIM - i] = prodInputDims[DIM - i + 1]*inputDims[DIM - i];
}
std::size_t j = 0;
std::size_t i = 0;
for (std::size_t = 0; j < prodSlicedDims[0]; ++j) {
output[j] = input[i++];
for (std::size_t idx = DIM - 1; idx > 0; --idx) {
i += j % prodSlicedDims[idx] == 0 ? substractedDims[idx]*prodInputDims[idx+1] : 0;
}
}
}
namespace {
template <std::size_t DIM>
static Registrar<SliceImplForward_cpu<DIM>> registrarSliceImplForward_cpu_Float32(
{DataType::Float32, DataType::Float32}, Aidge::SliceImpl_cpu_forward_kernel<float, float, DIM>);
template <std::size_t DIM>
static Registrar<SliceImplForward_cpu<DIM>> registrarSliceImplForward_cpu_Int32(
{DataType::Int32, DataType::Int32}, Aidge::SliceImpl_cpu_forward_kernel<int, int, DIM>);
template <std::size_t DIM>
static Registrar<SliceImplForward_cpu<DIM>> registrarSliceImplForward_cpu_Float64(
{DataType::Float64, DataType::Float64}, Aidge::SliceImpl_cpu_forward_kernel<double, double, DIM>);
} // namespace
} // namespace Aidge
#endif /* AIDGE_CPU_OPERATOR_LEAKYRELUIMPL_FORWARD_KERNEL_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
*
********************************************************************************/
#include <catch2/catch_test_macros.hpp>
#include "aidge/data/Tensor.hpp"
#include "aidge/operator/Slice.hpp"
#include "aidge/backend/cpu.hpp"
using namespace Aidge;
TEST_CASE("[cpu/operator] Slice(forward)") {
SECTION("1D Tensor") {
std::shared_ptr<Tensor> input0 = std::make_shared<Tensor>(Array1D<int,10> {
{0, 1, 2,-3, 4,-5,-6, 7, 8, 9}
});
std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>(Array1D<int,4> {
{0, 1, 2,-3}
});
std::shared_ptr<Node> mySlice = Slice(0, {4});
mySlice->getOperator()->setDatatype(DataType::Int32);
mySlice->getOperator()->setBackend("cpu");
mySlice->getOperator()->associateInput(0,input0);
mySlice->getOperator()->computeOutputDims();
mySlice->forward();
REQUIRE(mySlice->getOperator()->output(0) == *expectedOutput);
}
SECTION("2D Tensor") {
std::shared_ptr<Tensor> input0 = std::make_shared<Tensor>(Array2D<int,2,10> {
{
{ 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
{-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
}
});
std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>(Array2D<int,2,3> {
{
{-5,-6, 7},
{-5,-6, 7}
}
});
std::shared_ptr<Node> mySlice = Slice(5, {2,3});
mySlice->getOperator()->setDatatype(DataType::Int32);
mySlice->getOperator()->setBackend("cpu");
mySlice->getOperator()->associateInput(0,input0);
mySlice->getOperator()->computeOutputDims();
mySlice->forward();
REQUIRE(*mySlice->getOperator()->getOutput(0) == *expectedOutput);
}
SECTION("3D Tensor") {
std::shared_ptr<Tensor> input0 = std::make_shared<Tensor>(Array3D<int,2,2,10> {
{
{
{ 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
{-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
},
{
{ 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
{-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
}
}
});
std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>(Array3D<int,1,1,3> {
{
{
{ 4,-5,-6}
}
}
});
std::shared_ptr<Node> mySlice = Slice(14, {1,1,3});
mySlice->getOperator()->setDatatype(DataType::Int32);
mySlice->getOperator()->setBackend("cpu");
mySlice->getOperator()->associateInput(0,input0);
mySlice->getOperator()->computeOutputDims();
mySlice->forward();
REQUIRE(mySlice->getOperator()->output(0) == *expectedOutput);
}
SECTION("4D Tensor") {
std::shared_ptr<Tensor> input0 = std::make_shared<Tensor>(Array4D<int,2,2,2,10> {
{
{
{
{ 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
{-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
},
{
{ 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
{-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
}
},
{
{
{ 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
{-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
},
{
{ 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
{-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
}
}
}
});
std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>(Array4D<int,2,2,2,10> {
{
{
{
{ 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
{-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
},
{
{ 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
{-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
}
},
{
{
{ 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
{-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
},
{
{ 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
{-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
}
}
}
});
std::shared_ptr<Node> mySlice = Slice(0, {2,2,2,10});
mySlice->getOperator()->setDatatype(DataType::Int32);
mySlice->getOperator()->setBackend("cpu");
mySlice->getOperator()->associateInput(0,input0);
mySlice->getOperator()->computeOutputDims();
mySlice->forward();
REQUIRE(mySlice->getOperator()->output(0) == *expectedOutput);
}
}
\ 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