Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
Reader.h
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#pragma once
20
21#include <alien/data/IMatrix.h>
22#include <alien/data/IVector.h>
23#include <alien/handlers/scalar/BaseDirectMatrixBuilder.h>
24#include <alien/handlers/scalar/BaseVectorWriter.h>
25
26#include <vector>
27#include <string>
28#include <fstream>
29#include <cstdio>
30#ifdef ALIEN_USE_LIBARCHIVE
31#include <archive.h>
32#endif
33
34namespace Alien
35{
36
37class FStreamReader
38{
39 private:
40 std::fstream* m_file_stream = nullptr;
41 std::string m_line;
42
43 public:
44 FStreamReader() = delete;
45 FStreamReader(FStreamReader const&) = delete;
46 FStreamReader& operator=(FStreamReader const&) = delete;
47
48 explicit FStreamReader(std::fstream* fdes)
49 : m_file_stream(fdes)
50 {}
51
52 const char* line()
53 {
54 std::getline(*m_file_stream, m_line);
55
56 return m_line.c_str();
57 }
58
59 const char* currentLine() const
60 {
61 return m_line.c_str();
62 }
63};
64
65#ifdef ALIEN_USE_LIBARCHIVE
66class LibArchiveReader
67{
68 private:
69 const std::size_t m_buffer_size = 1024;
70
71 archive* m_archive = nullptr;
72 std::string m_line;
73 std::vector<char> m_buffer;
74 std::size_t m_pos = 0;
75
76 public:
77 LibArchiveReader() = delete;
78 LibArchiveReader(const LibArchiveReader&) = delete;
79 LibArchiveReader& operator=(const LibArchiveReader&) = delete;
80
81 LibArchiveReader(archive* archive)
82 : m_archive(archive)
83 , m_buffer(m_buffer_size, 0)
84 {
85 m_line.reserve(m_buffer_size);
86 }
87
88 const char* line()
89 {
90 la_ssize_t r = 1;
91
92 m_line.resize(0);
93
94 if (m_pos == 0) {
95 r = archive_read_data(m_archive, m_buffer.data(), m_buffer.size());
96 }
97
98 while (r > 0) {
99 for (auto i = m_pos; i < m_buffer_size; ++i) {
100 m_line.push_back(m_buffer[i]);
101 if (m_buffer[i] == '\n') {
102 m_pos = i + 1;
103 //std::cout << m_line;
104 return m_line.c_str();
105 }
106 }
107 // end of line is not found so read next buffer;
108 r = archive_read_data(m_archive, m_buffer.data(), m_buffer.size());
109 m_pos = 0;
110 }
111
112 // end of file reached
113 return m_line.c_str();
114 }
115
116 const char* currentLine() const
117 {
118 return m_line.c_str();
119 }
120};
121#endif
122
123template <typename ReaderT>
124bool readMMHeaderFromReader(const std::string& mm_type, ReaderT& reader)
125{
126 // check header
127 char param1[32];
128 char param2[32];
129 char param3[32];
130 char param4[32];
131
132 // TODO: use methods that directly read from std::string
133 if (sscanf(reader.line(), "%%%%MatrixMarket %31s %31s %31s %31s", param1, param2, param3, param4) != 4) {
134 throw FatalErrorException(A_FUNCINFO, "Matrix market wrong header");
135 }
136 if (std::string(param1) != std::string("matrix")) {
137 throw FatalErrorException(A_FUNCINFO, "Matrix market wrong header 1");
138 }
139 if (std::string(param2) != mm_type) {
140 throw FatalErrorException(A_FUNCINFO, "Matrix market wrong header 2");
141 }
142 if (std::string(param3) != std::string("real")) {
143 throw FatalErrorException(A_FUNCINFO, "Matrix market wrong header 3");
144 }
145
146 // skip comments
147 while (reader.line()[0] == '%')
148 ;
149
150 return std::string(param4) == std::string("symmetric");
151}
152
153template <typename MatrixT, typename ReaderT>
154void loadMMMatrixFromReader(MatrixT& A, ReaderT& reader)
155{
156 bool is_symmetric = readMMHeaderFromReader("coordinate", reader);
157
158 // first non comment line is: n m nnz
159 int n, m, nnz;
160 if (sscanf(reader.currentLine(), "%d %d %d", &n, &m, &nnz) != 3) {
161 perror("read mtx size line");
162 throw FatalErrorException(A_FUNCINFO, "IOError");
163 }
164
165 Alien::MatrixDistribution dist(n, m, n, nullptr);
166
167 A = MatrixT(dist);
168
169 DirectMatrixOptions::SymmetricFlag sym_flag = is_symmetric ? DirectMatrixOptions::eSymmetric : DirectMatrixOptions::eUnSymmetric;
170
171 Common::DirectMatrixBuilder matrix_builder(A, DirectMatrixOptions::eResetAllocation, sym_flag);
172 matrix_builder.allocate();
173
174 for (int i = 0; i < nnz; ++i) {
175 int li = 0;
176 int ci = 0;
177 double val = 0;
178
179 if (sscanf(reader.line(), "%d %d %lg\n", &li, &ci, &val) != 3) {
180 perror("read mtx line");
181 throw FatalErrorException(A_FUNCINFO, "IOError");
182 }
183 li--;
184 ci--;
185
186 matrix_builder.addData(li, ci, val);
187 }
188}
189
190template <typename VectorT, typename ReaderT>
191void loadMMRhsFromReader(VectorT& rhs, ReaderT& reader)
192{
193 readMMHeaderFromReader("array", reader);
194
195 // first non comment line is: n m
196 int n, m;
197 if (sscanf(reader.currentLine(), "%d %d", &n, &m) != 2) {
198 perror("read mtx size line");
199 throw FatalErrorException(A_FUNCINFO, "IOError");
200 }
201
202 if (m > 1) // does not allow more than one vector
203 {
204 throw FatalErrorException(A_FUNCINFO, "More than one vector not allowed");
205 }
206
207 Alien::VectorDistribution dist(n, n, nullptr);
208
209 rhs = VectorT(dist);
210
212
213 for (int i = 0; i < n; ++i) {
214 double val = 0;
215 if (sscanf(reader.line(), "%lg\n", &val) != 1) {
216 perror("read mtx line");
217 throw FatalErrorException(A_FUNCINFO, "IOError");
218 }
219
220 vector_writer[i] = val;
221 }
222}
223
224} // namespace Alien
IMatrix.h.
IVector.h.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Definition BackEnd.h:17