Ginkgo  Generated from pipelines/224724463 branch based on develop. Ginkgo version 1.3.0 A numerical linear algebra library targeting many-core architectures
The ginkgo-ranges program

The ranges and accessor example..

1. Introduction
2. The commented program

# The commented program

#include <ginkgo/ginkgo.hpp>
#include <iomanip>
#include <iostream>

LU factorization implementation using Ginkgo ranges For simplicity, we only consider square matrices, and no pivoting.

template <typename Accessor>
void factorize(const gko::range<Accessor> &A)

note: const means that the range (i.e. the data handler) is constant, not that the underlying data is constant!

{
using gko::span;
assert(A.length(0) == A.length(1));
for (gko::size_type i = 0; i < A.length(0) - 1; ++i) {
const auto trail = span{i + 1, A.length(0)};

note: neither of the lines below need additional memory to store intermediate arrays, all computation is done at the point of assignment

A(trail, i) = A(trail, i) / A(i, i);

caveat: operator * is element-wise multiplication, mmul is matrix multiplication

A(trail, trail) = A(trail, trail) - mmul(A(trail, i), A(i, trail));
}
}

a utility function for printing the factorization on screen

template <typename Accessor>
void print_lu(const gko::range<Accessor> &A)
{
std::cout << std::setprecision(2) << std::fixed;
std::cout << "L = [";
for (int i = 0; i < A.length(0); ++i) {
std::cout << "\n ";
for (int j = 0; j < A.length(1); ++j) {
std::cout << (i > j ? A(i, j) : (i == j) * 1.) << " ";
}
}
std::cout << "\n]\n\nU = [";
for (int i = 0; i < A.length(0); ++i) {
std::cout << "\n ";
for (int j = 0; j < A.length(1); ++j) {
std::cout << (i <= j ? A(i, j) : 0.) << " ";
}
}
std::cout << "\n]" << std::endl;
}
int main(int argc, char *argv[])
{
using ValueType = double;
using IndexType = int;

Print version information

std::cout << gko::version_info::get() << std::endl;

Create some test data, add some padding just to demonstrate how to use it with ranges. clang-format off

ValueType data[] = {
2., 4., 5., -1.0,
4., 11., 12., -1.0,
6., 24., 24., -1.0
};

clang-format on

Create a 3-by-3 range, with a 2D row-major accessor using data as the underlying storage. Set the stride (a.k.a. "LDA") to 4.

use the LU factorization routine defined above to factorize the matrix

factorize(A);

print the factorization on screen

print_lu(A);
}

# Results

This is the expected output:

L = [
1.00 0.00 0.00
2.00 1.00 0.00
3.00 4.00 1.00
]
U = [
2.00 4.00 5.00
0.00 3.00 2.00
0.00 0.00 1.00
]

# The plain program

Copyright (c) 2017-2020, the Ginkgo authors
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <ginkgo/ginkgo.hpp>
#include <iomanip>
#include <iostream>
template <typename Accessor>
void factorize(const gko::range<Accessor> &A)
{
using gko::span;
assert(A.length(0) == A.length(1));
for (gko::size_type i = 0; i < A.length(0) - 1; ++i) {
const auto trail = span{i + 1, A.length(0)};
A(trail, i) = A(trail, i) / A(i, i);
A(trail, trail) = A(trail, trail) - mmul(A(trail, i), A(i, trail));
}
}
template <typename Accessor>
void print_lu(const gko::range<Accessor> &A)
{
std::cout << std::setprecision(2) << std::fixed;
std::cout << "L = [";
for (int i = 0; i < A.length(0); ++i) {
std::cout << "\n ";
for (int j = 0; j < A.length(1); ++j) {
std::cout << (i > j ? A(i, j) : (i == j) * 1.) << " ";
}
}
std::cout << "\n]\n\nU = [";
for (int i = 0; i < A.length(0); ++i) {
std::cout << "\n ";
for (int j = 0; j < A.length(1); ++j) {
std::cout << (i <= j ? A(i, j) : 0.) << " ";
}
}
std::cout << "\n]" << std::endl;
}
int main(int argc, char *argv[])
{
using ValueType = double;
using IndexType = int;
std::cout << gko::version_info::get() << std::endl;
ValueType data[] = {
2., 4., 5., -1.0,
4., 11., 12., -1.0,
6., 24., 24., -1.0
};
auto A =
factorize(A);
print_lu(A);
}
gko::size_type
std::size_t size_type
Integral type used for allocation quantities.
Definition: types.hpp:100
gko::range
A range is a multidimensional view of the memory.
Definition: range.hpp:298
gko::version_info::get
static const version_info & get()
Returns an instance of version_info.
Definition: version.hpp:168
gko::span
A span is a lightweight structure used to create sub-ranges from other ranges.
Definition: range.hpp:75
gko::range::length
constexpr size_type length(size_type dimension) const
Returns the length of the specified dimension of the range.
Definition: range.hpp:396