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

Fixed wrong computation in int

parent 61611544
No related branches found
No related tags found
2 merge requests!166Update 0.5.0 -> 0.6.0,!149Fix mean computation for integers
......@@ -23,6 +23,22 @@
#include "aidge/utils/Types.h"
namespace Aidge {
template <typename T>
using Acc_T = typename std::conditional<std::is_floating_point<T>::value, T, double>::type;
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type
castFromFloat(T value) {
return value;
}
template <typename T>
typename std::enable_if<!std::is_floating_point<T>::value, T>::type
castFromFloat(double value) {
return static_cast<T>(std::nearbyint(value));
}
/**
* @brief Forward kernel for 2D AvgPoolingolution on CPU backend.
* @tparam I Input data type.
......@@ -79,7 +95,7 @@ void AvgPoolingImpl2D_cpu_forward_kernel(const std::array<DimSize_t, 2>& strideD
const std::size_t ix = ox * strideDims[0];
const std::size_t iy = oy * strideDims[1];
O sum = static_cast<O>(0);
Acc_T<I> sum = static_cast<Acc_T<I>>(0);
std::size_t count = 0;
for (unsigned int sy = syMin; sy < syMax; ++sy) {
......@@ -90,13 +106,13 @@ void AvgPoolingImpl2D_cpu_forward_kernel(const std::array<DimSize_t, 2>& strideD
// Ensure within bounds
if ((ix + dilated_sx) < dims[2] && (iy + dilated_sy) < dims[3]) {
sum += static_cast<O>(input[iIndex + (ix + dilated_sx) * dims[3] + (iy + dilated_sy)]);
sum += static_cast<Acc_T<I>>(input[iIndex + (ix + dilated_sx) * dims[3] + (iy + dilated_sy)]);
++count;
}
}
}
output[oIndexFull] = count > 0 ? sum / static_cast<O>(count) : 0;
output[oIndexFull] = count > 0 ? castFromFloat<O>(sum / count) : 0;
}
}
}
......
......@@ -38,7 +38,7 @@ stableMean(const T* vec, size_t size) {
// Specialization for integers: perform the mean computation in float
template <typename T>
typename std::enable_if<!std::is_floating_point<T>::value, T>::type
typename std::enable_if<!std::is_floating_point<T>::value, double>::type
stableMean(const T* vec, size_t size) {
double mean = 0;
for (size_t i = 0; i < size; ++i) {
......
......@@ -25,6 +25,9 @@
#include "aidge/utils/Registrar.hpp"
namespace Aidge {
template <typename T>
using Acc_T = typename std::conditional<std::is_floating_point<T>::value, T, double>::type;
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type
......@@ -38,7 +41,7 @@ stableMean(const T* vec, size_t len, size_t stride) {
// Specialization for integers: perform the mean computation in float
template <typename T>
typename std::enable_if<!std::is_floating_point<T>::value, T>::type
typename std::enable_if<!std::is_floating_point<T>::value, double>::type
stableMean(const T* vec, size_t len, size_t stride) {
double mean = 0;
for (size_t i = 0; i < len; ++i) {
......@@ -102,13 +105,13 @@ void ReduceMeanImpl_cpu_forward_kernel(const std::vector<std::int32_t>& axes,
}
// Type should be the return type of stableMean<I>(), which is always floating point
const decltype(stableMean<I>(input, 0, 0))* inputAccumulation = nullptr;
decltype(stableMean<I>(input, 0, 0))* outputAccumulation = nullptr;
const Acc_T<I>* inputAccumulation = nullptr;
Acc_T<I>* outputAccumulation = nullptr;
for (const auto& axisInt : axes) {
const std::size_t a = static_cast<std::size_t>(axisInt);
outputElements /= inputDims[a];
outputAccumulation = new I[outputElements];
outputAccumulation = new Acc_T<I>[outputElements];
const std::size_t dim_i = inputDims[a];
for (std::size_t pre = 0; pre < stride_pre[a]; ++pre) {
for (std::size_t post = 0; post < stride_post[a]; ++post) {
......@@ -118,7 +121,7 @@ void ReduceMeanImpl_cpu_forward_kernel(const std::vector<std::int32_t>& axes,
outputAccumulation[idx_o] = stableMean<I>(input + idx_i, dim_i, stride_post[a]);
}
else {
outputAccumulation[idx_o] = stableMean<I>(inputAccumulation + idx_i, dim_i, stride_post[a]);
outputAccumulation[idx_o] = stableMean<Acc_T<I>>(inputAccumulation + idx_i, dim_i, stride_post[a]);
}
}
}
......
......@@ -201,4 +201,25 @@ TEST_CASE("[cpu/operator] AvgPooling(forward)", "[AvgPooling][CPU]") {
op2->getOutput(0)->print();
REQUIRE(*(op2->getOutput(0)) == *myOutput5);
}
SECTION("Simple test") {
std::shared_ptr<Tensor> tensor =
std::make_shared<Tensor>(Array4D<int32_t, 1, 1, 7, 7>{{{{
{0, 8, 26, 35, 49, 45, 22},
{2, 24, 48, 66, 60, 46, 26},
{8, 41, 64, 68, 39, 18, 9},
{10, 48, 72, 76, 42, 14, 9},
{6, 29, 52, 65, 27, 7, 3},
{1, 9, 24, 31, 18, 7, 1},
{0, 0, 4, 6, 7, 1, 1}}}}});
auto op = AvgPooling2D_Op({7, 7});
op.setDataType(DataType::Int32);
op.setBackend("cpu");
op.associateInput(0, tensor);
op.forwardDims();
op.forward();
REQUIRE(op.getOutput(0)->get<int32_t>(0) == 26);
}
}
\ No newline at end of file
......@@ -558,6 +558,27 @@ TEST_CASE("[cpu/operator] GlobalAveragePooling",
Log::info("Number of operations : {}\n", number_of_operation);
Log::info("Operation / µs = {}\n", number_of_operation / duration.count());
}
SECTION("Simple test") {
std::shared_ptr<Tensor> tensor =
std::make_shared<Tensor>(Array4D<int32_t, 1, 1, 7, 7>{{{{
{0, 8, 26, 35, 49, 45, 22},
{2, 24, 48, 66, 60, 46, 26},
{8, 41, 64, 68, 39, 18, 9},
{10, 48, 72, 76, 42, 14, 9},
{6, 29, 52, 65, 27, 7, 3},
{1, 9, 24, 31, 18, 7, 1},
{0, 0, 4, 6, 7, 1, 1}}}}});
auto op = GlobalAveragePooling_Op();
op.setDataType(DataType::Int32);
op.setBackend("cpu");
op.associateInput(0, tensor);
op.forwardDims();
op.forward();
REQUIRE(op.getOutput(0)->get<int32_t>(0) == 26);
}
}
}
} // 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