• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

STEllAR-GROUP / hpx / #882

31 Aug 2023 07:44PM UTC coverage: 41.798% (-44.7%) from 86.546%
#882

push

19442 of 46514 relevant lines covered (41.8%)

126375.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/examples/transpose/transpose_smp.cpp
1
//  Copyright (c) 2014 Thomas Heller
2
//
3
//  SPDX-License-Identifier: BSL-1.0
4
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
5
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6

7
#include <hpx/algorithm.hpp>
8
#include <hpx/init.hpp>
9
#include <hpx/modules/iterator_support.hpp>
10
#include <hpx/numeric.hpp>
11

12
#include <algorithm>
13
#include <cstdint>
14
#include <exception>
15
#include <iostream>
16
#include <vector>
17

18
#define COL_SHIFT 1000.00    // Constant to shift column index
19
#define ROW_SHIFT 0.001      // Constant to shift row index
20

21
bool verbose = false;
22

23
double test_results(std::uint64_t order, std::vector<double> const& trans);
24

25
///////////////////////////////////////////////////////////////////////////////
26
int hpx_main(hpx::program_options::variables_map& vm)
×
27
{
28
    std::uint64_t order = vm["matrix_size"].as<std::uint64_t>();
×
29
    std::uint64_t iterations = vm["iterations"].as<std::uint64_t>();
×
30
    std::uint64_t tile_size = order;
×
31

32
    if (vm.count("tile_size"))
×
33
        tile_size = vm["tile_size"].as<std::uint64_t>();
×
34

35
    verbose = vm.count("verbose") ? true : false;
×
36

37
    std::uint64_t bytes =
×
38
        static_cast<std::uint64_t>(2 * sizeof(double) * order * order);
×
39

40
    std::vector<double> A(order * order);
×
41
    std::vector<double> B(order * order);
×
42

43
    std::cout << "Serial Matrix transpose: B = A^T\n"
44
              << "Matrix order          = " << order << "\n";
×
45
    if (tile_size < order)
×
46
        std::cout << "Tile size             = " << tile_size << "\n";
×
47
    else
48
        std::cout << "Untiled\n";
×
49
    std::cout << "Number of iterations  = " << iterations << "\n";
×
50

51
    using hpx::execution::par;
52
    using hpx::experimental::for_loop_strided;
53
    using hpx::ranges::for_each;
54

55
    std::uint64_t const start = 0;
56

57
    // Fill the original matrix, set transpose to known garbage value.
58
    auto range = hpx::util::counting_shape(order);
×
59
    // parallel for
60
    for_each(par, range, [&](std::uint64_t i) {
×
61
        for (std::uint64_t j = 0; j < order; ++j)
×
62
        {
63
            A[i * order + j] = COL_SHIFT * static_cast<double>(j) +
×
64
                ROW_SHIFT * static_cast<double>(i);
×
65
            B[i * order + j] = -1.0;
66
        }
×
67
    });
68

69
    double errsq = 0.0;
70
    double avgtime = 0.0;
×
71
    double maxtime = 0.0;
×
72
    double mintime =
73
        366.0 * 24.0 * 3600.0;    // set the minimum time to a large value;
74
                                  // one leap year should be enough
×
75
    for (std::uint64_t iter = 0; iter < iterations; ++iter)
76
    {
77
        hpx::chrono::high_resolution_timer t;
×
78
        if (tile_size < order)
79
        {
80
            // parallel for
81
            for_loop_strided(
×
82
                par, start, order + tile_size, tile_size, [&](std::uint64_t i) {
×
83
                    for (std::uint64_t j = 0; j < order; j += tile_size)
84
                    {
×
85
                        std::uint64_t i_max = (std::min) (order, i + tile_size);
×
86
                        std::uint64_t j_max = (std::min) (order, j + tile_size);
87

×
88
                        for (std::uint64_t it = i; it < i_max; ++it)
89
                        {
×
90
                            for (std::uint64_t jt = j; jt < j_max; ++jt)
91
                            {
×
92
                                B[it + order * jt] = A[jt + order * it];
93
                            }
94
                        }
95
                    }
×
96
                });
97
        }
98
        else
99
        {
100
            // parallel for
101
            auto range = hpx::util::counting_shape(order);
×
102
            for_each(par, range, [&](std::uint64_t i) {
×
103
                for (std::uint64_t j = 0; j < order; ++j)
104
                {
×
105
                    B[i + order * j] = A[j + order * i];
106
                }
×
107
            });
108
        }
109

×
110
        double elapsed = t.elapsed();
111

×
112
        if (iter > 0 || iterations == 1)    // Skip the first iteration
113
        {
×
114
            avgtime = avgtime + elapsed;
×
115
            maxtime = (std::max) (maxtime, elapsed);
×
116
            mintime = (std::min) (mintime, elapsed);
117
        }
118

×
119
        errsq += test_results(order, B);
120
    }    // end of iter loop
121

122
    // Analyze and output results
123

124
    double epsilon = 1.e-8;
×
125
    if (errsq < epsilon)
126
    {
×
127
        std::cout << "Solution validates\n";
×
128
        avgtime = avgtime /
×
129
            static_cast<double>(
×
130
                (std::max) (iterations - 1, static_cast<std::uint64_t>(1)));
×
131
        std::cout << "Rate (MB/s): "
132
                  << 1.e-6 * static_cast<double>(bytes) / mintime << ", "
133
                  << "Avg time (s): " << avgtime << ", "
×
134
                  << "Min time (s): " << mintime << ", "
135
                  << "Max time (s): " << maxtime << "\n";
×
136

×
137
        if (verbose)
138
            std::cout << "Squared errors: " << errsq << "\n";
139
    }
140
    else
141
    {
×
142
        std::cout << "ERROR: Aggregate squared error " << errsq
×
143
                  << " exceeds threshold " << epsilon << "\n";
144
        std::terminate();
145
    }
×
146

147
    return hpx::local::finalize();
148
}
×
149

150
int main(int argc, char* argv[])
151
{
152
    using namespace hpx::program_options;
×
153

154
    options_description desc_commandline;
×
155
    // clang-format off
×
156
    desc_commandline.add_options()
157
        ("matrix_size", value<std::uint64_t>()->default_value(1024),
×
158
         "Matrix Size")
159
        ("iterations", value<std::uint64_t>()->default_value(10),
×
160
         "# iterations")
161
        ("tile_size", value<std::uint64_t>(),
162
         "Number of tiles to divide the individual matrix blocks for improved "
×
163
         "cache and TLB performance")
164
        ( "verbose", "Verbose output")
165
    ;
166
    // clang-format on
×
167

×
168
    hpx::local::init_params init_args;
169
    init_args.desc_cmdline = desc_commandline;
×
170

×
171
    return hpx::local::init(hpx_main, argc, argv, init_args);
172
}
×
173

174
double test_results(std::uint64_t order, std::vector<double> const& trans)
175
{
176
    using hpx::transform_reduce;
177
    using hpx::execution::par;
178

179
    std::uint64_t const start = 0;
×
180

181
    auto range = hpx::util::counting_shape(start, order);
182
    // parallel reduce
183
    double errsq = transform_reduce(
×
184
        par, std::begin(range), std::end(range), 0.0,
×
185
        [](double lhs, double rhs) { return lhs + rhs; },
186
        [&](std::uint64_t i) -> double {
×
187
            double errsq = 0.0;
188
            for (std::uint64_t j = 0; j < order; ++j)
189
            {
×
190
                double diff = trans[i * order + j] -
×
191
                    (COL_SHIFT * static_cast<double>(i) +
192
                        ROW_SHIFT * static_cast<double>(j));
×
193
                errsq += diff * diff;
194
            }
195
            return errsq;
×
196
        });
×
197

198
    if (verbose)
×
199
        std::cout << " Squared sum of differences: " << errsq << "\n";
200

201
    return errsq;
202
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc