Skip to content

Commit

Permalink
Fix happycat function and extend fuzzing time
Browse files Browse the repository at this point in the history
  • Loading branch information
ewarchul committed Jun 29, 2024
1 parent 8ce0eb4 commit c4966f2
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 53 deletions.
3 changes: 1 addition & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

include(Package)
include(config)

include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
include(GenerateExportHeader)
Expand Down Expand Up @@ -49,7 +50,6 @@ target_sources(cecxx PRIVATE ${SOURCES})
target_sources(cecxx PUBLIC FILE_SET HEADERS BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include" FILES ${HEADERS})
target_compile_options(cecxx PRIVATE ${COMPILE_FLAGS})
target_compile_features(cecxx PRIVATE cxx_std_20)
#target_compile_definitions(cecxx PUBLIC DEFAULT_BENCHMARK_DATADIR="${BENCHMARK_DATA_STORAGE}")

configure_file(defaults.hpp.in ${CMAKE_CURRENT_SOURCE_DIR}/include/cecxx/benchmark/defaults.hpp)
generate_export_header(cecxx)
Expand All @@ -60,7 +60,6 @@ write_basic_package_version_file("${PROJECT_BINARY_DIR}/cecxxConfigVersion.cmake
)

include(CPack)
message("${BENCHMARK_DATA_STORAGE}")

install(TARGETS cecxx EXPORT cecxxTargets FILE_SET HEADERS)
install(EXPORT cecxxTargets NAMESPACE cecxx:: DESTINATION lib/cmake/cecxx)
Expand Down
14 changes: 8 additions & 6 deletions Justfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
set dotenv-load

alias i := init_build
alias b := build
alias r := rebuild
alias p := package
alias e := exe
alias t := test
Expand All @@ -12,19 +12,21 @@ c_compiler := "${CC}"
build_dir := "build-" + cxx_compiler
ncores := `nproc`

build: clean

# cd {{build_dir}} && CC={{c_compiler}} CXX={{cxx_compiler}} cmake -DWITH_TESTS=off ..

init_build: clean
mkdir -p {{build_dir}}
cd {{build_dir}} && CC={{c_compiler}} CXX={{cxx_compiler}} cmake -DFUZZTEST_FUZZING_MODE=on -DWITH_TESTS=on ..
cd {{build_dir}} && CC={{c_compiler}} CXX={{cxx_compiler}} cmake -DFUZZTEST_FUZZING_MODE=on -DWITH_TESTS=on -DWITH_EXAMPLES=on ..
ln -fs {{build_dir}}/compile_commands.json compile_commands.json
cd {{build_dir}} && make -j {{ncores}}

rebuild:
build:
cd {{build_dir}} && make -j {{ncores}}

exe:
./{{build_dir}}/main

fuzz_duration := "2s"
fuzz_duration := "15s"
test:
#!/usr/bin/env bash
set -euxo pipefail
Expand Down
8 changes: 3 additions & 5 deletions example/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,19 @@ auto main() -> int {

// Prepare input which resembles multidimensional array
const auto input = std::vector<std::vector<f64>>{
rv::repeat(10.0) | rv::take(DIMENSION) | ranges::to_vector};


rv::repeat(0.0) | rv::take(DIMENSION) | ranges::to_vector};

// Evaluate given input on each optimization problem from CEC2017
const auto start = std::chrono::system_clock::now();
for (const auto &fn : rv::closed_iota(11, 11)) {
for (const auto &fn : rv::closed_iota(1, 30)) {
auto output = cec2017_eval(fn, input);
fmt::println("fn = {}, output = {:}", fn, output);
}

fmt::println("Elapsed time: {}",
std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::system_clock::now() - start));

return EXIT_SUCCESS;
// Create a closure for 1st optimizaiton problem from CEC2017
const auto first_fn = [&eval = cec2017_eval](const auto &xs) {
return eval(11, xs);
Expand Down
1 change: 0 additions & 1 deletion include/cecxx/benchmark/detail/problem/complex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "cecxx/benchmark/detail/context.hpp"

namespace cecxx::benchmark::detail {

struct complex_problem_params {
std::vector<double> deltas{};
std::vector<double> biases{};
Expand Down
2 changes: 1 addition & 1 deletion include/cecxx/functions/multimodal/happycat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ constexpr auto happycat(std::span<const f64> input) -> f64 {
constexpr auto alpha = 1.0 / 8.0;
for (auto i = 0u; i < nrow; i++) {
r2 += (input[i] - 1.0) * (input[i] - 1.0);
sum_z += input[i];
sum_z += (input[i] - 1.0);
}
return std::pow(std::fabs(r2 - static_cast<f64>(nrow)), 2 * alpha) +
(0.5 * r2 + sum_z) / static_cast<f64>(nrow) + 0.5;
Expand Down
2 changes: 1 addition & 1 deletion src/legacy/affine_trans.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace cecxx::benchmark::detail {
void shufflefunc(std::span<const f64> input, std::span<f64> output,
std::span<const i64> shuffle_vec) {
for (auto i = 0u; i < output.size(); i++) {
auto idx = static_cast<u64>(std::max(shuffle_vec[i] - 1, 1L));
auto idx = static_cast<u64>(std::max(shuffle_vec[i] - 1, 0L));
output[i] = input[idx];
}
}
Expand Down
1 change: 0 additions & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ include(GoogleTest)

fuzztest_setup_fuzzing_flags()


add_compile_definitions(DATA_STORAGE_PATH="${CMAKE_SOURCE_DIR}/data")

add_executable(cecxx-fuzz gtest/cec2017_oracle_test.cpp oracle/cec2017.cpp)
Expand Down
67 changes: 41 additions & 26 deletions test/gtest/cec2017_oracle_test.cpp
Original file line number Diff line number Diff line change
@@ -1,67 +1,82 @@
// clang-format off
#include "gtest/gtest.h"
#include "fuzztest/fuzztest.h"
#include "helpers/combinators.hpp"
#include "fuzztest/googletest_fixture_adapter.h"
#include "fuzztest/domain.h"
// clang-format on

#include <range/v3/all.hpp>

#include "cecxx/evaluator.hpp"
#include "cecxx/benchmark/evaluator.hpp"

#include "cecxx/types.hpp"
#include "helpers/combinators.hpp"

#include "helpers/cec_suite.hpp"
#include "helpers/oracle.hpp"

using namespace fuzztest;
using namespace cecxx::benchmark;

class CecFuzzTest10D : public PerFuzzTestFixtureAdapter<CecTestFixture<cecxx::cec_edition_t::cec2017, 10>> {
public:
constexpr auto MAX_ABS_ERROR = 1e-10;

class CecFuzzTest10D : public PerFuzzTestFixtureAdapter<
CecTestFixture<cec_edition_t::cec2017, 10>> {
public:
void Cec2017ImplsAreEquiv(std::vector<double> input, int problem_num) {
const auto oracle_output = calculate_oracle_output(input, problem_num);
const auto cecxx_output = cec_evaluator(problem_num, std::vector<std::vector<double>>{input});
const auto delta = std::abs(oracle_output - cecxx_output[0]);
EXPECT_TRUE(delta < 1);
const auto cecxx_output =
cec_evaluator(problem_num, std::vector<std::vector<double>>{input});
EXPECT_NEAR(oracle_output, cecxx_output[0], MAX_ABS_ERROR);
}
};

FUZZ_TEST_F(CecFuzzTest10D, Cec2017ImplsAreEquiv)
.WithDomains(PositiveVectorOf<double>(InRange(-1.0, 1.0)).WithSize(10), InCecProblemRange(cecxx::cec_edition_t::cec2017));
.WithDomains(PositiveVectorOf<double>(InRange(-1.0, 1.0)).WithSize(10),
InCecProblemRange(cec_edition_t::cec2017));

class CecFuzzTest30D : public PerFuzzTestFixtureAdapter<CecTestFixture<cecxx::cec_edition_t::cec2017, 30>> {
public:
class CecFuzzTest30D : public PerFuzzTestFixtureAdapter<
CecTestFixture<cec_edition_t::cec2017, 30>> {
public:
void Cec2017ImplsAreEquiv(std::vector<double> input, int problem_num) {
const auto oracle_output = calculate_oracle_output(input, problem_num);
const auto cecxx_output = cec_evaluator(problem_num, std::vector<std::vector<double>>{input});
const auto delta = std::abs(oracle_output - cecxx_output[0]);
EXPECT_TRUE(delta < 1);
const auto cecxx_output =
cec_evaluator(problem_num, std::vector<std::vector<double>>{input});
EXPECT_NEAR(oracle_output, cecxx_output[0], MAX_ABS_ERROR);
}
};

FUZZ_TEST_F(CecFuzzTest30D, Cec2017ImplsAreEquiv)
.WithDomains(PositiveVectorOf<double>(InRange(-1.0, 1.0)).WithSize(30), InCecProblemRange(cecxx::cec_edition_t::cec2017));
.WithDomains(PositiveVectorOf<double>(InRange(-1.0, 1.0)).WithSize(30),
InCecProblemRange(cec_edition_t::cec2017));

class CecFuzzTest50D : public PerFuzzTestFixtureAdapter<CecTestFixture<cecxx::cec_edition_t::cec2017, 50>> {
public:
class CecFuzzTest50D : public PerFuzzTestFixtureAdapter<
CecTestFixture<cec_edition_t::cec2017, 50>> {
public:
void Cec2017ImplsAreEquiv(std::vector<double> input, int problem_num) {
const auto oracle_output = calculate_oracle_output(input, problem_num);
const auto cecxx_output = cec_evaluator(problem_num, std::vector<std::vector<double>>{input});
const auto delta = std::abs(oracle_output - cecxx_output[0]);
EXPECT_TRUE(delta < 1);
const auto cecxx_output =
cec_evaluator(problem_num, std::vector<std::vector<double>>{input});

EXPECT_NEAR(oracle_output, cecxx_output[0], MAX_ABS_ERROR);
}
};

FUZZ_TEST_F(CecFuzzTest50D, Cec2017ImplsAreEquiv)
.WithDomains(PositiveVectorOf<double>(InRange(-1.0, 1.0)).WithSize(50), InCecProblemRange(cecxx::cec_edition_t::cec2017));
.WithDomains(PositiveVectorOf<double>(InRange(-1.0, 1.0)).WithSize(50),
InCecProblemRange(cec_edition_t::cec2017));

class CecFuzzTest100D : public PerFuzzTestFixtureAdapter<CecTestFixture<cecxx::cec_edition_t::cec2017, 100>> {
public:
class CecFuzzTest100D : public PerFuzzTestFixtureAdapter<
CecTestFixture<cec_edition_t::cec2017, 100>> {
public:
void Cec2017ImplsAreEquiv(std::vector<double> input, int problem_num) {
const auto oracle_output = calculate_oracle_output(input, problem_num);
const auto cecxx_output = cec_evaluator(problem_num, std::vector<std::vector<double>>{input});
const auto delta = std::abs(oracle_output - cecxx_output[0]);
EXPECT_TRUE(delta < 10);
const auto cecxx_output =
cec_evaluator(problem_num, std::vector<std::vector<double>>{input});
EXPECT_NEAR(oracle_output, cecxx_output[0], MAX_ABS_ERROR);
}
};

FUZZ_TEST_F(CecFuzzTest100D, Cec2017ImplsAreEquiv)
.WithDomains(PositiveVectorOf<double>(InRange(-1.0, 1.0)).WithSize(100), InCecProblemRange(cecxx::cec_edition_t::cec2017));
.WithDomains(PositiveVectorOf<double>(InRange(-1.0, 1.0)).WithSize(100),
InCecProblemRange(cec_edition_t::cec2017));
14 changes: 10 additions & 4 deletions test/helpers/cec_suite.hpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
#pragma once

// clang-format off
#include "gtest/gtest.h"
#include "cecxx/evaluator.hpp"
// clang-format on

template <cecxx::cec_edition_t Edition, int Dimension> struct CecTestFixture : public testing::Test {
CecTestFixture() : cec_evaluator{cecxx::evaluator(Edition, Dimension, DATA_STORAGE_PATH)} {}
cecxx::evaluator cec_evaluator;
#include "cecxx/benchmark/evaluator.hpp"

template <cecxx::benchmark::cec_edition_t Edition, int Dimension>
struct CecTestFixture : public testing::Test {
CecTestFixture()
: cec_evaluator{cecxx::benchmark::evaluator(Edition, Dimension,
DATA_STORAGE_PATH)} {}
cecxx::benchmark::evaluator cec_evaluator;
};
12 changes: 7 additions & 5 deletions test/helpers/combinators.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@

#include <vector>

#include "cecxx/types.hpp"
#include "cecxx/benchmark/edition.hpp"
#include "fuzztest/domain.h"

template <typename T> auto PositiveVectorOf(auto&& Rng) {
template <typename T> auto PositiveVectorOf(auto &&Rng) {
return fuzztest::ContainerOf<std::vector>(std::forward<decltype(Rng)>(Rng));
}

auto InCecProblemRange(cecxx::cec_edition_t edition) {
auto InCecProblemRange(cecxx::benchmark::cec_edition_t edition) {
using namespace cecxx::benchmark;
switch (edition) {
case cecxx::cec_edition_t::cec2017: {
return fuzztest::Filter([](int x) { return x != 2; }, fuzztest::InRange(1, 28));
case cec_edition_t::cec2017: {
return fuzztest::Filter([](int x) { return x != 2; },
fuzztest::InRange(1, 30));
}
}
}
2 changes: 1 addition & 1 deletion test/oracle/cec2017.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ int ini_flag, n_flag, func_flag, *SS;

auto STORAGE_PREFIX(const auto& format) -> std::string {
using namespace std::string_literals;
return std::string{CEC_STORAGE} + "/cec2017/"s + format;
return std::string{DATA_STORAGE_PATH} + "/cec2017/"s + format;
}

long double fast_pow(long double x, int p) {
Expand Down

0 comments on commit c4966f2

Please sign in to comment.