algotune: finish library.
This commit is contained in:
parent
a5d4812025
commit
fbcef4955e
|
@ -4,5 +4,6 @@
|
||||||
],
|
],
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"*.ipp": "c"
|
"*.ipp": "c"
|
||||||
}
|
},
|
||||||
|
"python.linting.enabled": false
|
||||||
}
|
}
|
|
@ -2,6 +2,7 @@ AM_CPPFLAGS = -Wall -Wextra -pedantic -Wshadow -Wpointer-arith -Wcast-align
|
||||||
AM_CPPFLAGS += -Wwrite-strings -Wmissing-declarations -Wno-long-long -Werror
|
AM_CPPFLAGS += -Wwrite-strings -Wmissing-declarations -Wno-long-long -Werror
|
||||||
AM_CPPFLAGS += -Wunused-variable -std=c++14 -D_XOPEN_SOURCE -O2 -I.
|
AM_CPPFLAGS += -Wunused-variable -std=c++14 -D_XOPEN_SOURCE -O2 -I.
|
||||||
AM_CPPFLAGS += -fno-elide-constructors -Weffc++
|
AM_CPPFLAGS += -fno-elide-constructors -Weffc++
|
||||||
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
pkgconfigdir = $(libdir)/pkgconfig
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
pkgconfig_DATA = libalgotune-1.pc
|
pkgconfig_DATA = libalgotune-1.pc
|
||||||
|
@ -9,3 +10,7 @@ pkgconfig_DATA = libalgotune-1.pc
|
||||||
lib_LTLIBRARIES = libalgotune.la
|
lib_LTLIBRARIES = libalgotune.la
|
||||||
nobase_include_HEADERS = algotune.h
|
nobase_include_HEADERS = algotune.h
|
||||||
libalgotune_la_SOURCES = algotune.cc
|
libalgotune_la_SOURCES = algotune.cc
|
||||||
|
|
||||||
|
check_PROGRAMS = algotune_test
|
||||||
|
algotune_test_SOURCES = algotune_test.cc
|
||||||
|
algotune_test_LDADD = libalgotune.la
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -5,45 +7,110 @@
|
||||||
|
|
||||||
namespace algotune {
|
namespace algotune {
|
||||||
|
|
||||||
|
|
||||||
|
static std::mt19937 rng;
|
||||||
|
static std::random_device devrand;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
reseed()
|
||||||
|
{
|
||||||
|
rng.seed(devrand());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
rand_int(int low, int high)
|
rand_int(int low, int high)
|
||||||
{
|
{
|
||||||
return -1;
|
std::uniform_int_distribution<int> dist(low, high);
|
||||||
|
return dist(rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
rand_int(int64_t low, int64_t high)
|
rand_int64(int64_t low, int64_t high)
|
||||||
{
|
{
|
||||||
return -1;
|
std::uniform_int_distribution<int64_t> dist(low, high);
|
||||||
|
return dist(rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<int>
|
std::vector<int>
|
||||||
gen_int_vector(int size, int low, int high)
|
gen_int_vector(int size, int low, int high)
|
||||||
{
|
{
|
||||||
return vector<int>(0);
|
assert(low < high);
|
||||||
|
reseed();
|
||||||
|
std::vector<int> v(size);
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
v[i] = rand_int(low, high);
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<int64_t>
|
std::vector<int64_t>
|
||||||
gen_int_vector(int size, int low, int high)
|
gen_int64_vector(int64_t size, int64_t low, int64_t high)
|
||||||
{
|
{
|
||||||
return vector<int64_t>(0);
|
assert(low < high);
|
||||||
|
reseed();
|
||||||
|
std::vector<int64_t> v(size);
|
||||||
|
|
||||||
|
for (int64_t i = 0; i < size; i++) {
|
||||||
|
v[i] = rand_int64(low, high);
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
int64_t
|
||||||
stress_test_int(bool(*func)(std::vector<int>))
|
stress_test_int(bool(*func)(std::vector<int>&), int size, int low, int high)
|
||||||
{
|
{
|
||||||
|
assert(func != nullptr);
|
||||||
|
std::vector<int> v;
|
||||||
|
bool result = true;
|
||||||
|
int64_t iterations = 0;
|
||||||
|
int vsize = 0;
|
||||||
|
|
||||||
|
while (result) {
|
||||||
|
iterations++;
|
||||||
|
vsize = rand_int(0, size);
|
||||||
|
v = gen_int_vector(vsize, low, high);
|
||||||
|
result = func(v);
|
||||||
|
|
||||||
|
if ((iterations > 1) && ((iterations % display_step) == 0)) {
|
||||||
|
std::cout << "Iteration: " << iterations << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return iterations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
int64_t
|
||||||
stress_test_int64(bool(*func)(std::vector<int64_t))
|
stress_test_int64(bool(*func)(std::vector<int64_t>&), int64_t size, int64_t low, int64_t high)
|
||||||
{
|
{
|
||||||
|
assert(func != nullptr);
|
||||||
|
std::vector<int64_t> v;
|
||||||
|
bool result = true;
|
||||||
|
int64_t iterations = 0;
|
||||||
|
int64_t vsize = 0;
|
||||||
|
|
||||||
|
while (result) {
|
||||||
|
iterations++;
|
||||||
|
vsize = rand_int64(0, size);
|
||||||
|
v = gen_int64_vector(vsize, low, high);
|
||||||
|
result = func(v);
|
||||||
|
|
||||||
|
if ((iterations > 1) && ((iterations % display_step) == 0)) {
|
||||||
|
std::cout << "Iteration: " << iterations << std::endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return iterations;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace algotune
|
} // namespace algotune
|
||||||
|
|
|
@ -5,14 +5,18 @@
|
||||||
|
|
||||||
namespace algotune {
|
namespace algotune {
|
||||||
|
|
||||||
|
int64_t display_step = 1000;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int rand_int(int low, int high);
|
int rand_int(int low, int high);
|
||||||
int64_t rand_int(int64_t low, int64_t high);
|
int64_t rand_int64(int64_t low, int64_t high);
|
||||||
|
|
||||||
std::vector<int> gen_int_vector(int size, int low, int high);
|
std::vector<int> gen_int_vector(int size, int low, int high);
|
||||||
std::vector<int64_t> gen_int_vector(int size, int low, int high);
|
std::vector<int64_t> gen_int64_vector(int64_t size, int64_t low, int64_t high);
|
||||||
|
|
||||||
void stress_test_int(bool(*func)(std::vector<int>));
|
int64_t stress_test_int(bool(*func)(std::vector<int>&), int size, int low, int high);
|
||||||
void stress_test_int64(bool(*func)(std::vector<int64_t));
|
int64_t stress_test_int64(bool(*func)(std::vector<int64_t>&), int64_t size, int64_t low, int64_t high);
|
||||||
|
|
||||||
} // namespace algotune
|
} // namespace algotune
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "algotune.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
static int64_t
|
||||||
|
max_pairwise_fast(vector<int> &v)
|
||||||
|
{
|
||||||
|
size_t idx1 = 0;
|
||||||
|
size_t idx2 = 0;
|
||||||
|
auto n = v.size();
|
||||||
|
|
||||||
|
for (size_t i = 1; i < n; i++) {
|
||||||
|
if (v[i] > v[idx1]) {
|
||||||
|
idx1 = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 1; i < n; i++) {
|
||||||
|
if (i == idx1) continue;
|
||||||
|
if ((v[i] > v[idx2]) || (idx2 == idx1)) {
|
||||||
|
idx2 = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<int64_t>(v[idx1]) * static_cast<int64_t>(v[idx2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int64_t
|
||||||
|
max_pairwise_naive(vector<int> &v)
|
||||||
|
{
|
||||||
|
auto n = v.size();
|
||||||
|
int64_t best = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
for (size_t j = 0; j < n; j++) {
|
||||||
|
if (i == j) continue;
|
||||||
|
int64_t prod = v[i] * v[j];
|
||||||
|
best = prod > best ? prod : best;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
test_max_pairwise_fast(vector<int> &v)
|
||||||
|
{
|
||||||
|
auto result_fast = max_pairwise_fast(v);
|
||||||
|
auto result_naive = max_pairwise_naive(v);
|
||||||
|
|
||||||
|
return result_fast == result_naive;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
vector<int> v = algotune::gen_int_vector(10, 1, 10000);
|
||||||
|
if (!test_max_pairwise_fast(v)) {
|
||||||
|
cerr << "test failed\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
algotune::display_step = 100;
|
||||||
|
auto iterations = algotune::stress_test_int(test_max_pairwise_fast, 10000, 1, 1000000);
|
||||||
|
cout << "Iterations before failure: " << iterations << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
AC_PREREQ([2.68])
|
AC_PREREQ([2.69])
|
||||||
AC_INIT([libalgotune],
|
AC_INIT([libalgotune],
|
||||||
[1.0.0],
|
[1.0.0],
|
||||||
[kyle@imap.cc],
|
[kyle@imap.cc],
|
||||||
[],
|
[],
|
||||||
[])
|
[])
|
||||||
AM_INIT_AUTOMAKE([1.11 foreign])
|
AM_INIT_AUTOMAKE([1.15 foreign])
|
||||||
|
|
||||||
LT_INIT
|
LT_INIT
|
||||||
|
|
||||||
|
@ -13,10 +13,10 @@ PKG_PROG_PKG_CONFIG
|
||||||
AC_CONFIG_SRCDIR([algotune.h])
|
AC_CONFIG_SRCDIR([algotune.h])
|
||||||
AC_CONFIG_FILES([Makefile
|
AC_CONFIG_FILES([Makefile
|
||||||
libalgotune-1.pc])
|
libalgotune-1.pc])
|
||||||
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
|
||||||
AC_PROG_CXX
|
AC_PROG_CXX
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
AC_PROG_CC_C_O
|
AC_PROG_CC_C_O
|
||||||
|
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue