ViennaCL - The Vienna Computing Library: viennacl/linalg/detail/ilu/common.hpp Source File

ViennaCL - The Vienna Computing Library 1.7.1 Free open-source GPU-accelerated linear algebra and solver library. |

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
common.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_LINALG_DETAIL_ILU_COMMON_HPP_
2 #define VIENNACL_LINALG_DETAIL_ILU_COMMON_HPP_
3
4 /* =========================================================================
5 Copyright (c) 2010-2016, Institute for Microelectronics,
6 Institute for Analysis and Scientific Computing,
7 TU Wien.
8 Portions of this software are copyright by UChicago Argonne, LLC.
9
10 -----------------
11 ViennaCL - The Vienna Computing Library
12 -----------------
13
14 Project Head: Karl Rupp rupp@iue.tuwien.ac.at
15
16 (A list of authors and contributors can be found in the manual)
17
18 License: MIT (X11), see file LICENSE in the base directory
19 ============================================================================= */
20
25 #include <vector>
26 #include <cmath>
27 #include <iostream>
28 #include <map>
29 #include <list>
30
31 #include "viennacl/forwards.h"
32 #include "viennacl/tools/tools.hpp"
33 #include "viennacl/backend/memory.hpp"
34
35 #include "viennacl/linalg/host_based/common.hpp"
36 #include "viennacl/linalg/misc_operations.hpp"
37
38 namespace viennacl
39 {
40 namespace linalg
41 {
42 namespace detail
43 {
44
45
46 //
47 // Level Scheduling Setup for ILU:
48 //
49
50 template<typename NumericT, unsigned int AlignmentV>
51 void level_scheduling_setup_impl(viennacl::compressed_matrix<NumericT, AlignmentV> const & LU,
52 viennacl::vector<NumericT> const & diagonal_LU,
53 std::list<viennacl::backend::mem_handle> & row_index_arrays,
54 std::list<viennacl::backend::mem_handle> & row_buffers,
55 std::list<viennacl::backend::mem_handle> & col_buffers,
56 std::list<viennacl::backend::mem_handle> & element_buffers,
57 std::list<vcl_size_t> & row_elimination_num_list,
58 bool setup_U)
59 {
60 NumericT const * diagonal_buf = viennacl::linalg::host_based::detail::extract_raw_pointer<NumericT>(diagonal_LU.handle());
61 NumericT const * elements = viennacl::linalg::host_based::detail::extract_raw_pointer<NumericT>(LU.handle());
62 unsigned int const * row_buffer = viennacl::linalg::host_based::detail::extract_raw_pointer<unsigned int>(LU.handle1());
63 unsigned int const * col_buffer = viennacl::linalg::host_based::detail::extract_raw_pointer<unsigned int>(LU.handle2());
64
65 //
66 // Step 1: Determine row elimination order for each row and build up meta information about the number of entries taking part in each elimination step:
67 //
68 std::vector<vcl_size_t> row_elimination(LU.size1());
69 std::map<vcl_size_t, std::map<vcl_size_t, vcl_size_t> > row_entries_per_elimination_step;
70
71 vcl_size_t max_elimination_runs = 0;
72 for (vcl_size_t row2 = 0; row2 < LU.size1(); ++row2)
73 {
74 vcl_size_t row = setup_U ? (LU.size1() - row2) - 1 : row2;
75
76 vcl_size_t row_begin = row_buffer[row];
77 vcl_size_t row_end = row_buffer[row+1];
78 vcl_size_t elimination_index = 0; //Note: first run corresponds to elimination_index = 1 (otherwise, type issues with int <-> unsigned int would arise
79 for (vcl_size_t i = row_begin; i < row_end; ++i)
80 {
81 unsigned int col = col_buffer[i];
82 if ( (!setup_U && col < row) || (setup_U && col > row) )
83 {
84 elimination_index = std::max<vcl_size_t>(elimination_index, row_elimination[col]);
85 row_entries_per_elimination_step[row_elimination[col]][row] += 1;
86 }
87 }
88 row_elimination[row] = elimination_index + 1;
89 max_elimination_runs = std::max<vcl_size_t>(max_elimination_runs, elimination_index + 1);
90 }
91
92 //std::cout << "Number of elimination runs: " << max_elimination_runs << std::endl;
93
94 //
95 // Step 2: Build row-major elimination matrix for each elimination step
96 //
97
98 //std::cout << "Elimination order: " << std::endl;
99 //for (vcl_size_t i=0; i<row_elimination.size(); ++i)
100 // std::cout << row_elimination[i] << ", ";
101 //std::cout << std::endl;
102
103 //vcl_size_t summed_rows = 0;
104 for (vcl_size_t elimination_run = 1; elimination_run <= max_elimination_runs; ++elimination_run)
105 {
106 std::map<vcl_size_t, vcl_size_t> const & current_elimination_info = row_entries_per_elimination_step[elimination_run];
107
108 // count cols and entries handled in this elimination step
109 vcl_size_t num_tainted_cols = current_elimination_info.size();
110 vcl_size_t num_entries = 0;
111
112 for (std::map<vcl_size_t, vcl_size_t>::const_iterator it = current_elimination_info.begin();
113 it != current_elimination_info.end();
114 ++it)
115 num_entries += it->second;
116
117 //std::cout << "num_entries: " << num_entries << std::endl;
118 //std::cout << "num_tainted_cols: " << num_tainted_cols << std::endl;
119
120 if (num_tainted_cols > 0)
121 {
122 row_index_arrays.push_back(viennacl::backend::mem_handle());
123 viennacl::backend::switch_memory_context<unsigned int>(row_index_arrays.back(), viennacl::traits::context(LU));
124 viennacl::backend::typesafe_host_array<unsigned int> elim_row_index_array(row_index_arrays.back(), num_tainted_cols);
125
126 row_buffers.push_back(viennacl::backend::mem_handle());
127 viennacl::backend::switch_memory_context<unsigned int>(row_buffers.back(), viennacl::traits::context(LU));
128 viennacl::backend::typesafe_host_array<unsigned int> elim_row_buffer(row_buffers.back(), num_tainted_cols + 1);
129
130 col_buffers.push_back(viennacl::backend::mem_handle());
131 viennacl::backend::switch_memory_context<unsigned int>(col_buffers.back(), viennacl::traits::context(LU));
132 viennacl::backend::typesafe_host_array<unsigned int> elim_col_buffer(col_buffers.back(), num_entries);
133
134 element_buffers.push_back(viennacl::backend::mem_handle());
135 viennacl::backend::switch_memory_context<NumericT>(element_buffers.back(), viennacl::traits::context(LU));
136 std::vector<NumericT> elim_elements_buffer(num_entries);
137
138 row_elimination_num_list.push_back(num_tainted_cols);
139
140 vcl_size_t k=0;
141 vcl_size_t nnz_index = 0;
142 elim_row_buffer.set(0, 0);
143
144 for (std::map<vcl_size_t, vcl_size_t>::const_iterator it = current_elimination_info.begin();
145 it != current_elimination_info.end();
146 ++it)
147 {
148 //vcl_size_t col = setup_U ? (elimination_matrix.size() - it->first) - 1 : col2;
149 vcl_size_t row = it->first;
150 elim_row_index_array.set(k, row);
151
152 vcl_size_t row_begin = row_buffer[row];
153 vcl_size_t row_end = row_buffer[row+1];
154 for (vcl_size_t i = row_begin; i < row_end; ++i)
155 {
156 unsigned int col = col_buffer[i];
157 if ( (!setup_U && col < row) || (setup_U && col > row) ) //entry of L/U
158 {
159 if (row_elimination[col] == elimination_run) // this entry is substituted in this run
160 {
161 elim_col_buffer.set(nnz_index, col);
162 elim_elements_buffer[nnz_index] = setup_U ? elements[i] / diagonal_buf[it->first] : elements[i];
163 ++nnz_index;
164 }
165 }
166 }
167
168 elim_row_buffer.set(++k, nnz_index);
169 }
170
171 //
172 // Wrap in memory_handles:
173 //
174 viennacl::backend::memory_create(row_index_arrays.back(), elim_row_index_array.raw_size(), viennacl::traits::context(row_index_arrays.back()), elim_row_index_array.get());
175 viennacl::backend::memory_create(row_buffers.back(), elim_row_buffer.raw_size(), viennacl::traits::context(row_buffers.back()), elim_row_buffer.get());
176 viennacl::backend::memory_create(col_buffers.back(), elim_col_buffer.raw_size(), viennacl::traits::context(col_buffers.back()), elim_col_buffer.get());
177 viennacl::backend::memory_create(element_buffers.back(), sizeof(NumericT) * elim_elements_buffer.size(), viennacl::traits::context(element_buffers.back()), &(elim_elements_buffer[0]));
178 }
179
180 // Print some info:
181 //std::cout << "Eliminated columns in run " << elimination_run << ": " << num_tainted_cols << " (tainted columns: " << num_tainted_cols << ")" << std::endl;
182 //summed_rows += eliminated_rows_in_run;
183 //if (eliminated_rows_in_run == 0)
184 // break;
185 }
186 //std::cout << "Eliminated rows: " << summed_rows << " out of " << row_elimination.size() << std::endl;
187 }
188
189
190 template<typename NumericT, unsigned int AlignmentV>
191 void level_scheduling_setup_L(viennacl::compressed_matrix<NumericT, AlignmentV> const & LU,
192 viennacl::vector<NumericT> const & diagonal_LU,
193 std::list<viennacl::backend::mem_handle> & row_index_arrays,
194 std::list<viennacl::backend::mem_handle> & row_buffers,
195 std::list<viennacl::backend::mem_handle> & col_buffers,
196 std::list<viennacl::backend::mem_handle> & element_buffers,
197 std::list<vcl_size_t> & row_elimination_num_list)
198 {
199 level_scheduling_setup_impl(LU, diagonal_LU, row_index_arrays, row_buffers, col_buffers, element_buffers, row_elimination_num_list, false);
200 }
201
202
203 //
204 // Multifrontal setup of U:
205 //
206
207 template<typename NumericT, unsigned int AlignmentV>
208 void level_scheduling_setup_U(viennacl::compressed_matrix<NumericT, AlignmentV> const & LU,
209 viennacl::vector<NumericT> const & diagonal_LU,
210 std::list<viennacl::backend::mem_handle> & row_index_arrays,
211 std::list<viennacl::backend::mem_handle> & row_buffers,
212 std::list<viennacl::backend::mem_handle> & col_buffers,
213 std::list<viennacl::backend::mem_handle> & element_buffers,
214 std::list<vcl_size_t> & row_elimination_num_list)
215 {
216 level_scheduling_setup_impl(LU, diagonal_LU, row_index_arrays, row_buffers, col_buffers, element_buffers, row_elimination_num_list, true);
217 }
218
219
220 //
221 // Multifrontal substitution (both L and U). Will partly be moved to single_threaded/opencl/cuda implementations
222 //
223 template<typename NumericT>
224 void level_scheduling_substitute(viennacl::vector<NumericT> & vec,
225 std::list<viennacl::backend::mem_handle> const & row_index_arrays,
226 std::list<viennacl::backend::mem_handle> const & row_buffers,
227 std::list<viennacl::backend::mem_handle> const & col_buffers,
228 std::list<viennacl::backend::mem_handle> const & element_buffers,
229 std::list<vcl_size_t> const & row_elimination_num_list)
230 {
231 typedef typename std::list< viennacl::backend::mem_handle >::const_iterator ListIterator;
232 ListIterator row_index_array_it = row_index_arrays.begin();
233 ListIterator row_buffers_it = row_buffers.begin();
234 ListIterator col_buffers_it = col_buffers.begin();
235 ListIterator element_buffers_it = element_buffers.begin();
236 typename std::list< vcl_size_t>::const_iterator row_elimination_num_it = row_elimination_num_list.begin();
237 for (vcl_size_t i=0; i<row_index_arrays.size(); ++i)
238 {
239 viennacl::linalg::detail::level_scheduling_substitute(vec, *row_index_array_it, *row_buffers_it, *col_buffers_it, *element_buffers_it, *row_elimination_num_it);
240
241 ++row_index_array_it;
242 ++row_buffers_it;
243 ++col_buffers_it;
244 ++element_buffers_it;
245 ++row_elimination_num_it;
246 }
247 }
248
249
250
251
252
253 } // namespace detail
254 } // namespace linalg
255 } // namespace viennacl
256
257
258
259
260 #endif
261
262
263
viennacl::backend::typesafe_host_array
Helper class implementing an array on the host. Default case: No conversion necessary.
Definition: util.hpp:92
viennacl::compressed_matrix::size1
const vcl_size_t & size1() const
Returns the number of rows.
Definition: compressed_matrix.hpp:927
tools.hpp
Various little tools used here and there in ViennaCL.
forwards.h
This file provides the forward declarations for the main types used within ViennaCL.
viennacl::linalg::detail::level_scheduling_setup_U
void level_scheduling_setup_U(viennacl::compressed_matrix< NumericT, AlignmentV > const &LU, viennacl::vector< NumericT > const &diagonal_LU, std::list< viennacl::backend::mem_handle > &row_index_arrays, std::list< viennacl::backend::mem_handle > &row_buffers, std::list< viennacl::backend::mem_handle > &col_buffers, std::list< viennacl::backend::mem_handle > &element_buffers, std::list< vcl_size_t > &row_elimination_num_list)
Definition: common.hpp:208
viennacl::linalg::detail::level_scheduling_substitute
void level_scheduling_substitute(viennacl::vector< NumericT > &vec, std::list< viennacl::backend::mem_handle > const &row_index_arrays, std::list< viennacl::backend::mem_handle > const &row_buffers, std::list< viennacl::backend::mem_handle > const &col_buffers, std::list< viennacl::backend::mem_handle > const &element_buffers, std::list< vcl_size_t > const &row_elimination_num_list)
Definition: common.hpp:224
viennacl::compressed_matrix::handle
const handle_type & handle() const
Returns the OpenCL handle to the matrix entry array.
Definition: compressed_matrix.hpp:942
viennacl::compressed_matrix::handle1
const handle_type & handle1() const
Returns the OpenCL handle to the row index array.
Definition: compressed_matrix.hpp:936
NumericT
float NumericT
Definition: bisect.cpp:40
viennacl::linalg::detail::level_scheduling_setup_impl
void level_scheduling_setup_impl(viennacl::compressed_matrix< NumericT, AlignmentV > const &LU, viennacl::vector< NumericT > const &diagonal_LU, std::list< viennacl::backend::mem_handle > &row_index_arrays, std::list< viennacl::backend::mem_handle > &row_buffers, std::list< viennacl::backend::mem_handle > &col_buffers, std::list< viennacl::backend::mem_handle > &element_buffers, std::list< vcl_size_t > &row_elimination_num_list, bool setup_U)
Definition: common.hpp:51
viennacl::compressed_matrix::handle2
const handle_type & handle2() const
Returns the OpenCL handle to the column index array.
Definition: compressed_matrix.hpp:938
viennacl::vcl_size_t
std::size_t vcl_size_t
Definition: forwards.h:75
common.hpp
Common routines for single-threaded or OpenMP-enabled execution on CPU.
viennacl::vector< NumericT >
viennacl::row
vector_expression< const matrix_base< NumericT, F >, const unsigned int, op_row > row(const matrix_base< NumericT, F > &A, unsigned int i)
Definition: matrix.hpp:910
viennacl::traits::context
viennacl::context context(T const &t)
Returns an ID for the currently active memory domain of an object.
Definition: context.hpp:40
viennacl::backend::mem_handle
Main abstraction class for multiple memory domains. Represents a buffer in either main RAM...
Definition: mem_handle.hpp:89
viennacl::linalg::detail::level_scheduling_setup_L
void level_scheduling_setup_L(viennacl::compressed_matrix< NumericT, AlignmentV > const &LU, viennacl::vector< NumericT > const &diagonal_LU, std::list< viennacl::backend::mem_handle > &row_index_arrays, std::list< viennacl::backend::mem_handle > &row_buffers, std::list< viennacl::backend::mem_handle > &col_buffers, std::list< viennacl::backend::mem_handle > &element_buffers, std::list< vcl_size_t > &row_elimination_num_list)
Definition: common.hpp:191
viennacl::compressed_matrix
A sparse square matrix in compressed sparse rows format.
Definition: compressed_matrix.hpp:559
viennacl::backend::memory_create
void memory_create(mem_handle &handle, vcl_size_t size_in_bytes, viennacl::context const &ctx, const void *host_ptr=NULL)
Creates an array of the specified size. If the second argument is provided, the buffer is initialized...
Definition: memory.hpp:87
viennacl::vector_base::handle
const handle_type & handle() const
Returns the memory handle.
Definition: vector_def.hpp:128
misc_operations.hpp
Implementations of miscellaneous operations.
memory.hpp
Main interface routines for memory management.