analytical_engine/apps/pregel/pagerank_pregel.h (72 lines of code) (raw):
/** Copyright 2020 Alibaba Group Holding Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANALYTICAL_ENGINE_APPS_PREGEL_PAGERANK_PREGEL_H_
#define ANALYTICAL_ENGINE_APPS_PREGEL_PAGERANK_PREGEL_H_
#include <limits>
#include "vineyard/graph/fragment/arrow_fragment.h"
#include "core/app/pregel/i_vertex_program.h"
#include "core/app/pregel/pregel_compute_context.h"
#include "core/app/pregel/pregel_property_app_base.h"
namespace gs {
class PregelPagerank
: public IPregelProgram<
PregelPropertyVertex<
vineyard::ArrowFragment<vineyard::property_graph_types::OID_TYPE,
vineyard::property_graph_types::VID_TYPE>,
double, double>,
PregelPropertyComputeContext<
vineyard::ArrowFragment<vineyard::property_graph_types::OID_TYPE,
vineyard::property_graph_types::VID_TYPE>,
double, double>> {
using fragment_t =
vineyard::ArrowFragment<vineyard::property_graph_types::OID_TYPE,
vineyard::property_graph_types::VID_TYPE>;
public:
void Init(PregelPropertyVertex<fragment_t, double, double>& v,
PregelPropertyComputeContext<fragment_t, double, double>& context)
override {
v.set_value(1.0 / context.get_total_vertices_num());
}
void Compute(grape::IteratorPair<double*> messages,
PregelPropertyVertex<fragment_t, double, double>& v,
PregelPropertyComputeContext<fragment_t, double, double>&
context) override {
double delta = std::stod(context.get_config("delta"));
int max_round = std::stoi(context.get_config("max_round"));
if (context.superstep() >= 1) {
double sum = 0.0;
for (auto msg : messages) {
sum += msg;
}
v.set_value(delta * sum +
((1 - delta) / context.get_total_vertices_num()));
}
if (context.superstep() < max_round) {
size_t od_num = 0;
for (int label_id = 0; label_id < context.edge_label_num(); label_id++) {
od_num += v.outgoing_edges(label_id).size();
}
if (od_num != 0) {
double msg = v.value() / od_num;
for (int label_id = 0; label_id < context.edge_label_num();
label_id++) {
for (auto& e : v.outgoing_edges(label_id)) {
v.send(e.vertex(), msg);
}
}
}
} else {
v.vote_to_halt();
}
}
};
class PregelPagerankCombinator : public ICombinator<double> {
public:
double CombineMessages(MessageIterator<double> messages) {
double ret = 0.0;
for (auto msg : messages) {
ret += msg;
}
return ret;
}
};
} // namespace gs
#endif // ANALYTICAL_ENGINE_APPS_PREGEL_PAGERANK_PREGEL_H_