Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
MultiMatrixImpl.cc
Go to the documentation of this file.
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
23
24#include "MultiMatrixImpl.h"
25
27#include <alien/kernels/simple_csr/SimpleCSRMatrix.h>
28#include <cstdlib>
29#include <iostream>
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34namespace Alien
35{
36
37using namespace Arccore;
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
43: m_block(nullptr)
44, m_rows_block(nullptr)
45, m_cols_block(nullptr)
46{}
47
48/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
50
51MultiMatrixImpl::MultiMatrixImpl(std::shared_ptr<ISpace> row_space,
52 std::shared_ptr<ISpace> col_space, std::shared_ptr<MatrixDistribution> dist)
53: m_row_space(row_space)
54, m_col_space(col_space)
55, m_distribution(dist)
56, m_block(nullptr)
57, m_rows_block(nullptr)
58, m_cols_block(nullptr)
59{}
60
61/*---------------------------------------------------------------------------*/
62/*---------------------------------------------------------------------------*/
63
65: TimestampMng(impl)
69, m_block(nullptr)
70, m_rows_block(nullptr)
71, m_cols_block(nullptr)
72{
73 if (impl.m_block)
74 m_block = impl.m_block;
75 if (impl.m_rows_block)
77 if (impl.m_cols_block)
79}
80
81/*---------------------------------------------------------------------------*/
82/*---------------------------------------------------------------------------*/
83
88
89/*---------------------------------------------------------------------------*/
90/*---------------------------------------------------------------------------*/
91
92void MultiMatrixImpl::setBlockInfos(Integer block_size)
93{
94 m_block.reset(new Block(block_size));
95}
96
97/*---------------------------------------------------------------------------*/
98/*---------------------------------------------------------------------------*/
99
101{
102 m_block = blocks->clone();
103}
104
105/*---------------------------------------------------------------------------*/
106/*---------------------------------------------------------------------------*/
107
109{
110 m_rows_block = blocks->clone();
111}
112
113/*---------------------------------------------------------------------------*/
114/*---------------------------------------------------------------------------*/
115
117{
118 m_rows_block = blocks->clone();
119}
120
121/*---------------------------------------------------------------------------*/
122/*---------------------------------------------------------------------------*/
123
125{
126 m_cols_block = blocks->clone();
127}
128
129/*---------------------------------------------------------------------------*/
130/*---------------------------------------------------------------------------*/
131
133{
134 for (auto i = m_impls2.begin(); i != m_impls2.end(); ++i) {
135 delete i->second;
136 i->second = NULL;
137 }
138 m_impls2.clear();
139}
140
141/*---------------------------------------------------------------------------*/
142/*---------------------------------------------------------------------------*/
143
145{
146 for (auto i = m_impls2.begin(); i != m_impls2.end(); ++i) {
147 i->second->clear();
148 }
149}
150
151/*---------------------------------------------------------------------------*/
152/*---------------------------------------------------------------------------*/
153
154const Block*
156{
157 return m_block.get();
158}
159
160/*---------------------------------------------------------------------------*/
161/*---------------------------------------------------------------------------*/
162
163const VBlock*
165{
166 return m_rows_block.get();
167}
168
169/*---------------------------------------------------------------------------*/
170/*---------------------------------------------------------------------------*/
171
172const VBlock*
174{
175 if (m_cols_block.get())
176 return m_cols_block.get();
177 else
178 return rowBlock();
179}
180
181/*---------------------------------------------------------------------------*/
182/*---------------------------------------------------------------------------*/
183
184const VBlock*
186{
187 return m_rows_block.get();
188}
189
190/*---------------------------------------------------------------------------*/
191/*---------------------------------------------------------------------------*/
192
195{
196 // Initialize muli-representation without data
197 auto impl = new MultiMatrixImpl(*this);
198
199 typedef BackEnd::tag::simplecsr tag;
200 // We get the last up to date implementation
201 const SimpleCSRMatrix<Real>& matrixToClone = this->get<tag>();
202 // And clone it
203 SimpleCSRMatrix<Real>* matrixCloned = matrixToClone.cloneTo(impl);
204 matrixCloned->setTimestamp(impl, matrixToClone.timestamp());
205 matrixCloned->updateTimestamp();
206 impl->m_impls2.insert(
207 MultiMatrixImplMap::value_type(AlgebraTraits<tag>::name(), matrixCloned));
208
209 // TOCHECK: to be removed or not ?
210 /* WARNING: this implementation is temporary. Later it should be implemented through a
211 clone() method for each kernel as written lower.
212 For now, we will convert the last up to date matrix in SimpleCSRMatrix, then clone
213 it.
214
215 for(std::map<BackEndId, IMatrixImpl*>::const_iterator it = m_impls2.begin(); it !=
216 m_impls2.end(); ++it)
217 impl->m_impls2.insert(MultiMatrixImplMap::value_type(it->first,
218 it->second->clone()));
219 */
220 return impl;
221}
222
223/*---------------------------------------------------------------------------*/
224/*---------------------------------------------------------------------------*/
225
227{
228 // If we are up to date, do nothing
229 if (timestamp() == target->timestamp()) {
230 return;
231 }
232
233 // Otherwise we are looking for a converter
234 for (auto& impl : m_impls2) {
235 auto* candidate = impl.second;
236 // if the timestamp is not good we keep looking
237 if (candidate->timestamp() != timestamp())
238 continue;
239 auto* converter =
240 MatrixConverterRegisterer::getConverter(candidate->backend(), target->backend());
241 // If no converter is found, we continue
242 if (converter == nullptr)
243 continue;
244 // Otherwise we convert the matrix and return
245 converter->convert(candidate, target);
246 target->copyTimestamp(*candidate);
247 return;
248 }
249
250 // If there is no candidate up to date, throw an error
251 UniqueArray<IMatrixImpl*> candidates;
252 for (auto& impl : m_impls2) {
253 auto* candidate = impl.second;
254 if (candidate->timestamp() == timestamp())
255 candidates.add(candidate);
256 }
257 if (candidates.empty()) {
258 auto msg = String::format("Matrix converter to: ", target->backend(),
259 " internal error: no timestamp matching");
260 throw FatalErrorException(A_FUNCINFO, msg);
261 }
262
263 // Otherwise, we have candidates but no converter
264 // In that case we try to use simplecsr as a third party converter
265
266 // Error message that will be printed
267 auto print_error = [&] {
268 alien_fatal([&] {
269 cout() << "ALIEN FATAL ERROR \n"
270 << "Matrix converting to target backend '" << target->backend() << "' :\n"
271 << "* no converter available from source backend(s)";
272
273 for (auto* candidate : candidates) {
274 cout() << " ** '" << candidate->backend() << "'";
275 }
276 cout();
277 });
278 };
279
280 // Request simplecsr implementation
281 auto* simplecsr = getImpl<SimpleCSRMatrix<Real>>("simplecsr");
282
283 // Checking that we have a converter from simplecsr to the requested implementation
284 auto* simplecsr_target =
285 MatrixConverterRegisterer::getConverter(simplecsr->backend(), target->backend());
286
287 // If not, throw error
288 if (simplecsr_target == nullptr)
289 print_error();
290
291 // We look for each candidate
292 for (auto* candidate : candidates) {
293 auto* candidat_simplecsr = MatrixConverterRegisterer::getConverter(
294 candidate->backend(), simplecsr->backend());
295 // If we have one, we can convert to the requested implementation through simplecsr
296 if (candidat_simplecsr != nullptr) {
297 // Conversion from candidate to simplecsr
298 candidat_simplecsr->convert(candidate, simplecsr);
299 simplecsr->copyTimestamp(*candidate);
300 // Conversion from simplecsr to target
301 simplecsr_target->convert(simplecsr, target);
302 target->copyTimestamp(*simplecsr);
303 return;
304 }
305 }
306
307 // If we reach this line, all conversions possibilities have failed. Throw an exception
308 print_error();
309}
310
311/*---------------------------------------------------------------------------*/
312/*---------------------------------------------------------------------------*/
313
314} // namespace Alien
315
316/*---------------------------------------------------------------------------*/
317/*---------------------------------------------------------------------------*/
Block.h.
MultiMatrixImpl.h.
Block elements for block matrices.
Definition Block.h:45
std::shared_ptr< Block > clone() const
Clone this object.
Definition Block.cc:117
Interface to handle abstract matrices implementation.
Definition IMatrixImpl.h:47
virtual BackEndId backend() const
Definition IMatrixImpl.h:94
static IMatrixConverter * getConverter(BackEndId from, BackEndId to)
Get the converter from one matrix format to another one.
Multi matrices representation container.
void setColBlockInfos(const VBlock *blocks)
Set variable col block information.
std::shared_ptr< ISpace > m_row_space
The matrix row space.
std::shared_ptr< MatrixDistribution > m_distribution
The matrix distribution.
void setRowBlockInfos(const VBlock *blocks)
Set variable row block information.
void updateImpl(IMatrixImpl *target) const
Update a matrix implementation.
MultiMatrixImpl * clone() const
Clone this object.
MultiMatrixImpl()
Default constructor.
std::shared_ptr< VBlock > m_cols_block
The variable col block datas.
std::shared_ptr< Block > m_block
The uniform block datas.
void clear()
Clear resources.
void free()
Free resources.
IMatrixImpl *& getImpl(BackEndId backend) const
Get a specific matrix implementation.
std::shared_ptr< ISpace > m_col_space
The matrix column space.
virtual ~MultiMatrixImpl()
Free resources.
std::shared_ptr< VBlock > m_rows_block
The variable row block datas.
const Block * block() const
Get uniform block datas.
const VBlock * colBlock() const
Get variable col block datas.
MultiMatrixImplMap m_impls2
The matrices container.
const AlgebraTraits< tag >::matrix_type & get() const
Get a specific matrix implementation.
const VBlock * rowBlock() const
Get variable row block datas.
const VBlock * vblock() const
Get variable block datas.
void setBlockInfos(Arccore::Integer block_size)
Set uniform block information.
Int64 timestamp() const
Valeur du timestamp de référence.
virtual Int64 timestamp() const
Donne la valeur courante du timestamp.
Definition Timestamp.cc:43
void updateTimestamp()
Met à jour le timestamp.
Definition Timestamp.cc:50
void copyTimestamp(const Timestamp &v)
Copy un autre timestamp.
Definition Timestamp.cc:58
Variable size block elements for block matrices.
Definition VBlock.h:46
std::shared_ptr< VBlock > clone() const
Copy this object.
Definition VBlock.cc:184
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Definition BackEnd.h:17