Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: migrate GD namespace #4442

Merged
merged 5 commits into from
Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion python/pylibvw.cc
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ py::object get_options(vw_ptr all, py::object py_class, bool enabled_only)
return opt_manager.get_vw_option_pyobjects(enabled_only);
}

void my_audit_example(vw_ptr all, example_ptr ec) { GD::print_audit_features(*all, *ec); }
void my_audit_example(vw_ptr all, example_ptr ec) { VW::details::print_audit_features(*all, *ec); }

const char* get_model_id(vw_ptr all) { return all->id.c_str(); }

Expand Down
120 changes: 108 additions & 12 deletions vowpalwabbit/core/include/vw/core/gd_predict.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,18 @@
#undef VW_DEBUG_LOG
#define VW_DEBUG_LOG vw_dbg::GD_PREDICT

namespace GD
namespace VW
{
namespace details
{
template <class DataT>
inline void dummy_func(DataT&, const VW::audit_strings*)
{
} // should never be called due to call_audit overload

inline void vec_add(float& p, float fx, float fw) { p += fw * fx; }

} // namespace details
// iterate through one namespace (or its part), callback function FuncT(some_data_R, feature_value_x, feature_index)
template <class DataT, void (*FuncT)(DataT&, float feature_value, uint64_t feature_index), class WeightsT>
void foreach_feature(WeightsT& /*weights*/, const VW::features& fs, DataT& dat, uint64_t offset = 0, float mult = 1.)
Expand All @@ -39,11 +49,6 @@ inline void foreach_feature(
for (const auto& f : fs) { FuncT(dat, mult * f.value(), weights[static_cast<size_t>(f.index() + offset)]); }
}

template <class DataT>
inline void dummy_func(DataT&, const VW::audit_strings*)
{
} // should never be called due to call_audit overload

template <class DataT, class WeightOrIndexT, void (*FuncT)(DataT&, float, WeightOrIndexT),
class WeightsT> // nullptr func can't be used as template param in old
// compilers
Expand All @@ -54,7 +59,7 @@ inline void generate_interactions(const std::vector<std::vector<VW::namespace_in
VW::details::generate_interactions_object_cache& cache) // default value removed to eliminate
// ambiguity in old complers
{
VW::generate_interactions<DataT, WeightOrIndexT, FuncT, false, dummy_func<DataT>, WeightsT>(
VW::generate_interactions<DataT, WeightOrIndexT, FuncT, false, details::dummy_func<DataT>, WeightsT>(
interactions, extent_interactions, permutations, ec, dat, weights, num_interacted_features, cache);
}

Expand Down Expand Up @@ -100,16 +105,14 @@ inline void foreach_feature(WeightsT& weights, bool ignore_some_linear,
extent_interactions, permutations, ec, dat, num_interacted_features_ignored, cache);
}

inline void vec_add(float& p, float fx, float fw) { p += fw * fx; }

template <class WeightsT>
inline float inline_predict(WeightsT& weights, bool ignore_some_linear,
std::array<bool, VW::NUM_NAMESPACES>& ignore_linear,
const std::vector<std::vector<VW::namespace_index>>& interactions,
const std::vector<std::vector<VW::extent_term>>& extent_interactions, bool permutations, VW::example_predict& ec,
VW::details::generate_interactions_object_cache& cache, float initial = 0.f)
{
foreach_feature<float, float, vec_add, WeightsT>(
foreach_feature<float, float, details::vec_add, WeightsT>(
weights, ignore_some_linear, ignore_linear, interactions, extent_interactions, permutations, ec, initial, cache);
return initial;
}
Expand All @@ -121,8 +124,101 @@ inline float inline_predict(WeightsT& weights, bool ignore_some_linear,
const std::vector<std::vector<VW::extent_term>>& extent_interactions, bool permutations, VW::example_predict& ec,
size_t& num_interacted_features, VW::details::generate_interactions_object_cache& cache, float initial = 0.f)
{
foreach_feature<float, float, vec_add, WeightsT>(weights, ignore_some_linear, ignore_linear, interactions,
foreach_feature<float, float, details::vec_add, WeightsT>(weights, ignore_some_linear, ignore_linear, interactions,
extent_interactions, permutations, ec, initial, num_interacted_features, cache);
return initial;
}
} // namespace GD
} // namespace VW

namespace GD
{

// iterate through one namespace (or its part), callback function FuncT(some_data_R, feature_value_x, feature_index)
template <class DataT, void (*FuncT)(DataT&, float feature_value, uint64_t feature_index), class WeightsT>
VW_DEPRECATED("Moved to VW namespace")
void foreach_feature(WeightsT& weights, const VW::features& fs, DataT& dat, uint64_t offset = 0, float mult = 1.)
{
VW::foreach_feature<DataT, FuncT, WeightsT>(weights, fs, dat, offset, mult);
}

// iterate through one namespace (or its part), callback function FuncT(some_data_R, feature_value_x, feature_weight)
template <class DataT, void (*FuncT)(DataT&, const float feature_value, float& weight_reference), class WeightsT>
VW_DEPRECATED("Moved to VW namespace")
inline void foreach_feature(WeightsT& weights, const VW::features& fs, DataT& dat, uint64_t offset = 0, float mult = 1.)
{
VW::foreach_feature<DataT, FuncT, WeightsT>(weights, fs, dat, offset, mult);
}

// iterate through one namespace (or its part), callback function FuncT(some_data_R, feature_value_x, feature_weight)
template <class DataT, void (*FuncT)(DataT&, float, float), class WeightsT>
VW_DEPRECATED("Moved to VW namespace")
inline void foreach_feature(
const WeightsT& weights, const VW::features& fs, DataT& dat, uint64_t offset = 0, float mult = 1.)
{
VW::foreach_feature<DataT, FuncT, WeightsT>(weights, fs, dat, offset, mult);
}

template <class DataT, class WeightOrIndexT, void (*FuncT)(DataT&, float, WeightOrIndexT),
class WeightsT> // nullptr func can't be used as template param in old
// compilers
VW_DEPRECATED("Moved to VW namespace") inline void generate_interactions(
const std::vector<std::vector<VW::namespace_index>>& interactions,
const std::vector<std::vector<VW::extent_term>>& extent_interactions, bool permutations, VW::example_predict& ec,
DataT& dat, WeightsT& weights, size_t& num_interacted_features,
VW::details::generate_interactions_object_cache& cache) // default value removed to eliminate
// ambiguity in old complers
{
VW::generate_interactions<DataT, WeightOrIndexT, FuncT, WeightsT>(
interactions, extent_interactions, permutations, ec, dat, weights, num_interacted_features, cache);
}

// iterate through all namespaces and quadratic&cubic features, callback function FuncT(some_data_R, feature_value_x,
// WeightOrIndexT) where WeightOrIndexT is EITHER float& feature_weight OR uint64_t feature_index
template <class DataT, class WeightOrIndexT, void (*FuncT)(DataT&, float, WeightOrIndexT), class WeightsT>
VW_DEPRECATED("Moved to VW namespace")
inline void foreach_feature(WeightsT& weights, bool ignore_some_linear,
std::array<bool, VW::NUM_NAMESPACES>& ignore_linear,
const std::vector<std::vector<VW::namespace_index>>& interactions,
const std::vector<std::vector<VW::extent_term>>& extent_interactions, bool permutations, VW::example_predict& ec,
DataT& dat, size_t& num_interacted_features, VW::details::generate_interactions_object_cache& cache)
{
VW::foreach_feature<DataT, WeightOrIndexT, FuncT, WeightsT>(weights, ignore_some_linear, ignore_linear, interactions,
extent_interactions, permutations, ec, dat, num_interacted_features, cache);
}

template <class DataT, class WeightOrIndexT, void (*FuncT)(DataT&, float, WeightOrIndexT), class WeightsT>
VW_DEPRECATED("Moved to VW namespace")
inline void foreach_feature(WeightsT& weights, bool ignore_some_linear,
std::array<bool, VW::NUM_NAMESPACES>& ignore_linear,
const std::vector<std::vector<VW::namespace_index>>& interactions,
const std::vector<std::vector<VW::extent_term>>& extent_interactions, bool permutations, VW::example_predict& ec,
DataT& dat, VW::details::generate_interactions_object_cache& cache)
{
VW::foreach_feature<DataT, WeightOrIndexT, FuncT, WeightsT>(
weights, ignore_some_linear, ignore_linear, interactions, extent_interactions, permutations, ec, dat, cache);
}

template <class WeightsT>
VW_DEPRECATED("Moved to VW namespace")
inline float inline_predict(WeightsT& weights, bool ignore_some_linear,
std::array<bool, VW::NUM_NAMESPACES>& ignore_linear,
const std::vector<std::vector<VW::namespace_index>>& interactions,
const std::vector<std::vector<VW::extent_term>>& extent_interactions, bool permutations, VW::example_predict& ec,
VW::details::generate_interactions_object_cache& cache, float initial = 0.f)
{
return VW::inline_predict(
weights, ignore_some_linear, ignore_linear, interactions, extent_interactions, permutations, ec, cache, initial);
}

template <class WeightsT>
VW_DEPRECATED("Moved to VW namespace")
inline float inline_predict(WeightsT& weights, bool ignore_some_linear,
std::array<bool, VW::NUM_NAMESPACES>& ignore_linear,
const std::vector<std::vector<VW::namespace_index>>& interactions,
const std::vector<std::vector<VW::extent_term>>& extent_interactions, bool permutations, VW::example_predict& ec,
size_t& num_interacted_features, VW::details::generate_interactions_object_cache& cache, float initial = 0.f)
{
return VW::inline_predict(weights, ignore_some_linear, ignore_linear, interactions, extent_interactions, permutations,
ec, num_interacted_features, cache, initial);
}
} // namespace GD
87 changes: 79 additions & 8 deletions vowpalwabbit/core/include/vw/core/reductions/gd.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,22 @@ namespace VW
namespace reductions
{
VW::LEARNER::base_learner* gd_setup(VW::setup_base_i& stack_builder);
}
} // namespace VW
namespace GD

namespace details
{

class per_model_state
{
public:
double normalized_sum_norm_x = 0.0;
double total_weight = 0.0;
};
} // namespace details

class gd
{
public:
std::vector<per_model_state> per_model_states;
std::vector<details::per_model_state> per_model_states;
size_t no_win_counter = 0;
size_t early_stop_thres = 0;
float initial_constant = 0.f;
Expand All @@ -52,13 +54,17 @@ class gd
bool adax = false;
VW::workspace* all = nullptr; // parallel, features, parameters
};
} // namespace reductions

namespace details
{

float finalize_prediction(VW::shared_data* sd, VW::io::logger& logger, float ret);
void print_features(VW::workspace& all, VW::example& ec);
void print_audit_features(VW::workspace&, VW::example& ec);
void save_load_regressor(VW::workspace& all, VW::io_buf& model_file, bool read, bool text);
void save_load_online_state(VW::workspace& all, VW::io_buf& model_file, bool read, bool text, double& total_weight,
double& normalized_sum_norm_x, GD::gd* g = nullptr, uint32_t ftrl_size = 0);
void save_load_regressor_gd(VW::workspace& all, VW::io_buf& model_file, bool read, bool text);
void save_load_online_state_gd(VW::workspace& all, VW::io_buf& model_file, bool read, bool text, double& total_weight,
double& normalized_sum_norm_x, VW::reductions::gd* g = nullptr, uint32_t ftrl_size = 0);

template <class T>
class multipredict_info
Expand Down Expand Up @@ -99,6 +105,7 @@ inline void vec_add_multipredict(multipredict_info<T>& mp, const float fx, uint6
}
}
}
} // namespace details

// iterate through one namespace (or its part), callback function FuncT(some_data_R, feature_value_x, feature_weight)
template <class DataT, class WeightOrIndexT, void (*FuncT)(DataT&, float, WeightOrIndexT)>
Expand Down Expand Up @@ -180,7 +187,7 @@ inline float trunc_weight(const float w, const float gravity)
return (gravity < fabsf(w)) ? w - VW::math::sign(w) * gravity : 0.f;
}

} // namespace GD
} // namespace VW

namespace VW
{
Expand Down Expand Up @@ -239,3 +246,67 @@ inline void generate_interactions(VW::workspace& all, VW::example_predict& ec, R
}

} // namespace INTERACTIONS

namespace GD
{

using gd = VW::reductions::gd;

// iterate through one namespace (or its part), callback function FuncT(some_data_R, feature_value_x, feature_weight)
template <class DataT, class WeightOrIndexT, void (*FuncT)(DataT&, float, WeightOrIndexT)>
VW_DEPRECATED("Moved to VW namespace")
inline void foreach_feature(VW::workspace& all, VW::example& ec, DataT& dat)
{
VW::foreach_feature<DataT, WeightOrIndexT, FuncT>(all, ec, dat);
}

// iterate through one namespace (or its part), callback function FuncT(some_data_R, feature_value_x, feature_weight)
template <class DataT, class WeightOrIndexT, void (*FuncT)(DataT&, float, WeightOrIndexT)>
VW_DEPRECATED("Moved to VW namespace")
inline void foreach_feature(VW::workspace& all, VW::example& ec, DataT& dat, size_t& num_interacted_features)
{
VW::foreach_feature<DataT, WeightOrIndexT, FuncT>(all, ec, dat, num_interacted_features);
}

// iterate through all namespaces and quadratic&cubic features, callback function T(some_data_R, feature_value_x,
// feature_weight)
template <class DataT, void (*FuncT)(DataT&, float, float&)>
VW_DEPRECATED("Moved to VW namespace")
inline void foreach_feature(VW::workspace& all, VW::example& ec, DataT& dat)
{
VW::foreach_feature<DataT, float&, FuncT>(all, ec, dat);
}

template <class DataT, void (*FuncT)(DataT&, float, float)>
VW_DEPRECATED("Moved to VW namespace")
inline void foreach_feature(VW::workspace& all, VW::example& ec, DataT& dat)
{
VW::foreach_feature<DataT, float, FuncT>(all, ec, dat);
}

template <class DataT, void (*FuncT)(DataT&, float, float&)>
VW_DEPRECATED("Moved to VW namespace")
inline void foreach_feature(VW::workspace& all, VW::example& ec, DataT& dat, size_t& num_interacted_features)
{
VW::foreach_feature<DataT, float&, FuncT>(all, ec, dat, num_interacted_features);
}

template <class DataT, void (*FuncT)(DataT&, float, const float&)>
VW_DEPRECATED("Moved to VW namespace")
inline void foreach_feature(VW::workspace& all, VW::example& ec, DataT& dat, size_t& num_interacted_features)
{
VW::foreach_feature<DataT, const float&, FuncT>(all, ec, dat, num_interacted_features);
}

VW_DEPRECATED("Moved to VW namespace")
inline float inline_predict(VW::workspace& all, VW::example& ec) { return VW::inline_predict(all, ec); }

VW_DEPRECATED("Moved to VW namespace")
inline float inline_predict(VW::workspace& all, VW::example& ec, size_t& num_generated_features)
{
return VW::inline_predict(all, ec, num_generated_features);
}

VW_DEPRECATED("Moved to VW namespace")
inline float trunc_weight(const float w, const float gravity) { return VW::trunc_weight(w, gravity); }
} // namespace GD
2 changes: 1 addition & 1 deletion vowpalwabbit/core/src/example.cc
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ flat_example* flatten_example(VW::workspace& all, example* ec)
ffs.mask = all.weights.mask() >> all.weights.stride_shift();
}
else { ffs.mask = static_cast<uint64_t>(LONG_MAX) >> all.weights.stride_shift(); }
GD::foreach_feature<full_features_and_source, uint64_t, vec_ffs_store>(all, *ec, ffs);
VW::foreach_feature<full_features_and_source, uint64_t, vec_ffs_store>(all, *ec, ffs);

std::swap(fec.fs, ffs.fs);

Expand Down
2 changes: 1 addition & 1 deletion vowpalwabbit/core/src/reductions/automl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ VW::LEARNER::base_learner* make_automl_with_impl(VW::setup_base_i& stack_builder
auto ppw = max_live_configs;
auto* persist_ptr = verbose_metrics ? persist<config_manager_type, true> : persist<config_manager_type, false>;
data->adf_learner = as_multiline(base_learner->get_learner_by_name_prefix("cb_adf"));
GD::gd& gd = *static_cast<GD::gd*>(
VW::reductions::gd& gd = *static_cast<VW::reductions::gd*>(
base_learner->get_learner_by_name_prefix("gd")->get_internal_type_erased_data_pointer_test_use_only());
auto& adf_data =
*static_cast<VW::reductions::cb_adf*>(data->adf_learner->get_internal_type_erased_data_pointer_test_use_only());
Expand Down
14 changes: 7 additions & 7 deletions vowpalwabbit/core/src/reductions/bfgs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ constexpr bool test_example(VW::example& ec) noexcept { return ec.l.simple.label

float bfgs_predict(VW::workspace& all, VW::example& ec)
{
ec.partial_prediction = GD::inline_predict(all, ec);
return GD::finalize_prediction(all.sd, all.logger, ec.partial_prediction);
ec.partial_prediction = VW::inline_predict(all, ec);
return VW::details::finalize_prediction(all.sd, all.logger, ec.partial_prediction);
}

inline void add_grad(float& d, float f, float& fw) { (&fw)[W_GT] += d * f; }
Expand All @@ -175,7 +175,7 @@ float predict_and_gradient(VW::workspace& all, VW::example& ec)
all.set_minmax(all.sd, ld.label);

float loss_grad = all.loss->first_derivative(all.sd, fp, ld.label) * ec.weight;
GD::foreach_feature<float, add_grad>(all, ec, loss_grad);
VW::foreach_feature<float, add_grad>(all, ec, loss_grad);

return fp;
}
Expand All @@ -185,7 +185,7 @@ inline void add_precond(float& d, float f, float& fw) { (&fw)[W_COND] += d * f *
void update_preconditioner(VW::workspace& all, VW::example& ec)
{
float curvature = all.loss->second_derivative(all.sd, ec.pred.scalar, ec.l.simple.label) * ec.weight;
GD::foreach_feature<float, add_precond>(all, ec, curvature);
VW::foreach_feature<float, add_precond>(all, ec, curvature);
}

inline void add_dir(float& p, const float fx, float& fw) { p += (&fw)[W_DIR] * fx; }
Expand All @@ -194,7 +194,7 @@ float dot_with_direction(VW::workspace& all, VW::example& ec)
{
const auto& simple_red_features = ec.ex_reduction_features.template get<VW::simple_label_reduction_features>();
float temp = simple_red_features.initial;
GD::foreach_feature<float, add_dir>(all, ec, temp);
VW::foreach_feature<float, add_dir>(all, ec, temp);
return temp;
}

Expand Down Expand Up @@ -982,7 +982,7 @@ void predict(bfgs& b, base_learner&, VW::example& ec)
{
VW::workspace* all = b.all;
ec.pred.scalar = bfgs_predict(*all, ec);
if (audit) { GD::print_audit_features(*(b.all), ec); }
if (audit) { VW::details::print_audit_features(*(b.all), ec); }
}

template <bool audit>
Expand Down Expand Up @@ -1103,7 +1103,7 @@ void save_load(bfgs& b, VW::io_buf& model_file, bool read, bool text)
model_file, reinterpret_cast<char*>(&reg_vector), sizeof(reg_vector), read, msg, text);

if (reg_vector) { save_load_regularizer(*all, b, model_file, read, text); }
else { GD::save_load_regressor(*all, model_file, read, text); }
else { VW::details::save_load_regressor_gd(*all, model_file, read, text); }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ bool _test_only_generate_A(VW::workspace* _all, const multi_ex& examples, std::v
if (_all->weights.sparse)
{
A_triplet_constructor w(_all->weights.sparse_weights.mask(), row_index, _triplets, max_non_zero_col);
GD::foreach_feature<A_triplet_constructor, uint64_t, triplet_construction, sparse_parameters>(
VW::foreach_feature<A_triplet_constructor, uint64_t, triplet_construction, sparse_parameters>(
_all->weights.sparse_weights, _all->ignore_some_linear, _all->ignore_linear,
(red_features.generated_interactions ? *red_features.generated_interactions : *ex->interactions),
(red_features.generated_extent_interactions ? *red_features.generated_extent_interactions
Expand All @@ -83,7 +83,7 @@ bool _test_only_generate_A(VW::workspace* _all, const multi_ex& examples, std::v
{
A_triplet_constructor w(_all->weights.dense_weights.mask(), row_index, _triplets, max_non_zero_col);

GD::foreach_feature<A_triplet_constructor, uint64_t, triplet_construction, dense_parameters>(
VW::foreach_feature<A_triplet_constructor, uint64_t, triplet_construction, dense_parameters>(
_all->weights.dense_weights, _all->ignore_some_linear, _all->ignore_linear,
(red_features.generated_interactions ? *red_features.generated_interactions : *ex->interactions),
(red_features.generated_extent_interactions ? *red_features.generated_extent_interactions
Expand Down
Loading