-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
237 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
#ifndef TUNINGPLAYRGROUND_HPP | ||
#define TUNINGPLAYRGROUND_HPP | ||
|
||
#include<Kokkos_Core.hpp> | ||
#include<unordered_map> | ||
|
||
namespace Impl { | ||
|
||
struct empty {}; | ||
|
||
template <typename Tunable, template <typename...> typename TupleLike, | ||
typename... Components, size_t... Indices> | ||
void invoke_benchmark_helper(const Tunable &tunable, int num_iters, | ||
const TupleLike<Components...> &tup, | ||
const std::index_sequence<Indices...>) { | ||
for (int x = 0; x < num_iters; ++x) { | ||
tunable(x, num_iters, std::get<Indices>(tup)...); | ||
} | ||
} | ||
|
||
template <typename Tunable, template <typename...> typename TupleLike, | ||
typename... Components> | ||
void invoke_benchmark(const Tunable &tunable, int num_iters, | ||
const TupleLike<Components...> &tup) { | ||
invoke_benchmark_helper(tunable, num_iters, tup, | ||
std::make_index_sequence<sizeof...(Components)>{}); | ||
} | ||
|
||
template <typename Setup> | ||
auto setup_helper(const Setup &setup, int num_iters, std::false_type) { | ||
return setup(num_iters); | ||
} | ||
template <typename Setup> | ||
auto setup_helper(const Setup &setup, int num_iters, std::true_type) { | ||
setup(num_iters); | ||
return std::make_tuple(); | ||
} | ||
|
||
} // namespace Impl | ||
|
||
template<typename Setup, typename Tunable> | ||
void tuned_kernel(int argc, char* argv[], Setup setup, Tunable tunable){ | ||
int num_iters = 100000; | ||
bool tuned_internals; | ||
bool found_tuning_tool; | ||
bool print_progress; | ||
Kokkos::initialize(argc, argv); | ||
{ | ||
using emptiness = | ||
typename std::is_same<decltype(setup(num_iters)), void>::type; | ||
auto kernel_data = Impl::setup_helper(setup, num_iters, emptiness{}); | ||
Impl::invoke_benchmark(tunable, num_iters, kernel_data); | ||
} | ||
Kokkos::finalize(); | ||
} | ||
|
||
void fastest_of_helper(int index){ | ||
/** error case*/ | ||
} | ||
|
||
template<typename Head, typename... Cons> | ||
void fastest_of_helper(int index, Head head, Cons... cons){ | ||
if(index == 0){ | ||
return head(); | ||
} | ||
return fastest_of_helper(index-1, cons...); | ||
} | ||
|
||
static std::unordered_map<std::string, size_t> ids_for_kernels; | ||
size_t create_categorical_int_tuner(std::string name, size_t num_options){ | ||
using namespace Kokkos::Tools::Experimental; | ||
VariableInfo info; | ||
info.category = StatisticalCategory::kokkos_value_categorical; | ||
info.type = ValueType::kokkos_value_int64; | ||
info.valueQuantity = CandidateValueType::kokkos_value_set; | ||
std::vector<int64_t> options; | ||
for(int x=0;x<num_options;++x){ | ||
options.push_back(x); | ||
} | ||
info.candidates = make_candidate_set(options.size(), options.data()); | ||
return declare_output_type(name, info); | ||
} | ||
|
||
size_t create_fastest_implementation_id(){ | ||
using namespace Kokkos::Tools::Experimental; | ||
static size_t id; | ||
static bool done; | ||
if(!done){ | ||
done = true; | ||
VariableInfo info; | ||
info.category = StatisticalCategory::kokkos_value_categorical; | ||
info.type = ValueType::kokkos_value_string; | ||
info.valueQuantity = CandidateValueType::kokkos_value_unbounded; | ||
id = declare_input_type("playground.fastest_implementation_of", info); | ||
} | ||
return id; | ||
} | ||
|
||
template<typename ... Implementations> | ||
void fastest_of(const std::string& label, Implementations... implementations){ | ||
using namespace Kokkos::Tools::Experimental; | ||
auto tuner_iter = [&]() { | ||
auto my_tuner = ids_for_kernels.find(label); | ||
if (my_tuner == ids_for_kernels.end()) { | ||
return (ids_for_kernels.emplace(label, create_categorical_int_tuner(label, sizeof...(Implementations))) | ||
.first); | ||
} | ||
return my_tuner; | ||
}(); | ||
auto var_id = tuner_iter->second; | ||
auto input_id = create_fastest_implementation_id(); | ||
VariableValue picked_implementation = make_variable_value(var_id,int64_t(0)); | ||
VariableValue which_kernel = make_variable_value(var_id,label.c_str()); | ||
auto context_id = get_new_context_id(); | ||
begin_context(context_id); | ||
set_input_values(context_id, 1, &which_kernel); | ||
request_output_values(context_id, 1, &picked_implementation); | ||
fastest_of_helper(picked_implementation.value.int_value, implementations...); | ||
end_context(context_id); | ||
} | ||
|
||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/** | ||
* two_var | ||
* | ||
* Complexity: medium | ||
* | ||
* Tuning problem: | ||
* | ||
* This is a two-valued tuning problem, in which you need | ||
* both parameters to learn the answer. There are two | ||
* values between 0 and 11 (inclusive). | ||
* | ||
* The penalty function here is just the distance between | ||
* your answer and the provided value. | ||
* | ||
*/ | ||
#include <tuning_playground.hpp> | ||
|
||
#include <chrono> | ||
#include <cmath> // cbrt | ||
#include <cstdlib> | ||
#include <iostream> | ||
#include <random> | ||
#include <tuple> | ||
#include <unistd.h> | ||
auto make_value_candidates() { | ||
std::vector<int64_t> candidates{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; | ||
int64_t *bad_candidate_impl = | ||
(int64_t *)malloc(sizeof(int64_t) * candidates.size()); | ||
memcpy(bad_candidate_impl, candidates.data(), | ||
sizeof(int64_t) * candidates.size()); | ||
return Kokkos::Tools::Experimental::make_candidate_set(candidates.size(), | ||
bad_candidate_impl); | ||
} | ||
int main(int argc, char *argv[]) { | ||
constexpr const int data_size = 1000; | ||
std::vector<std::string> species = {"dog", "person"}; | ||
//size_t context = Kokkos::Tools::Experimental::get_new_context_id(); | ||
size_t context{1}; | ||
tuned_kernel( | ||
argc, argv, | ||
[&](const int total_iters) { | ||
srand(time(NULL)); | ||
size_t x_value_id; | ||
size_t y_value_id; | ||
size_t x_answer_id; | ||
size_t y_answer_id; | ||
Kokkos::Tools::Experimental::VariableInfo x_value_info; | ||
x_value_info.type = | ||
Kokkos::Tools::Experimental::ValueType::kokkos_value_int64; | ||
x_value_info.category = Kokkos::Tools::Experimental:: | ||
StatisticalCategory::kokkos_value_ratio; | ||
x_value_info.valueQuantity = | ||
Kokkos::Tools::Experimental::CandidateValueType::kokkos_value_set; | ||
x_value_info.candidates = make_value_candidates(); | ||
Kokkos::Tools::Experimental::VariableInfo y_value_info; | ||
y_value_info.type = | ||
Kokkos::Tools::Experimental::ValueType::kokkos_value_int64; | ||
y_value_info.category = Kokkos::Tools::Experimental:: | ||
StatisticalCategory::kokkos_value_ratio; | ||
y_value_info.valueQuantity = | ||
Kokkos::Tools::Experimental::CandidateValueType::kokkos_value_set; | ||
y_value_info.candidates = make_value_candidates(); | ||
Kokkos::Tools::Experimental::VariableInfo x_answer_info; | ||
x_answer_info.type = | ||
Kokkos::Tools::Experimental::ValueType::kokkos_value_int64; | ||
x_answer_info.category = Kokkos::Tools::Experimental:: | ||
StatisticalCategory::kokkos_value_ratio; | ||
x_answer_info.valueQuantity = | ||
Kokkos::Tools::Experimental::CandidateValueType::kokkos_value_set; | ||
x_answer_info.candidates = make_value_candidates(); | ||
|
||
Kokkos::Tools::Experimental::VariableInfo y_answer_info; | ||
y_answer_info.type = | ||
Kokkos::Tools::Experimental::ValueType::kokkos_value_int64; | ||
y_answer_info.category = Kokkos::Tools::Experimental:: | ||
StatisticalCategory::kokkos_value_categorical; | ||
y_answer_info.valueQuantity = | ||
Kokkos::Tools::Experimental::CandidateValueType::kokkos_value_set; | ||
y_answer_info.candidates = make_value_candidates(); | ||
x_value_id = Kokkos::Tools::Experimental::declare_input_type( | ||
"tuning_playground.x_value", x_value_info); | ||
y_value_id = Kokkos::Tools::Experimental::declare_input_type( | ||
"tuning_playground.y_value", y_value_info); | ||
x_answer_id = Kokkos::Tools::Experimental::declare_output_type( | ||
"tuning_playground.x_answer", x_answer_info); | ||
y_answer_id = Kokkos::Tools::Experimental::declare_output_type( | ||
"tuning_playground.y_answer", y_answer_info); | ||
|
||
return std::make_tuple(x_value_id, y_value_id, x_answer_id, | ||
y_answer_id); | ||
}, | ||
[&](const int iter, const int total_iters, size_t x_value_id, | ||
size_t y_value_id, size_t x_answer_id, size_t y_answer_id) { | ||
int64_t x = rand() % 12; | ||
int64_t y = rand() % 12; | ||
std::vector<Kokkos::Tools::Experimental::VariableValue> feature_vector{ | ||
Kokkos::Tools::Experimental::make_variable_value(x_value_id, x), | ||
Kokkos::Tools::Experimental::make_variable_value(y_value_id, y)}; | ||
std::vector<Kokkos::Tools::Experimental::VariableValue> answer_vector{ | ||
Kokkos::Tools::Experimental::make_variable_value(x_answer_id, | ||
int64_t(0)), | ||
Kokkos::Tools::Experimental::make_variable_value(y_answer_id, | ||
int64_t(0))}; | ||
Kokkos::Tools::Experimental::begin_context(context); | ||
Kokkos::Tools::Experimental::set_input_values(context, 2, | ||
feature_vector.data()); | ||
Kokkos::Tools::Experimental::request_output_values( | ||
context, 2, answer_vector.data()); | ||
auto penalty = std::abs(answer_vector[0].value.int_value - x) + | ||
std::abs(answer_vector[1].value.int_value - y); | ||
usleep(10 * penalty); | ||
Kokkos::Tools::Experimental::end_context(context); | ||
}); | ||
} |