Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
SystemReader.cc
1/*
2 * Copyright 2020 IFPEN-CEA
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * SPDX-License-Identifier: Apache-2.0
17 */
18
19#include <alien/ref/import_export/SystemReader.h>
20
21#include <string>
22#include <vector>
23
24#include <alien/ref/AlienRefSemantic.h>
25
26#ifdef ALIEN_USE_HDF5
27#include <hdf5.h>
28#endif
29
30#ifdef ALIEN_USE_LIBXML2
31#include <libxml/parser.h>
32#endif
33
34#include "HDF5Tools.h"
35
36namespace Alien
37{
38
39SystemReader::SystemReader(
40std::string const& filename, std::string format, IMessagePassingMng* parallel_mng)
41: m_filename(filename)
42, m_format(format)
43, m_prec(6)
44, m_parallel_mng(parallel_mng)
45{
46 m_rank = 0;
47 m_nproc = 1;
48 if (m_parallel_mng) {
49 m_parallel_mng->commRank();
50 m_parallel_mng->commSize();
51 }
52}
53
54SystemReader::~SystemReader() {}
55
56template <typename FileNodeT>
57void SystemReader::_readMatrixInfo(Importer& importer, FileNodeT& parent_node, int& nrows,
58 int& ncols, int& nnz, int& blk_size, int& blk_size2)
59{
60 FileNodeT matrix_info_node = importer.openFileNode(parent_node, "matrix-info");
61 importer.read(matrix_info_node, "nrows", nrows);
62 importer.read(matrix_info_node, "ncols", ncols);
63 importer.read(matrix_info_node, "nnz", nnz);
64 {
65 std::vector<int>& i32buffer = importer.i32buffer;
66 i32buffer.resize(2);
67 importer.read(matrix_info_node, "blk-size", i32buffer);
68 blk_size = i32buffer[0];
69 blk_size2 = i32buffer[1];
70 }
71 importer.closeFileNode(matrix_info_node);
72}
73
74template <typename FileNodeT>
75void SystemReader::_readCSRProfile(Importer& importer, FileNodeT& parent_node, int& nrows,
76 int& nnz, std::vector<int>& kcol, std::vector<int>& cols)
77{
78 FileNodeT profile_node = importer.openFileNode(parent_node, "profile");
79
80 importer.read(profile_node, "nrows", nrows);
81 importer.read(profile_node, "nnz", nnz);
82
83 kcol.resize(nrows + 1);
84 importer.read(profile_node, "kcol", kcol);
85
86 cols.resize(nnz);
87 importer.read(profile_node, "cols", cols);
88
89 importer.closeFileNode(profile_node);
90}
91
92template <typename FileNodeT>
93void SystemReader::_readMatrixValues(Importer& importer, FileNodeT& parent_node, int& size,
94 int& blk_size, int& blk_size2, std::vector<double>& values)
95{
96 std::vector<int>& i32buffer = importer.i32buffer;
97 FileNodeT data_node = importer.openFileNode(parent_node, "data");
98 {
99 {
100 FileNodeT info_node = importer.openFileNode(data_node, "struct-info");
101
102 importer.read(info_node, "size", size);
103
104 {
105 i32buffer.reserve(2);
106 importer.read(info_node, "blk-size", i32buffer);
107 blk_size = i32buffer[0];
108 blk_size = i32buffer[1];
109 }
110 importer.closeFileNode(info_node);
111 }
112 values.resize(size * blk_size * blk_size2);
113 importer.read(data_node, "values", values);
114 }
115 importer.closeFileNode(data_node);
116}
117
118void SystemReader::read(Matrix& A)
119{
120
121 typedef Importer::FileNode FileNode;
122
123 Importer importer(m_filename, m_format, m_prec);
124
125 int nrows = 0;
126 int ncols = 0;
127 int nnz = 0;
128 int blk_size = 1;
129 std::vector<int> kcol;
130 std::vector<int> cols;
131 std::vector<double> values;
132
133 FileNode root_node = importer.openFileNode("system");
134 {
135 FileNode matrix_node = importer.openFileNode(root_node, "matrix");
136 {
137 int file_blk_size;
138 int file_blk_size2;
139 _readMatrixInfo(
140 importer, matrix_node, nrows, ncols, nnz, file_blk_size, file_blk_size2);
141 if (file_blk_size != blk_size || file_blk_size2 != blk_size)
142 throw FatalErrorException(
143 A_FUNCINFO, "Incompatible block size with imported system");
144
145 const auto& dist = A.distribution();
146 int offset = dist.rowOffset();
147 int lsize = dist.localRowSize();
148
149 if (offset + lsize > nrows)
150 throw FatalErrorException(
151 A_FUNCINFO, "Incompatible space size with imported system");
152
153 int file_nrows;
154 int file_nnz;
155
156 // TODO: only read profile from offset to offset + lsize
157 // or explicitly distribute profile according to distribution
158 _readCSRProfile(importer, matrix_node, file_nrows, file_nnz, kcol, cols);
159
160 if (file_nrows != nrows || file_nnz != nnz)
161 throw FatalErrorException(A_FUNCINFO, "Incoherent matrix profile");
162
163 {
164 Alien::MatrixProfiler profiler(A);
165
166 for (int irow = offset; irow < offset + lsize; ++irow) {
167 for (int k = kcol[irow]; k < kcol[irow + 1]; ++k) {
168 profiler.addMatrixEntry(irow, cols[k]);
169 }
170 }
171 }
172
173 // TODO: only read values from offset to offset + lsize
174 // or explicitly distribute values according to distribution
175
176 _readMatrixValues(
177 importer, matrix_node, file_nnz, file_blk_size, file_blk_size2, values);
178
179 if (file_nnz != nnz || file_blk_size != 1 || file_blk_size2 != 1)
180 throw FatalErrorException(A_FUNCINFO, "Incoherent matrix values");
181
183 A, Alien::ProfiledMatrixOptions::eResetValues);
184
185 for (int irow = offset; irow < offset + lsize; ++irow) {
186 for (int k = kcol[irow]; k < kcol[irow + 1]; ++k) {
187 builder(irow, cols[k]) = values[k];
188 }
189 }
190 }
191 importer.closeFileNode(matrix_node);
192 }
193 importer.closeFileNode(root_node);
194}
195
196void SystemReader::read(BlockMatrix& A)
197{
198 typedef Importer::FileNode FileNode;
199
200 Importer importer(m_filename, m_format, m_prec);
201
202 int nrows = 0;
203 int ncols = 0;
204 int nnz = 0;
205 int blk_size = 1;
206 int blk_size2 = 1;
207 std::vector<int> kcol;
208 std::vector<int> cols;
209 std::vector<double> values;
210
211 FileNode root_node = importer.openFileNode("system");
212 {
213 FileNode matrix_node = importer.openFileNode(root_node, "matrix");
214 {
215 int file_blk_size;
216 int file_blk_size2;
217 _readMatrixInfo(
218 importer, matrix_node, nrows, ncols, nnz, file_blk_size, file_blk_size2);
219
220 if (file_blk_size != file_blk_size2)
221 throw FatalErrorException(A_FUNCINFO, "Non square block not supported");
222
223 blk_size = file_blk_size;
224 blk_size2 = blk_size;
225 const Alien::Block block(blk_size);
226
227 A = BlockMatrix(nrows, nrows, block, m_parallel_mng);
228
229 const auto& dist = A.distribution();
230
231 int offset = dist.rowOffset();
232 int lsize = dist.localRowSize();
233
234 if (offset + lsize > nrows)
235 throw FatalErrorException(
236 A_FUNCINFO, "Incompatible space size with imported system");
237
238 int file_nrows;
239 int file_nnz;
240 // TODO: only read profile from offset to offset + lsize
241 // or explicitly distribute profile according to distribution
242 _readCSRProfile(importer, matrix_node, file_nrows, file_nnz, kcol, cols);
243
244 if (file_nrows != nrows || file_nnz != nnz)
245 throw FatalErrorException(A_FUNCINFO, "Incoherent matrix profile");
246
247 {
248 Alien::MatrixProfiler profiler(A);
249
250 for (int irow = offset; irow < offset + lsize; ++irow) {
251 for (int k = kcol[irow]; k < kcol[irow + 1]; ++k)
252 profiler.addMatrixEntry(irow, cols[k]);
253 }
254 }
255
256 // TODO: only read values from offset to offset + lsize
257 // or explicitly distribute values according to distribution
258 _readMatrixValues(
259 importer, matrix_node, file_nnz, file_blk_size, file_blk_size2, values);
260
261 if (file_nnz != nnz || file_blk_size != blk_size || file_blk_size2 != blk_size2)
262 throw FatalErrorException(A_FUNCINFO, "Incoherent matrix values");
263
264 {
266 A, Alien::ProfiledBlockMatrixBuilderOptions::eResetValues);
267
268 // dist = A.distribution();
269 // offset = dist.rowOffset();
270 // lsize = dist.localRowSize();
271
272 for (int irow = offset; irow < offset + lsize; ++irow) {
273 for (int k = kcol[irow]; k < kcol[irow + 1]; ++k)
274 builder(irow, cols[k]) =
275 Array2View<double>(&values[k * blk_size * blk_size], blk_size, blk_size);
276 }
277 }
278 }
279 importer.closeFileNode(matrix_node);
280 }
281 importer.closeFileNode(root_node);
282}
283/*
284 void SystemReader::read(Vector & x)
285 {
286 typedef Importer::FileNode FileNode ;
287
288 Importer importer(m_filename,m_format,m_prec) ;
289 std::vector<double>& rbuffer = importer.rbuffer ;
290 std::vector<int>& i32buffer = importer.i32buffer ;
291
292 int nrows = 0 ;
293 int blk_size = 1 ;
294
295 FileNode root_node = importer.openFileRootNode() ;
296 {
297 FileNode vector_node = importer.openFileNode(root_node,"vector") ;
298 {
299 FileNode info_node = importer.openFileNode(vector_node,"struct-info") ;
300 {
301 FileNode nrows_node = importer.openFileNode(info_node,"nrows") ;
302 i32buffer.resize(1) ;
303 importer.read(nrows_node,i32buffer) ;
304 importer.closeFileNode(nrows_node) ;
305 nrows = i32buffer[0] ;
306 }
307 {
308 FileNode blk_size_node = importer.openFileNode(info_node,"blk-size") ;
309 i32buffer.resize(1) ;
310 importer.read(blk_size_node,i32buffer) ;
311 importer.closeFileNode(blk_size_node) ;
312 blk_size = i32buffer[0] ;
313 }
314 importer.closeFileNode(info_node) ;
315
316 x = Vector(nrows,m_parallel_mng) ;
317
318 const auto& dist = x.distribution();
319 int offset = dist.offset();
320 int lsize = dist.localSize();
321
322 FileNode data_node = importer.openFileNode(vector_node,"data") ;
323 {
324
325
326 FileNode values_node = importer.openFileNode(data_node,"values") ;
327 rbuffer.resize(nrows*blk_size) ;
328 importer.read(values_node,rbuffer) ;
329 importer.closeFileNode(values_node) ;
330
331 // Builder du vecteur
332 Alien::VectorWriter writer(x);
333
334 // On remplit le vecteur
335 for(int i = 0; i < lsize; ++i) {
336 writer[i+offset] = rbuffer[(offset+i)*blk_size];
337 }
338 }
339 importer.closeFileNode(data_node) ;
340 }
341 importer.closeFileNode(vector_node) ;
342 }
343 importer.closeFileNode(system_node) ;
344 importer.closeFileRootNode(root_node) ;
345 }
346
347
348
349 void SystemReader::read(BlockVector & x)
350 {
351
352 typedef Exporter::FileNode FileNode ;
353
354 Importer importer(m_filename,m_format,m_prec) ;
355 std::vector<double>& rbuffer = importer.rbuffer ;
356 std::vector<int>& i32buffer = importer.i32buffer ;
357
358 int nrows = 0 ;
359 int blk_size = 1 ;
360
361 FileNode root_node = importer.openFileRootNode() ;
362 FileNode system_node = importer.openFileNode(root_node,"system") ;
363 {
364 FileNode vector_node = importer.openFileNode(root_node,"vector") ;
365 {
366 FileNode info_node = importer.openFileNode(vector_node,"struct-info") ;
367 {
368 FileNode nrows_node = importer.openFileNode(info_node,"nrows") ;
369 i32buffer.resize(1) ;
370 importer.read(nrows_node,i32buffer) ;
371 importer.closeFileNode(nrows_node) ;
372 nrows = i32buffer[0] ;
373 }
374 {
375 FileNode blk_size_node = importer.openFileNode(info_node,"blk-size") ;
376 i32buffer.resize(1) ;
377 importer.read(blk_size_node,i32buffer) ;
378 importer.closeFileNode(blk_size_node) ;
379 blk_size = i32buffer[0] ;
380 }
381 importer.closeFileNode(info_node) ;
382
383 const Alien::Block block(blk_size);
384 x = BlockVector(nrows,block,m_parallel_mng) ;
385
386 const auto& dist = x.distribution();
387 int offset = dist.offset();
388 int lsize = dist.localSize();
389
390 FileNode data_node = importer.openFileNode(vector_node,"data") ;
391 {
392 FileNode values_node = importer.openFileNode(data_node,"values") ;
393 rbuffer.resize(nrows*blk_size) ;
394 importer.read(values_node,rbuffer) ;
395 importer.closeFileNode(values_node) ;
396
397 // Builder du vecteur
398 Alien::BlockVectorWriter writer(x);
399
400 // On remplit le vecteur
401 for(int i = 0; i < lsize; ++i) {
402 writer[i+offset] = ArrayView<double>(blk_size,&rbuffer[(offset+i)*blk_size]);
403 }
404 }
405 importer.closeFileNode(data_node) ;
406 }
407 importer.closeFileNode(vector_node) ;
408 }
409 importer.closeFileNode(system_node) ;
410 importer.closeFileRootNode(root_node) ;
411 }
412 */
413} /* namespace Alien */
Block elements for block matrices.
Definition Block.h:45
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Definition BackEnd.h:17