Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
MatrixMarketSystemWriter.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/MatrixMarketSystemWriter.h>
20
21#include <sstream>
22#include <fstream>
23#include <string>
24#include <vector>
25
26#include <alien/kernels/simple_csr/SimpleCSRMatrix.h>
27#include <alien/kernels/simple_csr/SimpleCSRVector.h>
28
30
31#include <alien/ref/data/block/BlockMatrix.h>
32#include <alien/ref/data/block/BlockVector.h>
33#include <alien/ref/data/scalar/Matrix.h>
34#include <alien/ref/data/scalar/Vector.h>
35
36namespace Alien
37{
38
39MatrixMarketSystemWriter::MatrixMarketSystemWriter(std::string const& filename,
40 IMessagePassingMng* parallel_mng)
41: m_filename(filename)
42, m_parallel_mng(parallel_mng)
43{
44 m_rank = 0;
45 m_nproc = 1;
46 if (m_parallel_mng) {
47 m_rank = m_parallel_mng->commRank();
48 m_nproc = m_parallel_mng->commSize();
49 std::stringstream suf;
50 suf << "-R" << m_rank << "P" << m_nproc;
51 m_filename = filename + suf.str();
52 }
53 else {
54 m_filename = filename;
55 }
56}
57
58MatrixMarketSystemWriter::~MatrixMarketSystemWriter() {}
59
60void MatrixMarketSystemWriter::dump(Matrix const& A, std::string const& description)
61{
62 const SimpleCSRMatrix<Real>& csr = A.impl()->get<BackEnd::tag::simplecsr>();
63 const SimpleCSRMatrix<Real>::ProfileType& profile = csr.getProfile();
64 int nrows = profile.getNRows();
65 int nnz = profile.getNnz();
66
67 const int* cols = profile.cols();
68 const int* kcol = profile.kcol();
69 const double* values = csr.getAddressData();
70 if (m_nproc == 1) {
71 std::ofstream fout(m_filename);
72 fout << "%%MatrixMarket matrix coordinate real general" << std::endl;
73 fout << "%" << std::endl;
74 fout << "% " << description << std::endl;
75 fout << "%" << std::endl;
76 fout << "% #rows #cols #nonzeros" << std::endl;
77 fout << "% #vertices #hyperedges #pins" << std::endl;
78 fout << nrows << " " << nrows << " " << nnz << std::endl;
79 for (int irow = 0; irow < nrows; ++irow) {
80 for (int k = kcol[irow]; k < kcol[irow + 1]; ++k) {
81 fout << irow + 1 << " " << cols[k] + 1 << " " << values[k] << std::endl;
82 }
83 }
84 }
85 else {
86 int global_nrows = Arccore::MessagePassing::mpAllReduce(m_parallel_mng,
87 Arccore::MessagePassing::ReduceSum,
88 nrows);
89
90 int global_nnz = Arccore::MessagePassing::mpAllReduce(m_parallel_mng,
91 Arccore::MessagePassing::ReduceSum,
92 nnz);
93 if (m_rank == 0) {
94 std::ofstream fout(m_filename);
95 fout << "%%MatrixMarket matrix coordinate real general" << std::endl;
96 fout << "%" << std::endl;
97 fout << "% " << description << std::endl;
98 fout << "%" << std::endl;
99 fout << "% #rows #cols #nonzeros" << std::endl;
100 fout << "% #vertices #hyperedges #pins" << std::endl;
101 fout << global_nrows << " " << global_nrows << " " << global_nnz << std::endl;
102 for (int irow = 0; irow < nrows; ++irow) {
103 for (int k = kcol[irow]; k < kcol[irow + 1]; ++k) {
104 fout << irow + 1 << " " << cols[k] + 1 << " " << values[k] << std::endl;
105 }
106 }
107 for (int ip = 1; ip < m_nproc; ++ip) {
108 Integer local_nnz = 0;
109 Arccore::MessagePassing::mpReceive(m_parallel_mng, ArrayView<Integer>(1, &local_nnz), ip);
110 if (local_nnz > 0) {
111 UniqueArray<Integer> indexes(2 * local_nnz);
112 UniqueArray<Real> local_values(2 * local_nnz);
113 Arccore::MessagePassing::mpReceive(m_parallel_mng, indexes, ip);
114 Arccore::MessagePassing::mpReceive(m_parallel_mng, local_values, ip);
115 for (int k = 0; k < local_nnz; ++k) {
116 fout << indexes[2 * k] << " " << indexes[2 * k + 1] << " " << local_values[k] << std::endl;
117 }
118 }
119 }
120 }
121 else {
122 Arccore::MessagePassing::mpSend(m_parallel_mng, ArrayView<Integer>(1, &nnz), 0);
123 UniqueArray<Integer> indexes(2 * nnz);
124 UniqueArray<Real> local_values(nnz);
125 Integer domain_offset = csr.distribution().rowOffset();
126 for (int irow = 0; irow < nrows; ++irow) {
127 for (int k = kcol[irow]; k < kcol[irow + 1]; ++k) {
128 indexes[2 * k] = domain_offset + irow + 1;
129 indexes[2 * k + 1] = cols[k] + 1;
130 local_values[k] = values[k];
131 }
132 }
133 Arccore::MessagePassing::mpSend(m_parallel_mng, indexes, 0);
134 Arccore::MessagePassing::mpSend(m_parallel_mng, local_values, 0);
135 }
136 }
137}
138
139void MatrixMarketSystemWriter::dump(Vector const& rhs, std::string const& description)
140{
141 const SimpleCSRVector<Real>& v = rhs.impl()->get<BackEnd::tag::simplecsr>();
142 auto local_size = v.distribution().localSize();
143 const double* values = v.getAddressData();
144 if (m_nproc == 1) {
145 std::ofstream fout(m_filename);
146 fout << "%%MatrixMarket matrix array real general" << std::endl;
147 fout << "%" << std::endl;
148 fout << "% " << description << std::endl;
149 fout << "%" << std::endl;
150 fout << local_size << " 1" << std::endl;
151 for (int irow = 0; irow < local_size; ++irow) {
152 fout << irow + 1 << " " << values[irow] << std::endl;
153 }
154 }
155 else {
156 int global_size = Arccore::MessagePassing::mpAllReduce(m_parallel_mng,
157 Arccore::MessagePassing::ReduceSum,
158 local_size);
159 if (m_rank == 0) {
160 std::ofstream fout(m_filename);
161 fout << "%%MatrixMarket matrix array real general" << std::endl;
162 fout << "%" << std::endl;
163 fout << "% " << description << std::endl;
164 fout << "%" << std::endl;
165 fout << global_size << " 1" << std::endl;
166 for (int irow = 0; irow < local_size; ++irow) {
167 fout << irow + 1 << " " << values[irow] << std::endl;
168 }
169 for (int ip = 1; ip < m_nproc; ++ip) {
170 Integer local_nrows = 0;
171 Integer domain_offset = v.distribution().offset(ip);
172 Arccore::MessagePassing::mpReceive(m_parallel_mng, ArrayView<Integer>(1, &local_nrows), ip);
173 if (local_nrows > 0) {
174 UniqueArray<Real> local_values(local_nrows);
175 Arccore::MessagePassing::mpReceive(m_parallel_mng, local_values, ip);
176 for (int k = 0; k < local_nrows; ++k) {
177 fout << domain_offset + k + 1 << " " << local_values[k] << std::endl;
178 }
179 }
180 }
181 }
182 else {
183 Arccore::MessagePassing::mpSend(m_parallel_mng, ConstArrayView<Integer>(1, &local_size), 0);
184 Arccore::MessagePassing::mpSend(m_parallel_mng, ConstArrayView<Real>(local_size, values), 0);
185 }
186 }
187}
188
189} /* namespace Alien */
MultiVectorImpl.h.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Definition BackEnd.h:17