Skip to content

Commit a487c2f

Browse files
authored
Merge cde8208 into bf4f55b
2 parents bf4f55b + cde8208 commit a487c2f

File tree

6 files changed

+55
-52
lines changed

6 files changed

+55
-52
lines changed

ydb/core/kqp/opt/logical/kqp_opt_log.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class TKqpLogicalOptTransformer : public TOptimizeTransformerBase {
9292
public:
9393
TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) override {
9494
auto status = TOptimizeTransformerBase::DoTransform(input, output, ctx);
95-
95+
9696
if (status == TStatus::Ok) {
9797
for (const auto& hint: KqpCtx.GetOptimizerHints().GetUnappliedString()) {
9898
ctx.AddWarning(YqlIssue({}, TIssuesIds::YQL_UNUSED_HINT, "Unapplied hint: " + hint));
@@ -118,7 +118,7 @@ class TKqpLogicalOptTransformer : public TOptimizeTransformerBase {
118118
TMaybeNode<TExprBase> RewriteAggregate(TExprBase node, TExprContext& ctx) {
119119
TMaybeNode<TExprBase> output;
120120
auto aggregate = node.Cast<TCoAggregateBase>();
121-
auto hopSetting = GetSetting(aggregate.Settings().Ref(), "hopping");
121+
auto hopSetting = GetSetting(aggregate.Settings().Ref(), "hopping");
122122
if (hopSetting) {
123123
auto input = aggregate.Input().Maybe<TDqConnection>();
124124
if (!input) {
@@ -163,8 +163,9 @@ class TKqpLogicalOptTransformer : public TOptimizeTransformerBase {
163163
TMaybeNode<TExprBase> OptimizeEquiJoinWithCosts(TExprBase node, TExprContext& ctx) {
164164
auto maxDPhypDPTableSize = Config->MaxDPHypDPTableSize.Get().GetOrElse(TDqSettings::TDefault::MaxDPHypDPTableSize);
165165
auto optLevel = Config->CostBasedOptimizationLevel.Get().GetOrElse(Config->DefaultCostBasedOptimizationLevel);
166+
bool enableShuffleElimination = KqpCtx.Config->OptShuffleElimination.Get().GetOrElse(false);;
166167
auto providerCtx = TKqpProviderContext(KqpCtx, optLevel);
167-
auto opt = std::unique_ptr<IOptimizerNew>(MakeNativeOptimizerNew(providerCtx, maxDPhypDPTableSize, ctx));
168+
auto opt = std::unique_ptr<IOptimizerNew>(MakeNativeOptimizerNew(providerCtx, maxDPhypDPTableSize, ctx, enableShuffleElimination));
168169
TExprBase output = DqOptimizeEquiJoinWithCosts(node, ctx, TypesCtx, optLevel,
169170
*opt, [](auto& rels, auto label, auto node, auto stat) {
170171
rels.emplace_back(std::make_shared<TKqpRelOptimizerNode>(TString(label), *stat, node));

ydb/library/yql/dq/opt/dq_opt_join_cbo_factory.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace {
1010
class TDqOptimizerFactory : public IOptimizerFactory {
1111
public:
1212
virtual IOptimizerNew::TPtr MakeJoinCostBasedOptimizerNative(IProviderContext& pctx, TExprContext& ectx, const TNativeSettings& settings) const override {
13-
return IOptimizerNew::TPtr(MakeNativeOptimizerNew(pctx, settings.MaxDPhypDPTableSize, ectx));
13+
return IOptimizerNew::TPtr(MakeNativeOptimizerNew(pctx, settings.MaxDPhypDPTableSize, ectx, false));
1414
}
1515

1616
virtual IOptimizerNew::TPtr MakeJoinCostBasedOptimizerPG(IProviderContext& pctx, TExprContext& ctx, const TPGSettings& settings) const override {

ydb/library/yql/dq/opt/dq_opt_join_cost_based.cpp

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -187,14 +187,14 @@ TExprBase BuildTree(TExprContext& ctx, const TCoEquiJoin& equiJoin,
187187
shuffleBy.reserve(optimizerNode->Stats.ShuffledByColumns->Data.size());
188188

189189
for (const auto& column: optimizerNode->Stats.ShuffledByColumns->Data) {
190-
auto node =
190+
auto node =
191191
ctx.Builder(equiJoin.Pos())
192192
.List()
193193
.Atom(0, column.RelName)
194194
.Atom(1, column.AttributeName)
195195
.Seal()
196196
.Build();
197-
197+
198198
shuffleBy.emplace_back(std::move(node));
199199
}
200200

@@ -204,7 +204,7 @@ TExprBase BuildTree(TExprContext& ctx, const TCoEquiJoin& equiJoin,
204204
case EShuffleSide::ERight: { shuffleSideOpt = "shuffle_rhs_by"; break;}
205205
}
206206

207-
auto option =
207+
auto option =
208208
Build<TExprList>(ctx, equiJoin.Pos())
209209
.Add<TCoAtom>()
210210
.Build(shuffleSideOpt)
@@ -267,10 +267,10 @@ void ComputeStatistics(const std::shared_ptr<TJoinOptimizerNode>& join, IProvide
267267
}
268268
join->Stats = TOptimizerStatistics(
269269
ctx.ComputeJoinStatsV1(
270-
join->LeftArg->Stats,
270+
join->LeftArg->Stats,
271271
join->RightArg->Stats,
272-
join->LeftJoinKeys,
273-
join->RightJoinKeys,
272+
join->LeftJoinKeys,
273+
join->RightJoinKeys,
274274
EJoinAlgoType::GraceJoin,
275275
join->JoinType,
276276
nullptr,
@@ -282,26 +282,27 @@ void ComputeStatistics(const std::shared_ptr<TJoinOptimizerNode>& join, IProvide
282282

283283
class TOptimizerNativeNew: public IOptimizerNew {
284284
public:
285-
TOptimizerNativeNew(IProviderContext& ctx, ui32 maxDPhypDPTableSize, TExprContext& exprCtx)
285+
TOptimizerNativeNew(IProviderContext& ctx, ui32 maxDPhypDPTableSize, TExprContext& exprCtx, bool enableShuffleElimination)
286286
: IOptimizerNew(ctx)
287287
, MaxDPHypTableSize_(maxDPhypDPTableSize)
288288
, ExprCtx(exprCtx)
289+
, EnableShuffleElimination(enableShuffleElimination)
289290
{}
290291

291292
std::shared_ptr<TJoinOptimizerNode> JoinSearch(
292-
const std::shared_ptr<TJoinOptimizerNode>& joinTree,
293+
const std::shared_ptr<TJoinOptimizerNode>& joinTree,
293294
const TOptimizerHints& hints = {}
294295
) override {
295296
auto relsCount = joinTree->Labels().size();
296297

297-
if (relsCount <= 14) {
298+
if (EnableShuffleElimination && relsCount <= 14) {
298299
return JoinSearchImpl<TNodeSet64, TDPHypSolverShuffleElimination<TNodeSet64>>(joinTree, false, hints);
299300
} else if (relsCount <= 64) { // The algorithm is more efficient.
300-
return JoinSearchImpl<TNodeSet64, TDPHypSolverClassic<TNodeSet64>>(joinTree, true, hints);
301+
return JoinSearchImpl<TNodeSet64, TDPHypSolverClassic<TNodeSet64>>(joinTree, EnableShuffleElimination, hints);
301302
} else if (64 < relsCount && relsCount <= 128) {
302-
return JoinSearchImpl<TNodeSet128, TDPHypSolverClassic<TNodeSet128>>(joinTree, true, hints);
303+
return JoinSearchImpl<TNodeSet128, TDPHypSolverClassic<TNodeSet128>>(joinTree, EnableShuffleElimination, hints);
303304
} else if (128 < relsCount && relsCount <= 192) {
304-
return JoinSearchImpl<TNodeSet192, TDPHypSolverClassic<TNodeSet192>>(joinTree, true, hints);
305+
return JoinSearchImpl<TNodeSet192, TDPHypSolverClassic<TNodeSet192>>(joinTree, EnableShuffleElimination, hints);
305306
}
306307

307308
ComputeStatistics(joinTree, this->Pctx);
@@ -314,7 +315,7 @@ class TOptimizerNativeNew: public IOptimizerNew {
314315
using TNodeSet192 = std::bitset<192>;
315316

316317
template <
317-
typename TNodeSet,
318+
typename TNodeSet,
318319
typename TDPHypImpl
319320
>
320321
std::shared_ptr<TJoinOptimizerNode> JoinSearchImpl(
@@ -379,7 +380,7 @@ class TOptimizerNativeNew: public IOptimizerNew {
379380
joinNode->LogicalOrderings = fsm.CreateState();
380381
switch (joinNode->JoinAlgo) {
381382
case EJoinAlgoType::GraceJoin: {
382-
bool hashFuncArgsMatch =
383+
bool hashFuncArgsMatch =
383384
left->LogicalOrderings.GetShuffleHashFuncArgsCount() == right->LogicalOrderings.GetShuffleHashFuncArgsCount();
384385

385386
if (!hashFuncArgsMatch || !left->LogicalOrderings.HasState() || !left->LogicalOrderings.ContainsShuffle(leftJoinKeysOrderingIdx)) {
@@ -433,10 +434,11 @@ class TOptimizerNativeNew: public IOptimizerNew {
433434
private:
434435
ui32 MaxDPHypTableSize_;
435436
TExprContext& ExprCtx;
437+
bool EnableShuffleElimination;
436438
};
437439

438-
IOptimizerNew* MakeNativeOptimizerNew(IProviderContext& pctx, const ui32 maxDPhypDPTableSize, TExprContext& ectx) {
439-
return new TOptimizerNativeNew(pctx, maxDPhypDPTableSize, ectx);
440+
IOptimizerNew* MakeNativeOptimizerNew(IProviderContext& pctx, const ui32 maxDPhypDPTableSize, TExprContext& ectx, bool enableShuffleElimination) {
441+
return new TOptimizerNativeNew(pctx, maxDPhypDPTableSize, ectx, enableShuffleElimination);
440442
}
441443

442444
TExprBase DqOptimizeEquiJoinWithCosts(
@@ -496,8 +498,8 @@ TExprBase DqOptimizeEquiJoinWithCosts(
496498
YQL_CLOG(TRACE, CoreDq) << "All statistics for join in place";
497499

498500
bool allRowStorage = std::all_of(
499-
rels.begin(),
500-
rels.end(),
501+
rels.begin(),
502+
rels.end(),
501503
[](std::shared_ptr<TRelOptimizerNode>& r) {return r->Stats.StorageType==EStorageType::RowStorage; });
502504

503505
if (optLevel == 2 && allRowStorage) {

ydb/library/yql/dq/opt/dq_opt_join_cost_based.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
#pragma once
22

3-
#include <yql/essentials/core/cbo/cbo_optimizer_new.h>
3+
#include <yql/essentials/core/cbo/cbo_optimizer_new.h>
44
#include <yql/essentials/core/expr_nodes_gen/yql_expr_nodes_gen.h>
55
#include <yql/essentials/core/yql_type_annotation.h>
66

77
namespace NYql::NDq {
88

9-
using TProviderCollectFunction =
9+
using TProviderCollectFunction =
1010
std::function<void(TVector<std::shared_ptr<TRelOptimizerNode>>&, TStringBuf, const TExprNode::TPtr, const std::shared_ptr<TOptimizerStatistics>&)>;
1111

1212
/*
@@ -38,6 +38,6 @@ NYql::NNodes::TExprBase DqOptimizeEquiJoinWithCosts(
3838
const TOptimizerHints& hints = {}
3939
);
4040

41-
IOptimizerNew* MakeNativeOptimizerNew(IProviderContext& ctx, const ui32 maxDPHypDPTableSize, TExprContext& ectx);
41+
IOptimizerNew* MakeNativeOptimizerNew(IProviderContext& ctx, const ui32 maxDPHypDPTableSize, TExprContext& ectx, bool enableShuffleElimination);
4242

4343
} // namespace NYql::NDq

ydb/library/yql/dq/opt/ut/dq_cbo_ut.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ Y_UNIT_TEST_SUITE(DQCBO) {
3434
Y_UNIT_TEST(Empty) {
3535
TBaseProviderContext pctx;
3636
TExprContext dummyCtx;
37-
std::unique_ptr<IOptimizerNew> optimizer = std::unique_ptr<IOptimizerNew>(MakeNativeOptimizerNew(pctx, 100000, dummyCtx));
37+
std::unique_ptr<IOptimizerNew> optimizer = std::unique_ptr<IOptimizerNew>(MakeNativeOptimizerNew(pctx, 100000, dummyCtx, false));
3838
}
3939

4040
Y_UNIT_TEST(JoinSearch2Rels) {
4141
TBaseProviderContext pctx;
4242
TExprContext dummyCtx;
43-
std::unique_ptr<IOptimizerNew> optimizer = std::unique_ptr<IOptimizerNew>(MakeNativeOptimizerNew(pctx, 100000, dummyCtx));
43+
std::unique_ptr<IOptimizerNew> optimizer = std::unique_ptr<IOptimizerNew>(MakeNativeOptimizerNew(pctx, 100000, dummyCtx, false));
4444

4545
auto rel1 = std::make_shared<TRelOptimizerNode>(
4646
"a",
@@ -83,7 +83,7 @@ Type: ManyManyJoin, Nrows: 2e+10, Ncols: 2, ByteSize: 0, Cost: 2.00112e+10, Sel:
8383
Y_UNIT_TEST(JoinSearch3Rels) {
8484
TBaseProviderContext pctx;
8585
TExprContext dummyCtx;
86-
std::unique_ptr<IOptimizerNew> optimizer = std::unique_ptr<IOptimizerNew>(MakeNativeOptimizerNew(pctx, 100000, dummyCtx));
86+
std::unique_ptr<IOptimizerNew> optimizer = std::unique_ptr<IOptimizerNew>(MakeNativeOptimizerNew(pctx, 100000, dummyCtx, false));
8787

8888
auto rel1 = std::make_shared<TRelOptimizerNode>("a",
8989
TOptimizerStatistics(BaseTable, 100000, 1, 0, 1000000));
@@ -246,7 +246,7 @@ Y_UNIT_TEST(DqOptimizeEquiJoinWithCostsNative) {
246246
TExprContext ctx;
247247
TBaseProviderContext pctx;
248248
std::function<IOptimizerNew*()> optFactory = [&]() {
249-
return MakeNativeOptimizerNew(pctx, 100000, ctx);
249+
return MakeNativeOptimizerNew(pctx, 100000, ctx, false);
250250
};
251251
_DqOptimizeEquiJoinWithCosts(optFactory, ctx);
252252
}

ydb/library/yql/dq/opt/ut/dq_opt_hypergraph_ut.cpp

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ struct TTestContext : public TBaseProviderContext {
4242
const TVector<NDq::TJoinColumn>& ,
4343
const TVector<NDq::TJoinColumn>& ,
4444
EJoinAlgoType ,
45-
EJoinKind
45+
EJoinKind
4646
) override {
4747
return true;
4848
}
@@ -53,8 +53,8 @@ std::shared_ptr<IBaseOptimizerNode> Enumerate(const std::shared_ptr<IBaseOptimiz
5353
auto ctx = TProviderContext();
5454
TExprContext dummyCtx;
5555
auto optimizer =
56-
std::unique_ptr<IOptimizerNew>(MakeNativeOptimizerNew(ctx, std::numeric_limits<ui32>::max(), dummyCtx));
57-
56+
std::unique_ptr<IOptimizerNew>(MakeNativeOptimizerNew(ctx, std::numeric_limits<ui32>::max(), dummyCtx, false));
57+
5858
Y_ENSURE(root->Kind == EOptimizerNodeKind::JoinNodeType);
5959
auto res = optimizer->JoinSearch(std::static_pointer_cast<TJoinOptimizerNode>(root), hints);
6060
Cout << "Optimized Tree:" << Endl;
@@ -76,25 +76,25 @@ TVector<TJoinColumn> CollectConditions(const std::shared_ptr<IBaseOptimizerNode>
7676
lhsConds.push_back(lhsCond);
7777
lhsConds.push_back(rhsCond);
7878
}
79-
79+
8080
return lhsConds;
8181
}
8282

8383
bool HaveSameConditions(const std::shared_ptr<IBaseOptimizerNode>& actual, std::shared_ptr<IBaseOptimizerNode> expected) {
8484
auto actualConds = CollectConditions(actual);
8585
auto expectedConds = CollectConditions(expected);
8686

87-
return
88-
std::unordered_set<TJoinColumn, TJoinColumn::THashFunction>(actualConds.begin(), actualConds.end()) ==
87+
return
88+
std::unordered_set<TJoinColumn, TJoinColumn::THashFunction>(actualConds.begin(), actualConds.end()) ==
8989
std::unordered_set<TJoinColumn, TJoinColumn::THashFunction>(expectedConds.begin(), expectedConds.end());
9090
}
9191

9292
bool HaveSameConditionCount(const std::shared_ptr<IBaseOptimizerNode>& actual, std::shared_ptr<IBaseOptimizerNode> expected) {
9393
auto actualConds = CollectConditions(actual);
9494
auto expectedConds = CollectConditions(expected);
95-
95+
9696
return actualConds.size() == expectedConds.size() &&
97-
std::unordered_set<TJoinColumn, TJoinColumn::THashFunction>(actualConds.begin(), actualConds.end()).size() ==
97+
std::unordered_set<TJoinColumn, TJoinColumn::THashFunction>(actualConds.begin(), actualConds.end()).size() ==
9898
std::unordered_set<TJoinColumn, TJoinColumn::THashFunction>(expectedConds.begin(), expectedConds.end()).size();
9999
}
100100

@@ -107,7 +107,7 @@ Y_UNIT_TEST_SUITE(HypergraphBuild) {
107107

108108
for (size_t i = 0; i < nodeCount; ++i) {
109109
for (size_t j = 0; j < nodeCount; ++j) {
110-
if (i == j) continue;
110+
if (i == j) continue;
111111

112112
TNodeSet64 lhs; lhs[i] = 1;
113113
TNodeSet64 rhs; rhs[j] = 1;
@@ -122,17 +122,17 @@ Y_UNIT_TEST_SUITE(HypergraphBuild) {
122122

123123
UNIT_ASSERT(graph.GetEdges().size() == 6);
124124

125-
CheckClique(graph);
125+
CheckClique(graph);
126126
Enumerate(root);
127127
}
128128

129129
Y_UNIT_TEST(SimpleChain4NodesTransitiveClosure) {
130130
auto root = CreateChain(4, "Ya hochu pitsu");
131131
auto graph = MakeJoinHypergraph<TNodeSet64>(root);
132-
132+
133133
UNIT_ASSERT(graph.GetEdges().size() == 12);
134134

135-
CheckClique(graph);
135+
CheckClique(graph);
136136
Enumerate(root);
137137
}
138138

@@ -142,7 +142,7 @@ Y_UNIT_TEST_SUITE(HypergraphBuild) {
142142

143143
UNIT_ASSERT(graph.GetEdges().size() == 20);
144144

145-
CheckClique(graph);
145+
CheckClique(graph);
146146
Enumerate(root);
147147
}
148148

@@ -166,7 +166,7 @@ Y_UNIT_TEST_SUITE(HypergraphBuild) {
166166

167167
rhs = CreateChain(2, "228", "c");
168168

169-
// a1 --228-- a2 --228-- a3 --1337-- b1 --1337-- b2 --123-- c1 --228-- c2
169+
// a1 --228-- a2 --228-- a3 --1337-- b1 --1337-- b2 --123-- c1 --228-- c2
170170
// ^ we don't want to have transitive closure between c and a
171171
root = std::make_shared<TJoinOptimizerNode>(
172172
root, rhs, leftKeys, rightKeys, EJoinKind::InnerJoin, EJoinAlgoType::Undefined, false, false
@@ -211,7 +211,7 @@ Y_UNIT_TEST_SUITE(HypergraphBuild) {
211211
return root;
212212
} else {
213213
static_assert(
214-
std::is_convertible_v<TJoinArg, std::string> || std::is_same_v<TJoinArg, std::shared_ptr<IBaseOptimizerNode>>,
214+
std::is_convertible_v<TJoinArg, std::string> || std::is_same_v<TJoinArg, std::shared_ptr<IBaseOptimizerNode>>,
215215
"Args of join must be either Join or TString, for example: Join(Join('A', 'B'), 'C')"
216216
);
217217
}
@@ -252,7 +252,7 @@ Y_UNIT_TEST_SUITE(HypergraphBuild) {
252252
TString attr = ToString(rand());
253253
leftJoinCond.push_back(TJoinColumn(std::move(lhsCond), attr));
254254
rightJoinCond.push_back(TJoinColumn(std::move(rhsCond), attr));
255-
255+
256256
}
257257
}
258258

@@ -288,7 +288,7 @@ Y_UNIT_TEST_SUITE(HypergraphBuild) {
288288

289289
Y_UNIT_TEST(SimpleDimpleJoin) {
290290
auto join = Join("A", "B");
291-
291+
292292
auto graph = MakeJoinHypergraph<TNodeSet64>(join);
293293
Cout << graph.String() << Endl;
294294

@@ -301,7 +301,7 @@ Y_UNIT_TEST_SUITE(HypergraphBuild) {
301301

302302
auto graph = MakeJoinHypergraph<TNodeSet64>(root);
303303
Cout << graph.String() << Endl;
304-
304+
305305
auto A = graph.GetNodesByRelNames({"A"});
306306
auto B = graph.GetNodesByRelNames({"B"});
307307
auto C = graph.GetNodesByRelNames({"C"});
@@ -318,7 +318,7 @@ Y_UNIT_TEST_SUITE(HypergraphBuild) {
318318
auto anyJoin = Join(Join("A", "B"), "C", /*on=*/ "B=C");
319319
std::static_pointer_cast<TJoinOptimizerNode>(anyJoin)->LeftAny = true;
320320
auto join = Join(anyJoin, "D", /*on=*/"A=D");
321-
321+
322322
auto graph = MakeJoinHypergraph<TNodeSet64>(join);
323323
Cout << graph.String() << Endl;
324324
UNIT_ASSERT(graph.GetEdges().size() != graph.GetSimpleEdges().size());
@@ -331,7 +331,7 @@ Y_UNIT_TEST_SUITE(HypergraphBuild) {
331331
auto anyJoin = Join(Join(Join("A", "B"), "C", /*on=*/ "B=C"), "D", "C=D");
332332
std::static_pointer_cast<TJoinOptimizerNode>(anyJoin)->LeftAny = true;
333333
auto join = Join(anyJoin, "E", /*on=*/ "A=E");
334-
334+
335335
auto graph = MakeJoinHypergraph<TNodeSet64>(join);
336336
Cout << graph.String() << Endl;
337337
UNIT_ASSERT(graph.GetEdges().size() != graph.GetSimpleEdges().size());
@@ -343,7 +343,7 @@ Y_UNIT_TEST_SUITE(HypergraphBuild) {
343343
auto anyJoin = Join(Join("A", "B"), Join("C", "D"), /*on=*/"B=C");
344344
std::static_pointer_cast<TJoinOptimizerNode>(anyJoin)->RightAny = true;
345345
auto join = Join(anyJoin, "E", /*on=*/ "C=E");
346-
346+
347347
auto graph = MakeJoinHypergraph<TNodeSet64>(join);
348348
Cout << graph.String() << Endl;
349349
UNIT_ASSERT(graph.GetEdges().size() != graph.GetSimpleEdges().size());
@@ -355,7 +355,7 @@ Y_UNIT_TEST_SUITE(HypergraphBuild) {
355355
auto nonReorderable = Join(Join(Join("A", "B"), "C", /*on=*/ "B=C"), "D", "C=D");
356356
std::static_pointer_cast<TJoinOptimizerNode>(nonReorderable)->IsReorderable = false;
357357
auto join = Join(nonReorderable, "E", /*on=*/ "A=E");
358-
358+
359359
auto graph = MakeJoinHypergraph<TNodeSet64>(join);
360360
Cout << graph.String() << Endl;
361361
UNIT_ASSERT(graph.GetEdges().size() != graph.GetSimpleEdges().size());
@@ -556,7 +556,7 @@ Y_UNIT_TEST_SUITE(HypergraphBuild) {
556556
return res;
557557
};
558558

559-
auto mean = [](const TVector<double>& v) -> double {
559+
auto mean = [](const TVector<double>& v) -> double {
560560
double sum = std::accumulate(v.begin(), v.end(), 0.0);
561561
return sum / static_cast<double>(v.size());
562562
};

0 commit comments

Comments
 (0)