diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 66227de2..1f52983f 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -33,7 +33,7 @@ endif() message(STATUS "Building benchmark") set(benchmark_src - bench_epu8.cpp bench_perm16.cpp bench_bmat8.cpp sort.cpp inverse.cpp) + bench_epu8.cpp bench_perm16.cpp bench_bmat8.cpp) foreach(f ${benchmark_src}) get_filename_component(benchName ${f} NAME_WE) diff --git a/benchmark/bench_epu8.cpp b/benchmark/bench_epu8.cpp index a577ac2b..91ae319c 100644 --- a/benchmark/bench_epu8.cpp +++ b/benchmark/bench_epu8.cpp @@ -152,8 +152,6 @@ TEST_CASE_METHOD(Fix_epu8, "Permuting", "[Epu8][001]") { BENCHMARK_FREE_FN_PAIR(HPCombi::permuted, pairs); } -/* -int Bench_hsum() { TEST_CASE_METHOD(Fix_epu8, "hsum", "[Epu8][000]") { BENCHMARK_FREE_FN("| no lambda", horiz_sum_ref, Fix_epu8::perms); BENCHMARK_FREE_FN("| no lambda", horiz_sum_gen, Fix_epu8::perms); @@ -176,90 +174,59 @@ TEST_CASE_METHOD(Fix_epu8, "partial sums", "[Epu8][000]") { BENCHMARK_LAMBDA("| lambda", partial_sums_gen, Fix_epu8::perms); BENCHMARK_LAMBDA("| lambda", partial_sums_round, Fix_epu8::perms); } -/* -// -// -################################################################################## -int Bench_hmax() { +TEST_CASE_METHOD(Fix_epu8, "horiz max", "[Epu8][000]") { BENCHMARK_FREE_FN("| no lambda", horiz_max_ref, Fix_epu8::perms); BENCHMARK_FREE_FN("| no lambda", horiz_max_ref, Fix_epu8::perms); BENCHMARK_FREE_FN("| no lambda", horiz_max_ref, Fix_epu8::perms); BENCHMARK_FREE_FN("| no lambda", horiz_max_ref, Fix_epu8::perms); - // BENCHMARK_FREE_FN("| no lambda", horiz_max_gen, -Fix_epu8::perms); BENCHMARK_FREE_FN("| no lambda", horiz_max4, -Fix_epu8::perms); BENCHMARK_FREE_FN("| no lambda", horiz_max3, -Fix_epu8::perms); + // BENCHMARK_FREE_FN("| no lambda", horiz_max_gen, Fix_epu8::perms); + BENCHMARK_FREE_FN("| no lambda", horiz_max4, Fix_epu8::perms); + BENCHMARK_FREE_FN("| no lambda", horiz_max3, Fix_epu8::perms); BENCHMARK_LAMBDA("| lambda", horiz_max_ref, Fix_epu8::perms); // BENCHMARK_LAMBDA("| lambda", horiz_max_gen, Fix_epu8::perms); BENCHMARK_LAMBDA("| lambda", horiz_max4, Fix_epu8::perms); BENCHMARK_LAMBDA("| lambda", horiz_max3, Fix_epu8::perms); - return 0; } -// -################################################################################## -int Bench_pmax() { + +TEST_CASE_METHOD(Fix_epu8, "partial max", "[Epu8][000]") { BENCHMARK_FREE_FN("| no lambda", partial_max_ref, Fix_epu8::perms); BENCHMARK_FREE_FN("| no lambda", partial_max_ref, Fix_epu8::perms); BENCHMARK_FREE_FN("| no lambda", partial_max_ref, Fix_epu8::perms); BENCHMARK_FREE_FN("| no lambda", partial_max_ref, Fix_epu8::perms); - // BENCHMARK_FREE_FN("| no lambda", partial_max_gen, -Fix_epu8::perms); BENCHMARK_FREE_FN("| no lambda", partial_max_round, -Fix_epu8::perms); + // BENCHMARK_FREE_FN("| no lambda", partial_max_gen, Fix_epu8::perms); + BENCHMARK_FREE_FN("| no lambda", partial_max_round, Fix_epu8::perms); BENCHMARK_LAMBDA("| lambda", partial_max_ref, Fix_epu8::perms); - // BENCHMARK_LAMBDA("| lambda", partial_max_gen, -Fix_epu8::perms); BENCHMARK_LAMBDA("| lambda", partial_max_round, -Fix_epu8::perms); return 0; + // BENCHMARK_LAMBDA("| lambda", partial_max_gen, Fix_epu8::perms); + BENCHMARK_LAMBDA("| lambda", partial_max_round, Fix_epu8::perms); } -// -################################################################################## -int Bench_hmin() { - BENCHMARK_FREE_FN("| no lambda", horiz_min_ref, Fix_epu8::perms); - BENCHMARK_FREE_FN("| no lambda", horiz_min_ref, Fix_epu8::perms); +TEST_CASE_METHOD(Fix_epu8, "horiz min", "[Epu8][000]") { BENCHMARK_FREE_FN("| no lambda", horiz_min_ref, Fix_epu8::perms); - - BENCHMARK_FREE_FN("| no lambda", horiz_min_ref, Fix_epu8::perms); - // BENCHMARK_FREE_FN("| no lambda", horiz_min_gen, -Fix_epu8::perms); BENCHMARK_FREE_FN("| no lambda", horiz_min4, -Fix_epu8::perms); BENCHMARK_FREE_FN("| no lambda", horiz_min3, -Fix_epu8::perms); + // BENCHMARK_FREE_FN("| no lambda", horiz_min_gen, Fix_epu8::perms); + BENCHMARK_FREE_FN("| no lambda", horiz_min4, Fix_epu8::perms); + BENCHMARK_FREE_FN("| no lambda", horiz_min3, Fix_epu8::perms); BENCHMARK_LAMBDA("| lambda", horiz_min_ref, Fix_epu8::perms); // BENCHMARK_LAMBDA("| lambda", horiz_min_gen, Fix_epu8::perms); BENCHMARK_LAMBDA("| lambda", horiz_min4, Fix_epu8::perms); BENCHMARK_LAMBDA("| lambda", horiz_min3, Fix_epu8::perms); - return 0; } -// -################################################################################## -int Bench_pmin() { - BENCHMARK_FREE_FN("| no lambda", partial_min_ref, Fix_epu8::perms); - BENCHMARK_FREE_FN("| no lambda", partial_min_ref, Fix_epu8::perms); - BENCHMARK_FREE_FN("| no lambda", partial_min_ref, Fix_epu8::perms); +TEST_CASE_METHOD(Fix_epu8, "partial min", "[Epu8][000]") { BENCHMARK_FREE_FN("| no lambda", partial_min_ref, Fix_epu8::perms); - // BENCHMARK_FREE_FN("| no lambda", partial_min_gen, -Fix_epu8::perms); BENCHMARK_FREE_FN("| no lambda", partial_min_round, -Fix_epu8::perms); - + // BENCHMARK_FREE_FN("| no lambda", partial_min_gen, Fix_epu8::perms); + BENCHMARK_FREE_FN("| no lambda", partial_min_round, Fix_epu8::perms); + // BENCHMARK_LAMBDA("| lambda", partial_min_gen, Fix_epu8::perms); BENCHMARK_LAMBDA("| lambda", partial_min_ref, Fix_epu8::perms); - // BENCHMARK_LAMBDA("| lambda", partial_min_gen, -Fix_epu8::perms); BENCHMARK_LAMBDA("| lambda", partial_min_round, -Fix_epu8::perms); return 0; + BENCHMARK_LAMBDA("| lambda", partial_min_round, Fix_epu8::perms); } -// -################################################################################## -int Bench_eval() { - BENCHMARK_FREE_FN("| no lambda", eval16_ref, Fix_epu8::perms); - BENCHMARK_FREE_FN("| no lambda", eval16_ref, Fix_epu8::perms); - BENCHMARK_FREE_FN("| no lambda", eval16_ref, Fix_epu8::perms); - +TEST_CASE_METHOD(Fix_epu8, "eval16", "[Epu8][000]") { BENCHMARK_FREE_FN("| no lambda", eval16_ref, Fix_epu8::perms); BENCHMARK_FREE_FN("| no lambda", eval16_gen, Fix_epu8::perms); BENCHMARK_FREE_FN("| no lambda", eval16_popcount, Fix_epu8::perms); @@ -271,24 +238,21 @@ int Bench_eval() { BENCHMARK_LAMBDA("| lambda", eval16_popcount, Fix_epu8::perms); BENCHMARK_LAMBDA("| lambda", eval16_arr, Fix_epu8::perms); BENCHMARK_LAMBDA("| lambda", eval16_cycle, Fix_epu8::perms); - return 0; } -// -################################################################################## -int Bench_first_diff() { - MYBENCH2("firstDiff_ref_lmbd", first_diff_ref, Fix_epu8::perms); - MYBENCH2("firstDiff_cmpstr_lmbd", first_diff_cmpstr, -Fix_epu8::perms); MYBENCH2("firstDiff_mask_lmbd", first_diff_mask, -Fix_epu8::perms); return 0; +TEST_CASE_METHOD(Fix_epu8, "first diff", "[Epu8][000]") { + BENCHMARK_LAMBDA2("| lambda", first_diff_ref, Fix_epu8::pairs); +#ifdef SIMDE_X86_SSE4_2_NATIVE + BENCHMARK_LAMBDA2("| lambda", first_diff_cmpstr, Fix_epu8::pairs); +#endif + BENCHMARK_LAMBDA2("| lambda", first_diff_mask, Fix_epu8::pairs); } -// -################################################################################## -int Bench_last_diff() { - MYBENCH2("lastDiff_ref_lmbd", last_diff_ref, Fix_epu8::perms); - MYBENCH2("lastDiff_cmpstr_lmbd", last_diff_cmpstr, -Fix_epu8::perms); MYBENCH2("lastDiff_mask_lmbd", last_diff_mask, -Fix_epu8::perms); return 0; -} */ +TEST_CASE_METHOD(Fix_epu8, "last diff", "[Epu8][000]") { + BENCHMARK_LAMBDA2("| lambda", last_diff_ref, Fix_epu8::pairs); +#ifdef SIMDE_X86_SSE4_2_NATIVE + BENCHMARK_LAMBDA2("| lambda", last_diff_cmpstr, Fix_epu8::pairs); +#endif + BENCHMARK_LAMBDA2("| lambda", last_diff_mask, Fix_epu8::pairs); +} } // namespace HPCombi diff --git a/benchmark/bench_fixture.hpp b/benchmark/bench_fixture.hpp index 8d2db5d0..79f642f5 100644 --- a/benchmark/bench_fixture.hpp +++ b/benchmark/bench_fixture.hpp @@ -60,19 +60,16 @@ std::vector rand_transf(int sz) { std::vector> make_pair_sample(size_t sz) { std::vector> res{}; for (size_t i = 0; i < sz; i++) { - res.push_back(std::make_pair(HPCombi::random_epu8(15), - HPCombi::random_epu8(15))); + res.emplace_back(HPCombi::random_epu8(15), HPCombi::random_epu8(15)); } return res; } class Fix_epu8 { public: - Fix_epu8() : vects(rand_epu8(size)), - transf(rand_transf(size)), - perms(rand_perms(size)), - pairs(make_pair_sample(size)) - {} + Fix_epu8() + : vects(rand_epu8(size)), transf(rand_transf(size)), + perms(rand_perms(size)), pairs(make_pair_sample(size)) {} ~Fix_epu8() {} const std::vector vects; const std::vector transf; diff --git a/benchmark/bench_main.hpp b/benchmark/bench_main.hpp index 3d8cb90b..4cde8e0c 100644 --- a/benchmark/bench_main.hpp +++ b/benchmark/bench_main.hpp @@ -38,6 +38,25 @@ return true; \ }; +#define BENCHMARK_LAMBDA2(msg, free_fn, sample) \ + BENCHMARK(#free_fn " " msg) { \ + auto lambda__xxx = [](auto const &x, auto const &y) { \ + return free_fn(x, y); \ + }; \ + for (auto [x, y] : sample) { \ + volatile auto dummy = lambda__xxx(x, y); \ + } \ + return true; \ + }; + +#define BENCHMARK_MEM_FN_PAIR(mem_fn, sample) \ + BENCHMARK(#mem_fn) { \ + for (auto &pair : sample) { \ + volatile auto val = pair.first.mem_fn(pair.second); \ + } \ + return true; \ + }; + #define BENCHMARK_MEM_FN_PAIR_EQ(mem_fn, sample) \ BENCHMARK(#mem_fn) { \ for (auto &pair : sample) { \ @@ -48,10 +67,10 @@ return true; \ }; -#define BENCHMARK_FREE_FN_PAIR(free_fn, sample) \ - BENCHMARK(#free_fn) { \ +#define BENCHMARK_FREE_FN_PAIR(free_fn, sample) \ + BENCHMARK(#free_fn) { \ for (auto &pair : sample) { \ - volatile auto val = free_fn(pair.first, pair.second); \ + volatile auto val = free_fn(pair.first, pair.second); \ } \ return true; \ }; diff --git a/etc/bench_plot.py b/etc/bench_plot.py index f619bf42..6e6b080b 100755 --- a/etc/bench_plot.py +++ b/etc/bench_plot.py @@ -1,12 +1,8 @@ #!/usr/bin/env python3 - -import os -import re -import statistics as stats import sys +from math import isqrt import matplotlib -import numpy as np from bs4 import BeautifulSoup from matplotlib import pyplot as plt @@ -15,7 +11,7 @@ matplotlib.rcParams["mathtext.fontset"] = "stix" matplotlib.rcParams["font.family"] = "STIXGeneral" -color = [ +colors = [ (238 / 255, 20 / 255, 135 / 255), (0 / 255, 221 / 255, 164 / 255), (86 / 255, 151 / 255, 209 / 255), @@ -26,114 +22,101 @@ # Filenames should be: name.something.xml -> name.png -def normalize_xml(xml_fnam): - with open(xml_fnam, "r") as f: - xml = f.read() - xml = re.sub("<", "<", xml) - with open(xml_fnam, "w") as f: - f.write(xml) - - -def xml_stdout_get(xml, name): - try: - return xml.find("StdOut").find(name)["value"] - except (KeyError, TypeError, AttributeError): - return None - - -def time_unit(Y): - time_units = ("microseconds", "milliseconds", "seconds") - index = 0 - - while all(y > 1000 for y in Y) and index < len(time_units): - index += 1 - Y = [y / 1000 for y in Y] - return time_units[index], Y - -def add_plot(xml_fnam, num_bars=4): - global color; - current_bar = 0 - Y = [] - Y_for_comparison = None - labels = [] - - xml = BeautifulSoup(open(xml_fnam, "r"), "xml") - total_cols = 0 - xticks_label = [] - xticks_pos = [] - for x, test_case in enumerate(xml.find_all("TestCase")): - results = test_case.find_all("BenchmarkResults") - Y = ( - np.array([float(x.find("mean")["value"]) for x in results]) / 1 - ) # times in nanoseconds - X = np.arange(total_cols + 1, total_cols + len(Y) + 1, 1) - xticks_label.append(("\n" * (x % 2)) + test_case["name"]) - xticks_pos.append(total_cols + 1 + (len(Y) / 2) - 0.5) - bars = plt.bar( - X, - Y, - 1, - align="center", - color=color[:len(Y)], +def determine_subplot_layout(nr_plots: int) -> tuple[int, int]: + """Determine the number of rows and columns from number of plots.""" + nr_plot_rows = isqrt(nr_plots) + nr_plot_cols = nr_plot_rows + if nr_plot_rows * nr_plot_cols < nr_plots: + nr_plot_cols += 1 + while nr_plot_rows * nr_plot_cols < nr_plots: + nr_plot_rows += 1 + return nr_plot_rows, nr_plot_cols + + +def process_result(result_soup) -> tuple[str, float]: + """Extract data from a single xml result entry. + + Returns + ------- + result_name: str + The test case name + result_time: float + The test case time in nanoseconds + """ + result_name = result_soup["name"] + if "name" not in result_soup.attrs: + raise ValueError( + f"Malformed benchmark file, result record does not contain 'name': {result_soup}" + ) + result_mean_soup = result_soup.find("mean") + if result_mean_soup is None: + raise ValueError( + f"Malformed benchmark file, result record does not contain 'mean': {result_soup}" ) - total_cols += len(Y) + 1 - plt.yscale("log", nonpositive="clip") - plt.ylabel("Time in ns") - plt.xticks(xticks_pos, xticks_label) - # plt.legend(loc="upper right") - - # print(Y) - # width = 1 - - - # plt.axhline( - # stats.mean(Y), - # color=color[current_bar], - # linestyle="--", - # lw=1, - # xmin=0.01, - # xmax=0.99, - # ) - - # current_bar += 1 - # if current_bar == num_bars - 1: - # Ys = zip(*sorted(zip(*Ys))) - # for i, Y in enumerate(Ys): - # X = np.arange(i, num_bars * len(Y), num_bars) - # bars = plt.bar( - # X, - # Y, - # width, - # align="center", - # color=color[i], - # label=labels[i], - # ) - # plt.xticks( - # np.arange(1, num_bars * (len(X) + 1), num_bars * 20), - # np.arange(0, len(X) + num_bars - 1, 20), - # ) - # plt.xlabel("Test case") - # plt.ylabel("Time (relative)") - # plt.legend(loc="upper left") + if "value" not in result_mean_soup.attrs: + raise ValueError( + f"Malformed benchmark file, result 'mean' record does not contain 'value': {result_mean_soup}" + ) + result_time = float(result_mean_soup["value"]) / 1 # time in nanoseconds + return result_name, result_time -def check_filename(xml_fnam): - if len(xml_fnam.split(".")) < 2: + +def make_ax(ax, test_case_soup): + if "name" not in test_case_soup.attrs: raise ValueError( - f"expected filename of form x.xml found {xml_fnam}" + f"Malformed benchmark file, test_case record does not contain 'name': {test_case_soup}" ) + results = test_case_soup.find_all("BenchmarkResults") + result_names, result_times = zip(*map(process_result, reversed(results))) + bars = ax.barh( + result_names, + result_times, + align="center", + color=[colors[i % len(colors)] for i in range(len(result_names))], + ) + test_name = test_case_soup["name"] + ax.set_title(f'Benchmark "{test_name}" runtime') + ax.set_xlabel(f"time, ns") + return ax + + +def make_fig(benchmark_soup, plot_width_inches=7.5, plot_height_inches=5): + test_cases = benchmark_soup.find_all("TestCase") + nr_plots = len(test_cases) + nr_plot_rows, nr_plot_cols = determine_subplot_layout(nr_plots) + fig, axs = plt.subplots( + nr_plot_rows, + nr_plot_cols, + figsize=(plot_width_inches * nr_plot_cols, plot_height_inches * nr_plot_rows), + ) + for test_case_soup, ax in zip(test_cases, axs.flat): + ax = make_ax(ax, test_case_soup) + for ax in axs.flat[nr_plots:]: + fig.delaxes(ax) + fig.tight_layout() + return fig + + +def check_filename(xml_fnam): + if len(xml_fnam.split(".")) < 2: + raise ValueError(f"expected filename of form x.xml found {xml_fnam}") + +if __name__ == "__main__": + args = sys.argv[1:] -from sys import argv + for x in args: + check_filename(x) + # TODO more arg checks -args = sys.argv[1:] + for x in args: + with open(x, "r") as in_file: + xml_text = in_file.read() + soup = BeautifulSoup(xml_text, "xml") + fig = make_fig(soup) -for x in args: - check_filename(x) - # TODO more arg checks -for x in args: - add_plot(x) -xml_fnam = args[0] -png_fnam = "".join(xml_fnam.split(".")[:-1]) + ".png" -print("Writing {} . . .".format(png_fnam)) -plt.savefig(png_fnam, format="png", dpi=300) -sys.exit(0) + xml_fnam = x + png_fnam = "".join(xml_fnam.split(".")[:-1]) + ".png" + print("Writing {} . . .".format(png_fnam)) + fig.savefig(png_fnam, format="png", dpi=300) + sys.exit(0) diff --git a/benchmark/compilerinfo.hpp b/experiments/compilerinfo.hpp similarity index 100% rename from benchmark/compilerinfo.hpp rename to experiments/compilerinfo.hpp diff --git a/benchmark/cpu_x86.h b/experiments/cpu_x86.h similarity index 100% rename from benchmark/cpu_x86.h rename to experiments/cpu_x86.h diff --git a/benchmark/cpu_x86_Linux.ipp b/experiments/cpu_x86_Linux.ipp similarity index 100% rename from benchmark/cpu_x86_Linux.ipp rename to experiments/cpu_x86_Linux.ipp diff --git a/benchmark/cpu_x86_Windows.ipp b/experiments/cpu_x86_Windows.ipp similarity index 100% rename from benchmark/cpu_x86_Windows.ipp rename to experiments/cpu_x86_Windows.ipp diff --git a/benchmark/cpu_x86_impl.hpp b/experiments/cpu_x86_impl.hpp similarity index 100% rename from benchmark/cpu_x86_impl.hpp rename to experiments/cpu_x86_impl.hpp diff --git a/benchmark/cycle.cpp b/experiments/cycle.cpp similarity index 100% rename from benchmark/cycle.cpp rename to experiments/cycle.cpp diff --git a/benchmark/inverse.cpp b/experiments/inverse.cpp similarity index 100% rename from benchmark/inverse.cpp rename to experiments/inverse.cpp diff --git a/benchmark/length.cpp b/experiments/length.cpp similarity index 100% rename from benchmark/length.cpp rename to experiments/length.cpp diff --git a/benchmark/python/compare.py b/experiments/python/compare.py similarity index 100% rename from benchmark/python/compare.py rename to experiments/python/compare.py diff --git a/benchmark/python/compare_bench.py b/experiments/python/compare_bench.py similarity index 100% rename from benchmark/python/compare_bench.py rename to experiments/python/compare_bench.py diff --git a/benchmark/python/gbench/__init__.py b/experiments/python/gbench/__init__.py similarity index 100% rename from benchmark/python/gbench/__init__.py rename to experiments/python/gbench/__init__.py diff --git a/benchmark/python/gbench/report.py b/experiments/python/gbench/report.py similarity index 100% rename from benchmark/python/gbench/report.py rename to experiments/python/gbench/report.py diff --git a/benchmark/python/gbench/util.py b/experiments/python/gbench/util.py similarity index 100% rename from benchmark/python/gbench/util.py rename to experiments/python/gbench/util.py diff --git a/benchmark/sort.cpp b/experiments/sort.cpp similarity index 100% rename from benchmark/sort.cpp rename to experiments/sort.cpp diff --git a/benchmark/sum.cpp b/experiments/sum.cpp similarity index 100% rename from benchmark/sum.cpp rename to experiments/sum.cpp diff --git a/benchmark/testtools.hpp b/experiments/testtools.hpp similarity index 100% rename from benchmark/testtools.hpp rename to experiments/testtools.hpp diff --git a/include/hpcombi/bmat8_impl.hpp b/include/hpcombi/bmat8_impl.hpp index 394651b3..f92eb59b 100644 --- a/include/hpcombi/bmat8_impl.hpp +++ b/include/hpcombi/bmat8_impl.hpp @@ -449,7 +449,10 @@ inline Perm16 BMat8::right_perm_action_on_basis_ref(BMat8 bm) const { std::distance(prod_rows.begin(), std::find(prod_rows.begin(), prod_rows.end(), row)); } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overflow" std::iota(perm.begin() + nr_rows(), perm.end(), nr_rows()); +#pragma GCC diagnostic pop Perm16 res = Perm16::one(); for (size_t i = 0; i < 8; i++) diff --git a/include/hpcombi/epu_impl.hpp b/include/hpcombi/epu_impl.hpp index be83c3b4..70d5d140 100644 --- a/include/hpcombi/epu_impl.hpp +++ b/include/hpcombi/epu_impl.hpp @@ -215,10 +215,11 @@ inline epu8 sort8_perm(epu8 &a) noexcept { inline epu8 random_epu8(uint16_t bnd) { epu8 res; - std::random_device rd; - std::default_random_engine e1(rd()); + static std::random_device rd; + static std::default_random_engine e1(rd()); std::uniform_int_distribution uniform_dist(0, bnd - 1); + for (size_t i = 0; i < 16; i++) res[i] = uniform_dist(e1); return res; diff --git a/include/hpcombi/perm16.hpp b/include/hpcombi/perm16.hpp index 5b74b239..d8fc99e4 100644 --- a/include/hpcombi/perm16.hpp +++ b/include/hpcombi/perm16.hpp @@ -47,19 +47,13 @@ struct alignas(16) PTransf16 : public Vect16 { using array = typename decltype(Epu8)::array; PTransf16() = default; - constexpr PTransf16(const PTransf16 &v) = default; + constexpr PTransf16(const vect v) : Vect16(v) {} constexpr PTransf16(const epu8 x) : Vect16(x) {} PTransf16(std::vector dom, std::vector rng, size_t = 0 /* unused */); PTransf16(std::initializer_list il); - PTransf16 &operator=(const PTransf16 &) = default; - PTransf16 &operator=(const epu8 &vv) { - v = vv; - return *this; - } - //! Return whether \c *this is a well constructed object bool validate(size_t k = 16) const { return HPCombi::is_partial_transformation(v, k); diff --git a/include/hpcombi/vect16.hpp b/include/hpcombi/vect16.hpp index 49c3e760..5ea4702d 100644 --- a/include/hpcombi/vect16.hpp +++ b/include/hpcombi/vect16.hpp @@ -33,19 +33,11 @@ struct alignas(16) Vect16 { epu8 v; Vect16() = default; - constexpr Vect16(const Vect16 &v) = default; - constexpr Vect16(epu8 x) : v(x) {} Vect16(std::initializer_list il, uint8_t def = 0) : v(Epu8(il, def)) {} constexpr operator epu8() const { return v; } - Vect16 &operator=(const Vect16 &) = default; - Vect16 &operator=(const epu8 &vv) { - v = vv; - return *this; - } - array &as_array() { return HPCombi::as_array(v); } const array &as_array() const { return HPCombi::as_array(v); } diff --git a/include/hpcombi/vect_generic.hpp b/include/hpcombi/vect_generic.hpp index 5e1e1558..2ba82a75 100644 --- a/include/hpcombi/vect_generic.hpp +++ b/include/hpcombi/vect_generic.hpp @@ -47,21 +47,14 @@ template struct VectGeneric { array v; VectGeneric() = default; - constexpr VectGeneric(const VectGeneric &v) = default; - VectGeneric(const std::array &_v) : v(_v) {} // NOLINT + VectGeneric(const array &_v) : v(_v) {} // NOLINT VectGeneric(std::initializer_list il, Expo def = 0) { HPCOMBI_ASSERT(il.size() <= Size); std::copy(il.begin(), il.end(), v.begin()); std::fill(v.begin() + il.size(), v.end(), def); } - VectGeneric &operator=(const VectGeneric &) = default; - VectGeneric &operator=(const array &vv) { - v = vv; - return *this; - } - Expo operator[](uint64_t i) const { return v[i]; } Expo &operator[](uint64_t i) { return v[i]; } diff --git a/tests/test_epu.cpp b/tests/test_epu.cpp index 2079a60f..ac165b6d 100644 --- a/tests/test_epu.cpp +++ b/tests/test_epu.cpp @@ -257,6 +257,8 @@ TEST_CASE_METHOD(Fix, "Epu8::is_sorted", "[Epu8][017]") { epu8 x = epu8id; CHECK(is_sorted(x)); auto &refx = as_array(x); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overflow" while (std::next_permutation(refx.begin(), refx.begin() + 9)) { CHECK(!is_sorted(x)); } @@ -269,6 +271,7 @@ TEST_CASE_METHOD(Fix, "Epu8::is_sorted", "[Epu8][017]") { while (std::next_permutation(refx.begin(), refx.begin() + 14)) { CHECK(!is_sorted(x)); } +#pragma GCC diagnostic pop } TEST_CASE_METHOD(Fix, "Epu8::sorted", "[Epu8][018]") { @@ -283,7 +286,10 @@ TEST_CASE_METHOD(Fix, "Epu8::sorted", "[Epu8][018]") { auto &refx = as_array(x); do { CHECK(is_sorted(sorted(x))); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overflow" } while (std::next_permutation(refx.begin(), refx.begin() + 9)); +#pragma GCC diagnostic pop } TEST_CASE_METHOD(Fix, "Epu8::revsorted", "[Epu8][019]") { @@ -298,7 +304,10 @@ TEST_CASE_METHOD(Fix, "Epu8::revsorted", "[Epu8][019]") { auto &refx = as_array(x); do { CHECK(is_sorted(reverted(revsorted(x)))); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overflow" } while (std::next_permutation(refx.begin(), refx.begin() + 9)); +#pragma GCC diagnostic pop } TEST_CASE_METHOD(Fix, "Epu8::sort_perm", "[Epu8][020]") { diff --git a/tests/test_perm16.cpp b/tests/test_perm16.cpp index fbb8b16d..8d13f868 100644 --- a/tests/test_perm16.cpp +++ b/tests/test_perm16.cpp @@ -27,7 +27,10 @@ std::vector all_perms(uint8_t sz) { epu8 x = HPCombi::epu8id; res.push_back(x); auto &refx = HPCombi::as_array(x); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overflow" while (std::next_permutation(refx.begin(), refx.begin() + sz)) { +#pragma GCC diagnostic pop res.push_back(x); } return res;