File: smoothed_aggregation.cu

package info (click to toggle)
python-escript 5.0-3
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 87,772 kB
  • ctags: 49,550
  • sloc: python: 585,488; cpp: 133,173; ansic: 18,675; xml: 3,283; sh: 690; makefile: 215
file content (142 lines) | stat: -rw-r--r-- 4,961 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <cusp/relaxation/jacobi.h>
#include <cusp/relaxation/polynomial.h>
#include <cusp/precond/aggregation/smoothed_aggregation.h>
#include <cusp/krylov/cg.h>
#include <cusp/gallery/poisson.h>
#include <cusp/csr_matrix.h>

#include <iostream>

#include "../timer.h"

template<typename IndexType, typename ValueType, typename MemorySpace>
class unsmoothed_aggregation_options
    : public cusp::precond::aggregation::smoothed_aggregation_options<IndexType,ValueType,MemorySpace>
{
    typedef cusp::precond::aggregation::smoothed_aggregation_options<IndexType,ValueType,MemorySpace> Parent;
    typedef typename Parent::MatrixType MatrixType;

public:

    unsmoothed_aggregation_options() : Parent() {}

    virtual void smooth_prolongator(const MatrixType& A, const MatrixType& T, MatrixType& P, ValueType& rho_DinvA) const
    {
        P = T;
    }
};

template <typename Monitor>
void report_status(Monitor& monitor)
{
    if (monitor.converged())
    {
        std::cout << "Solver converged to " << monitor.tolerance() << " tolerance";
        std::cout << " after " << monitor.iteration_count() << " iterations";
        std::cout << " (" << monitor.residual_norm() << " final residual)" << std::endl;
    }
    else
    {
        std::cout << "Solver reached iteration limit " << monitor.iteration_limit() << " before converging";
        std::cout << " to " << monitor.tolerance() << " tolerance ";
        std::cout << " (" << monitor.residual_norm() << " final residual)" << std::endl;
    }
}

template<typename MatrixType, typename Prec>
void run_amg(const MatrixType& A, Prec& M)
{
    typedef typename MatrixType::index_type IndexType;
    typedef typename MatrixType::value_type ValueType;
    typedef typename MatrixType::memory_space MemorySpace;

    // allocate storage for solution (x) and right hand side (b)
    cusp::array1d<ValueType, MemorySpace> x(A.num_rows, 0);
    cusp::array1d<ValueType, MemorySpace> b(A.num_rows, 1);

    // set stopping criteria (iteration_limit = 1000, relative_tolerance = 1e-10)
    cusp::default_monitor<ValueType> monitor(b, 1000, 1e-10);

    // solve
    timer t1;
    cusp::krylov::cg(A, x, b, monitor, M);
    std::cout << "solved system  in " << t1.milliseconds_elapsed() << " ms " << std::endl;

    // report status
    report_status(monitor);
}

int main(int argc, char ** argv)
{
    typedef int                 IndexType;
    typedef float               ValueType;
    typedef cusp::device_memory MemorySpace;

    // create an empty sparse matrix structure
    cusp::hyb_matrix<IndexType, ValueType, MemorySpace> A;

    IndexType N = 256;

    // create 2D Poisson problem
    cusp::gallery::poisson5pt(A, N, N);

    // solve without preconditioning
    {
        std::cout << "\nSolving with no preconditioner" << std::endl;

        // allocate storage for solution (x) and right hand side (b)
        cusp::array1d<ValueType, MemorySpace> x(A.num_rows, 0);
        cusp::array1d<ValueType, MemorySpace> b(A.num_rows, 1);

        // set stopping criteria (iteration_limit = 10000, relative_tolerance = 1e-10)
        cusp::default_monitor<ValueType> monitor(b, 10000, 1e-10);

        // solve
        timer t0;
        cusp::krylov::cg(A, x, b, monitor);
        std::cout << "solved system  in " << t0.milliseconds_elapsed() << " ms " << std::endl;

        // report status
        report_status(monitor);
    }

    // solve with smoothed aggregation algebraic multigrid preconditioner
    {
        std::cout << "\nSolving with smoothed aggregation preconditioner and jacobi smoother" << std::endl;

        // setup preconditioner
        timer t0;
        cusp::precond::aggregation::smoothed_aggregation<IndexType, ValueType, MemorySpace> M(A);
        std::cout << "constructed hierarchy in " << t0.milliseconds_elapsed() << " ms " << std::endl;

        run_amg(A,M);
    }

    // solve with smoothed aggregation algebraic multigrid preconditioner and polynomial smoother
    {
        typedef cusp::relaxation::polynomial<ValueType,MemorySpace> Smoother;
        std::cout << "\nSolving with smoothed aggregation preconditioner and polynomial smoother" << std::endl;

        timer t0;
        cusp::precond::aggregation::smoothed_aggregation<IndexType, ValueType, MemorySpace, Smoother> M(A);
        std::cout << "constructed hierarchy in " << t0.milliseconds_elapsed() << " ms " << std::endl;

        run_amg(A,M);
    }

    // solve with unsmoothed aggregation algebraic multigrid preconditioner and polynomial smoother
    {
        std::cout << "\nSolving with unsmoothed aggregation preconditioner" << std::endl;

        unsmoothed_aggregation_options<IndexType,ValueType,MemorySpace> opts;

        timer t0;
        cusp::precond::aggregation::smoothed_aggregation<IndexType, ValueType, MemorySpace> M(A,opts);
        std::cout << "constructed hierarchy in " << t0.milliseconds_elapsed() << " ms " << std::endl;

        run_amg(A,M);
    }

    return 0;
}