14#include "arcane/core/BlockIndexList.h"
16#include "arcane/utils/ArrayView.h"
17#include "arcane/utils/ITraceMng.h"
18#include "arcane/utils/String.h"
19#include "arcane/utils/FatalErrorException.h"
36 if (m_original_size == 0)
39 Int32 new_size = m_indexes.
size() + m_blocks_index_and_offset.
size();
40 return (
static_cast<Real>(new_size) /
static_cast<Real>(m_original_size));
47fillArray(Array<Int32>& v)
49 for (Int32 i = 0, n = m_nb_block; i < n; ++i) {
50 BlockIndex bi = block(i);
51 for (Int32 z = 0, nb_z = bi.size(); z < nb_z; ++z) {
64 m_blocks_index_and_offset.
clear();
68 m_last_block_size = 0;
75_setBlockIndexAndOffset(Int32 block, Int32 index, Int32 offset)
77 m_blocks_index_and_offset[block * 2] = index * m_block_size;
78 m_blocks_index_and_offset[(block * 2) + 1] = offset;
85_setNbBlock(Int32 nb_block)
87 m_blocks_index_and_offset.
resize(nb_block * 2);
88 m_nb_block = nb_block;
95_currentIndexPosition()
const
97 return m_indexes.
size();
104_addBlockInfo(
const Int32* data, Int16 size)
106 m_indexes.
addRange(ConstArrayView<Int32>(size, data));
112Int32 BlockIndexList::
113_computeNbContigusBlock()
const
117 if (m_block_size == 0)
120 Int32 nb_reduced_block = m_indexes.
size() / m_block_size;
121 const Int32 block_size = m_block_size;
123 Int32 contigu_block_pos = -1;
125 for (Int32 i = 0; i < nb_reduced_block; ++i) {
126 bool is_contigu =
true;
127 Int32 pos = i * block_size;
128 for (Int32 z = 1; z < block_size; ++z) {
129 if (m_indexes[pos + z] != z) {
135 contigu_block_pos = pos;
140 if (contigu_block_pos < 0)
145 Int32 nb_contigu = 0;
146 for (Int32 i = 0, n = m_nb_block; i < n; ++i) {
147 if (m_blocks_index_and_offset[i * 2] == contigu_block_pos)
160void BlockIndexListBuilder::
161build(BlockIndexList& block_index_list, SmallSpan<const Int32> indexes,
const String& name)
163 block_index_list.reset();
165 bool is_verbose = m_is_verbose;
167 const Int16 block_size = (m_block_size > 0) ? m_block_size : 32;
168 const Int32 original_size = indexes.size();
169 const Int32 nb_fixed_block = original_size / block_size;
170 const Int16 remaining_size =
static_cast<Int16
>(original_size % block_size);
171 Int32 nb_block = nb_fixed_block;
172 Int16 last_block_size = block_size;
173 if (remaining_size != 0) {
175 last_block_size = remaining_size;
178 std::unordered_map<std::size_t, Int32> block_indexes;
179 std::hash<Int32> hasher;
180 std::ostringstream o;
181 block_index_list._setNbBlock(nb_block);
182 block_index_list.m_original_size = original_size;
183 block_index_list.m_block_size = block_size;
184 block_index_list.m_last_block_size = last_block_size;
186 UniqueArray<Int32> block_index_in_original_array;
187 block_index_in_original_array.reserve(nb_block);
189 for (Int32 i = 0; i < nb_fixed_block; ++i) {
190 Int32 iter_index = i * block_size;
191 Int32 first_value = indexes[iter_index];
192 size_t hash = hasher(0);
195 for (Int32 z = 1; z < block_size; ++z) {
196 Int32 diff = indexes[iter_index + z] - first_value;
197 size_t hash2 = hasher(diff);
198 hash ^= hash2 + 0x9e3779b9 + (hash << 6) + (hash >> 2);
201 auto idx = block_indexes.find(hash);
202 Int32 block_index = -1;
203 if (idx == block_indexes.end()) {
205 block_index =
static_cast<Int32
>(block_indexes.size());
206 block_indexes.insert(std::make_pair(hash, block_index));
207 block_index_in_original_array.add(iter_index);
210 block_index = idx->second;
211 block_index_list._setBlockIndexAndOffset(i, block_index, first_value);
214 o <<
"\nBlock i=" << std::setw(5) << i;
215 for (Int32 z = 1; z < block_size; ++z) {
216 Int32 diff = indexes[iter_index + z] - first_value;
217 o <<
" " << std::setw(4) << diff;
219 o <<
" H=" << std::hex << hash << std::setbase(0);
224 if (remaining_size != 0) {
225 Int32 iter_index = nb_fixed_block * block_size;
226 Int32 first_value = indexes[iter_index];
227 Int32 block_index =
static_cast<Int32
>(block_indexes.size());
228 block_index_in_original_array.add(iter_index);
229 block_index_list._setBlockIndexAndOffset(nb_fixed_block, block_index, first_value);
235 Int32 local_block_values[BlockIndex::MAX_BLOCK_SIZE];
236 local_block_values[0] = 0;
237 const Int32 nb_reduced_block =
static_cast<Int32
>(block_indexes.size());
238 block_index_list.m_indexes.reserve((block_size * nb_reduced_block) + remaining_size);
239 for (Int32 i = 0; i < nb_reduced_block; ++i) {
240 Int32 pos = block_index_in_original_array[i];
241 Int32 first_value = indexes[pos];
242 for (Int32 z = 1; z < block_size; ++z) {
243 Int32 diff = indexes[pos + z] - first_value;
244 local_block_values[z] = diff;
246 block_index_list.m_indexes.addRange(ConstArrayView<Int32>(block_size, local_block_values));
248 if (remaining_size != 0) {
249 Int32 pos = nb_fixed_block * block_size;
250 Int32 first_value = indexes[pos];
253 for (Int32 z = 1; z < remaining_size; ++z) {
254 Int32 diff = indexes[pos + z] - first_value;
255 local_block_values[z] = diff;
257 block_index_list.m_indexes.addRange(ConstArrayView<Int32>(remaining_size, local_block_values));
261 Int32 nb_contigu = block_index_list._computeNbContigusBlock();
265 info() <<
"Group Name=" << name <<
" original_size = " << original_size <<
" nb_block = " << nb_block
266 <<
" nb_contigu=" << nb_contigu
267 <<
" reduced_nb_block=" << block_indexes.size()
268 <<
" ratio=" << block_index_list.memoryRatio();
274BlockIndexListBuilder::
275BlockIndexListBuilder(ITraceMng* tm)
283void BlockIndexListBuilder::
284setBlockSizeAsPowerOfTwo(Int32 v)
287 _throwInvalidBlockSize(v);
288 Int32 block_size = 1 << v;
289 if (block_size > BlockIndex::MAX_BLOCK_SIZE)
290 _throwInvalidBlockSize(block_size);
291 m_block_size =
static_cast<Int16
>(block_size);
297void BlockIndexListBuilder::
298_throwInvalidBlockSize(Int32 block_size)
300 ARCANE_FATAL(
"Bad value for block size v={0} min=1 max={1}",
301 block_size, BlockIndex::MAX_BLOCK_SIZE);
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Integer size() const
Nombre d'éléments du vecteur.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
void addRange(ConstReferenceType val, Int64 n)
Ajoute n élément de valeur val à la fin du tableau.
void clear()
Supprime les éléments du tableau.
TraceMessage info() const
Flot pour un message d'information.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
double Real
Type représentant un réel.