Skip to content
Snippets Groups Projects
Commit e5fab1bc authored by Grégoire Kubler's avatar Grégoire Kubler Committed by Olivier BICHLER
Browse files

feat : operator constant of shape

parent fa8f8ec4
No related branches found
No related tags found
2 merge requests!93Release v0.3.0,!84feat : operator constant of shape
Pipeline #54383 passed
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "aidge/backend/cpu/operator/BatchNormImpl.hpp" #include "aidge/backend/cpu/operator/BatchNormImpl.hpp"
#include "aidge/backend/cpu/operator/ConvDepthWiseImpl.hpp" #include "aidge/backend/cpu/operator/ConvDepthWiseImpl.hpp"
#include "aidge/backend/cpu/operator/ConvImpl.hpp" #include "aidge/backend/cpu/operator/ConvImpl.hpp"
#include "aidge/backend/cpu/operator/ConstantOfShapeImpl.hpp"
#include "aidge/backend/cpu/operator/DivImpl.hpp" #include "aidge/backend/cpu/operator/DivImpl.hpp"
#include "aidge/backend/cpu/operator/ErfImpl.hpp" #include "aidge/backend/cpu/operator/ErfImpl.hpp"
#include "aidge/backend/cpu/operator/FCImpl.hpp" #include "aidge/backend/cpu/operator/FCImpl.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_CONSTANTOFSHAPEIMPL_H_
#define AIDGE_CPU_OPERATOR_CONSTANTOFSHAPEIMPL_H_
#include <cstddef>
#include <memory>
#include <vector>
#include "aidge/backend/OperatorImpl.hpp"
#include "aidge/operator/ConstantOfShape.hpp"
#include "aidge/utils/Registrar.hpp"
#include "aidge/utils/Types.h"
namespace Aidge {
// class ConstantOfShape_op;
class ConstantOfShapeImplForward_cpu
: public Registrable<
ConstantOfShapeImplForward_cpu, std::tuple<DataType>,
void(const std::vector<DimSize_t>, const Tensor&, void *)> {};
class ConstantOfShapeImpl_cpu : public OperatorImpl {
public:
ConstantOfShapeImpl_cpu(const ConstantOfShape_Op &op)
: OperatorImpl(op, "cpu") {}
static std::unique_ptr<ConstantOfShapeImpl_cpu>
create(const ConstantOfShapeImpl_cpu &op) {
return std::make_unique<ConstantOfShapeImpl_cpu>(op);
}
void forward() override;
};
namespace {
static Registrar<ConstantOfShape_Op> registrarConstantOfShapeImpl_cpu(
"cpu", Aidge::ConstantOfShapeImpl_cpu::create);
}
} // namespace Aidge
#endif /* _AIDGE_CPU_OPERATOR_CONSTANTOFSHAPEIMPL_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_CONSTANTOFSHAPEIMPL_FORWARD_KERNEL_H_
#define AIDGE_CPU_OPERATOR_CONSTANTOFSHAPEIMPL_FORWARD_KERNEL_H_
#include <aidge/data/Tensor.hpp>
#include <aidge/data/half.hpp>
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <functional> // std::multiplies
#include <numeric> // std::accumulate
#include <vector>
#include "aidge/backend/cpu/operator/ConstantOfShapeImpl.hpp"
#include "aidge/data/Data.hpp"
#include "aidge/utils/ErrorHandling.hpp"
#include "aidge/utils/Registrar.hpp"
#include "aidge/utils/Types.h"
namespace Aidge {
template <class O>
void ConstantOfShapeimpl_cpu_forward_kernel(
const std::vector<DimSize_t> output_dims, const Tensor &value,
void *output_) {
O *output = static_cast<O *>(output_);
O val;
std::copy(static_cast<O *>(value.getImpl()->hostPtr()),
static_cast<O *>(value.getImpl()->hostPtr()) +
static_cast<NbElts_t>(1),
&val);
const size_t output_size = std::accumulate(
output_dims.begin(), output_dims.end(), 1, std::multiplies<DimSize_t>());
for (size_t i = 0; i < output_size; ++i) {
output[i] = val;
}
}
// Then we add the Registrar declaration for different input/output types
namespace {
static Registrar<ConstantOfShapeImplForward_cpu>
registrarConstantOfShapeImplForward_cpu_Float16(
{DataType::Float16},
Aidge::ConstantOfShapeimpl_cpu_forward_kernel<half_float::half>);
static Registrar<ConstantOfShapeImplForward_cpu>
registrarConstantOfShapeImplForward_cpu_Float32(
{DataType::Float32},
Aidge::ConstantOfShapeimpl_cpu_forward_kernel<float>);
static Registrar<ConstantOfShapeImplForward_cpu>
registrarConstantOfShapeImplForward_cpu_Float64(
{DataType::Float64},
Aidge::ConstantOfShapeimpl_cpu_forward_kernel<double>);
static Registrar<ConstantOfShapeImplForward_cpu>
registrarConstantOfShapeImplForward_cpu_Int16(
{DataType::Int16},
Aidge::ConstantOfShapeimpl_cpu_forward_kernel<std::int16_t>);
static Registrar<ConstantOfShapeImplForward_cpu>
registrarConstantOfShapeImplForward_cpu_Int32(
{DataType::Int32},
Aidge::ConstantOfShapeimpl_cpu_forward_kernel<std::int32_t>);
static Registrar<ConstantOfShapeImplForward_cpu>
registrarConstantOfShapeImplForward_cpu_Int64(
{DataType::Int64}, Aidge::ConstantOfShapeimpl_cpu_forward_kernel <std::int64_t>);
} // namespace
} // namespace Aidge
#endif /* AIDGE_CPU_OPERATOR_CONSTANTOFSHAPEIMPL_FORWARD_KERNEL_H_ */
/********************************************************************************
* Copyright (c) 2024 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 "aidge/backend/cpu/operator/ConstantOfShapeImpl.hpp"
#include <functional>
#include <memory>
#include <vector>
#include "aidge/backend/cpu/operator/ConstantOfShapeImpl_forward_kernels.hpp"
#include "aidge/data/Data.hpp"
#include "aidge/data/Tensor.hpp"
#include "aidge/operator/ConstantOfShape.hpp"
#include "aidge/utils/ErrorHandling.hpp"
#include "aidge/utils/Registrar.hpp"
#include "aidge/utils/Types.h"
void Aidge::ConstantOfShapeImpl_cpu::forward() {
const ConstantOfShape_Op &op_ = static_cast<const ConstantOfShape_Op &>(mOp);
// Check if input is provided
AIDGE_ASSERT(op_.getInput(0), "{} : Missing input 0", __func__);
// Create the forward kernal with the wanted types
auto kernelFunc = Registrar<ConstantOfShapeImplForward_cpu>::create(
{op_.getOutput(0)->dataType()});
// Call kernel
kernelFunc(op_.getOutput(0)->dims(),
op_.value(),
op_.getOutput(0)->getImpl()->rawPtr());
}
/********************************************************************************
* 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 <algorithm>
#include <chrono>
#include <cmath>
#include <cstddef> // std::size_t
#include <cstdint> // std::uint16_t
#include <iostream>
#include <memory>
#include <numeric> // std::accumulate
#include <ostream>
#include <random> // std::random_device, std::mt19937, std::uniform_real_distribution
#include "catch2/internal/catch_compiler_capabilities.hpp"
#include "catch2/internal/catch_enforce.hpp"
#include <catch2/catch_test_macros.hpp>
#include <catch2/generators/catch_generators_random.hpp>
#include "aidge/data/Tensor.hpp"
#include "aidge/operator/ConstantOfShape.hpp"
#include "aidge/utils/TensorUtils.hpp"
#include <aidge/data/Data.hpp>
#include <aidge/data/half.hpp>
#include <aidge/filler/Filler.hpp>
#include <aidge/operator/OperatorTensor.hpp>
#include <aidge/operator/Reshape.hpp>
#include <aidge/utils/TensorUtils.hpp>
#include <aidge/utils/Types.h>
namespace Aidge {
TEST_CASE("[cpu/operator] ConstantOfShape", "[ConstantOfShape][CPU]") {
constexpr std::uint16_t NBTRIALS = 10;
// Create a random number generator
auto random_seed = Catch::Generators::Detail::getSeed;
std::mt19937 gen(random_seed());
std::uniform_real_distribution<float> valueDist(
0.1f, 1.1f); // Random float distribution between 0 and 1
std::uniform_int_distribution<DimSize_t> input_tensor_size_dist(
std::size_t(1), std::size_t(10));
std::uniform_int_distribution<int64_t> input_tensor_values_dist(
std::size_t(1), std::size_t(7));
std::uniform_real_distribution<double> operator_attr_value_dist(-100., 100.);
///////////////////////////////////////////////
// SETUP FUNCTIONS
auto generate_input_tensor =
[&gen, &input_tensor_size_dist,
&input_tensor_values_dist]() -> std::shared_ptr<Tensor> {
std::vector<DimSize_t> input_dims;
input_dims.push_back(input_tensor_size_dist(gen));
auto result = std::make_shared<Tensor>(input_dims);
result->setDataType(DataType::Int64);
result->setBackend("cpu");
for (DimSize_t i = 0; i < result->size(); ++i) {
result->set<int64_t>(i, input_tensor_values_dist(gen));
}
return result;
};
auto generate_random_operator =
[&gen,
&operator_attr_value_dist]() -> std::shared_ptr<ConstantOfShape_Op> {
auto node = ConstantOfShape(Tensor(operator_attr_value_dist(gen)));
auto op = std::static_pointer_cast<ConstantOfShape_Op>(node->getOperator());
op->setDataType(DataType::Float64);
op->setBackend("cpu");
return op;
};
auto generate_output_tensor = [](std::shared_ptr<Tensor> input_tensor,
std::shared_ptr<ConstantOfShape_Op> op) {
std::vector<DimSize_t> output_dims;
output_dims.reserve(input_tensor->size());
for (DimSize_t i = 0; i < input_tensor->size(); ++i) {
output_dims.push_back(input_tensor->get<int64_t>(i));
}
auto result = std::make_shared<Tensor>(output_dims);
result->setDataType(op->value().dataType());
result->setBackend("cpu");
constantFiller(result, op->value().get<double>(0));
return result;
};
/////////////////////////////////////
// BENCHMARKING
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{};
int number_of_operation{0};
SECTION("ConstantOfShapeImpl_cpu::forward()") {
for (int i = 0; i < NBTRIALS; ++i) {
auto input_T = generate_input_tensor();
std::shared_ptr<ConstantOfShape_Op> op = generate_random_operator();
auto output_T = generate_output_tensor(input_T, op);
op->associateInput(0, input_T);
REQUIRE(op->forwardDims(true));
REQUIRE_NOTHROW(op->forward());
CHECK(output_T->nbDims() == op->getOutput(0)->nbDims());
for (DimIdx_t i = 0; i < output_T->nbDims(); ++i) {
CHECK(output_T->dims().at(i) == op->getOutput(0)->dims().at(i));
}
CHECK(approxEq<double>(*output_T, *op->getOutput(0)));
}
}
}
} // namespace Aidge
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