main.cpp 2.3 KB
Newer Older
Ignacio Labarca Figueroa's avatar
Ignacio Labarca Figueroa committed
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
/*
 * Programming Techniques for Scientific Simulations I
 * HS 2019
 * Exercise 10
 */

#include <iostream>
#include <chrono>
#include <cstdlib>
#include <random>

#include "matrix_multiplication.hpp"

double benchmark(function_t f, matrix_t const & A, matrix_t const & B, matrix_t & C, std::size_t N) noexcept {
	for (std::size_t i = 0; i < N * N; ++i) {
		C[i] = 0;
	}

	auto start = std::chrono::high_resolution_clock::now();
	f(A, B, C, N);
	auto end = std::chrono::high_resolution_clock::now();

	return std::chrono::duration<double>(end - start).count();
}

int main() {
	std::mt19937 gen;
	std::uniform_real_distribution<double> dis(0, 1);

	{
		constexpr int N = 16;
		constexpr double tolerance = 1e-6;
		matrix_t A(N * N);
		matrix_t B(N * N);

		for (std::size_t j = 0; j < N; ++j) {
			for (std::size_t i = 0; i < N; ++i) {
				A[i + j * N] = dis(gen);
				B[i + j * N] = dis(gen);
			}
		}

#define TEST(f) do { \
	matrix_t C(N * N); \
	for (int i = 0; i < N * N; ++i) { \
		C[i] = 0; \
	} \
	f(A, B, C, N); \
	for (int i = 0; i < N; ++i) { \
		for (int j = 0; j < N; ++j) { \
			if (std::abs(C0[i + j * N] - C[i + j * N]) > tolerance) { \
				std::cerr << #f << " incorrect" << '\n' << "C0" << '\n'; \
				for (int j = 0; j < N; ++j) { \
					for (int i = 0; i < N; ++i) { \
						std::cerr << C0[i + j * N] << ' '; \
					} \
					std::cerr << '\n'; \
				} \
				std::cerr << "C" << '\n'; \
				for (int j = 0; j < N; ++j) { \
					for (int i = 0; i < N; ++i) { \
						std::cerr << C[i + j * N] << ' '; \
					} \
					std::cerr << '\n'; \
				} \
				exit(1); \
			} \
		} \
	} \
} while (false)

		matrix_t C0(N * N);
		mm0(A, B, C0, N);

		TEST(mm0);
		TEST(mm1);
		TEST(mm2);
		TEST(mm3);
		TEST(mm_blas);
		TEST(mm_eigen);
	}

	constexpr int runs = 10;

	#define BENCHMARK(f) do { \
		for (int i = 0; i < runs; ++i) { \
			auto time = benchmark(f, A, B, C, N); \
			std::cout << #f << ',' << N << ',' << time << std::endl; \
		} \
	} while (false)

	std::cout << "function,size,time" << std::endl;

	for (int N = 4; N <= 1024; N *= 2) {
		matrix_t A(N * N);
		matrix_t B(N * N);
		matrix_t C(N * N);

		for (std::size_t i = 0; i < N * N; ++i) {
			A[i] = dis(gen);
			B[i] = dis(gen);
		}

		BENCHMARK(mm0);
		BENCHMARK(mm1);
		BENCHMARK(mm2);
		BENCHMARK(mm3);

		BENCHMARK(mm_blas);
		BENCHMARK(mm_eigen);

	}

	#undef BENCHMARK
}