23#include <arccore/base/FatalErrorException.h>
24#include <arccore/message_passing/IMessagePassingMng.h>
30#include <alien/move/data/MatrixData.h>
31#include <alien/move/handlers/scalar/DoKDirectMatrixBuilder.h>
32#include <alien/move/data/VectorData.h>
33#include <alien/kernels/dok/DoKVector.h>
34#include <alien/kernels/dok/DoKBackEnd.h>
41 std::pair<size_t, size_t> partition(
size_t full_size,
const Arccore::MessagePassing::IMessagePassingMng* pm)
43 auto my_rank = pm->commRank();
44 auto comm_size = pm->commSize();
45 size_t line_slice = full_size / comm_size;
46 auto start = line_slice * my_rank;
47 auto stop = line_slice * (my_rank + 1);
48 if (my_rank == comm_size - 1) {
51 return std::make_pair(start, stop);
54 void tolower(std::string& str)
56 std::transform(str.begin(), str.end(), str.begin(), ::tolower);
59 class MatrixDescription
62 MatrixDescription() =
default;
67 bool symmetric{
true };
70 std::optional<MatrixDescription> readBanner(std::istream& fstream)
74 MatrixDescription out;
76 auto try_header =
true;
78 while (std::getline(fstream, line)) {
92 if (
"%%MatrixMarket" != matrix) {
105 if (
"coordinate" != format) {
109 if (
"real" != scalar) {
113 if (
"general" == symmetry) {
114 out.symmetric =
false;
117 out.symmetric =
true;
121 else if (
'%' == line[0]) {
133 return std::make_optional(out);
136 bool readValues(std::istream& fstream,
DoKDirectMatrixBuilder& builder,
bool symmetric,
size_t start,
size_t stop)
138 for (
size_t i = 0; i < start; ++i) {
139 fstream.ignore(4096,
'\n');
143 size_t count = start;
144 while (count < stop && std::getline(fstream, line)) {
145 if (
'%' == line[0]) {
153 std::stringstream ss;
155 ss >> row >> col >> value;
156 builder.contribute(row - 1, col - 1, value);
157 if (symmetric && row != col) {
158 builder.contribute(col - 1, row - 1, value);
164 MatrixData createMatrixData(MatrixDescription desc, Arccore::MessagePassing::IMessagePassingMng* pm)
166 Alien::Space row_space(desc.n_rows,
"RowSpace");
167 Alien::Space col_space(desc.n_cols,
"ColSpace");
168 Alien::MatrixDistribution dist(
169 row_space, col_space, pm);
170 return Alien::Move::MatrixData(dist);
176readFromMatrixMarket(Arccore::MessagePassing::IMessagePassingMng* pm,
const std::string& filename)
178 std::ifstream stream;
179 std::array<char, 1024 * 1024> buf;
180 stream.rdbuf()->pubsetbuf(buf.data(), buf.size());
181 stream.open(filename);
183 throw Arccore::FatalErrorException(
"readFromMatrixMarket",
"Unable to matrix read file");
185 auto desc = readBanner(stream);
187 throw Arccore::FatalErrorException(
"readFromMatrixMarket",
"Invalid header");
191 auto [nnz_start, nnz_stop] = partition(desc.value().n_nnz, pm);
192 readValues(stream, builder, desc->symmetric, nnz_start, nnz_stop);
193 return builder.release();
197readFromMatrixMarket(
const VectorDistribution& distribution,
const std::string& filename)
200 auto& v = out.impl()->template get<BackEnd::tag::DoK>(
true);
202 std::ifstream stream;
203 std::array<char, 1024 * 1024> buf;
204 stream.rdbuf()->pubsetbuf(buf.data(), buf.size());
205 stream.open(filename);
207 throw Arccore::FatalErrorException(
"readFromMatrixMarket",
"Unable to read vector file");
212 auto try_header =
true;
213 while (std::getline(stream, line)) {
215 std::stringstream ss;
226 if (
"%%MatrixMarket" != matrix)
237 if (
"array" != format ||
"real" != scalar) {
238 throw Arccore::FatalErrorException(
"mtx vector must be in 'array' and 'real' formats.");
249 throw Arccore::FatalErrorException(
"mtx vector reader does not support multiple vectors.");
251 if (distribution.globalSize() != rows) {
252 throw Arccore::FatalErrorException(
"mtx vector is not of correct size");
257 auto [row_start, row_stop] = partition(rows, distribution.parallelMng());
259 Arccore::Int32 row = 0;
260 for (row = 0; row < row_start; ++row) {
261 stream.ignore(4096,
'\n');
264 while (row < row_stop && std::getline(stream, line)) {
266 std::stringstream ss;
270 v.contribute(row, value);
Algebraic Matrix with internal multi-representation object.
Algebraic Vector with internal multi-representation object.