1 // Copyright (C) 2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
15 #include "data_stats.hpp"
17 //----- dataStats -----//
18 void dataStats::registerLayer(const std::string& name, size_t batch, size_t channels) {
19 _registeredLayers.push_back({name, batch, channels});
22 void dataStats::addStatistics(const std::string &name, size_t channel, uint8_t *data, size_t count) {
23 float* dst = new float[count];
24 for (size_t i = 0lu; i < count; i++) {
25 dst[i] = static_cast<float>(data[i]);
27 addStatistics(name, channel, dst, count);
31 void dataStats::addStatistics(const std::string &name, size_t channel, short *data, size_t count) {
32 float* dst = new float[count];
33 for (size_t i = 0lu; i < count; i++) {
34 dst[i] = static_cast<float>(data[i]);
36 addStatistics(name, channel, dst, count);
40 //----- simpleDataStats -----//
41 void simpleDataStats::registerLayer(const std::string& name, size_t batch, size_t channels) {
42 dataStats::registerLayer(name, batch, channels);
46 size_t simpleDataStats::getNumberChannels(const std::string& name) const {
47 auto it = _data.find(name);
48 if (it != _data.end()) {
49 return it->second.size();
54 void simpleDataStats::addStatistics(const std::string& name, size_t channel, float* data, size_t count) {
55 auto& byChannel = _data[name][channel];
56 // TODO: Investigate synchronization of _data usage
58 for (size_t i = 0lu; i < count; i++) {
59 if (byChannel._min > data[i]) {
60 byChannel._min = data[i];
63 if (byChannel._max < data[i]) {
64 byChannel._max = data[i];
67 // add_mutex.unlock();
70 void simpleDataStats::getDataMinMax(const std::string& name, size_t channel, float& min, float& max, float threshold) {
71 auto it = _data.find(name);
72 if (it != _data.end()) {
73 min = it->second[channel]._min;
74 max = it->second[channel]._max;
80 //----- TensorStatistic -----//
81 TensorStatistic::TensorStatistic(float* data, size_t count, size_t nbuckets) {
82 _min = std::numeric_limits<float>::max();
83 _max = std::numeric_limits<float>::min();
84 for (size_t i = 0; i < count; i++) {
85 float val = static_cast<float>(data[i]);
100 float TensorStatistic::getMaxValue() const {
104 float TensorStatistic::getMinValue() const {
107 //----- AggregatedDataStats -----//
108 void AggregatedDataStats::registerLayer(const std::string& name, size_t batch, size_t channels) {
109 dataStats::registerLayer(name , batch, channels);
113 void AggregatedDataStats::addStatistics(const std::string& name, size_t channel, float* data, size_t count) {
114 auto&& byChannel = _data[name];
115 byChannel[channel].push_back(TensorStatistic(data, count));
118 size_t AggregatedDataStats::getNumberChannels(const std::string& name) const {
119 auto it = _data.find(name);
120 if (it != _data.end()) {
121 return it->second.size();
126 void AggregatedDataStats::getDataMinMax(const std::string& name, size_t channel, float& min, float& max, float threshold) {
128 auto it = _data.find(name);
129 if (it != _data.end()) {
130 auto stats = it->second[channel];
131 // having absolute min/max values, we can create new statistic
132 std::vector<float> maxValues;
133 std::vector<float> minValues;
134 for (size_t i = 0; i < stats.size(); i++) {
135 const TensorStatistic& tsS = stats[i];
136 maxValues.push_back(tsS.getMaxValue());
137 minValues.push_back(tsS.getMinValue());
139 // define number of elements to throw out
140 size_t elementToTake = static_cast<size_t>(maxValues.size() * (threshold / 100));
141 int elementsToThrow = maxValues.size() - elementToTake;
142 std::sort(maxValues.begin(), maxValues.end());
143 std::sort(minValues.begin(), minValues.end());
145 min = minValues[elementsToThrow];
146 max = maxValues[elementToTake - 1];