souffle  2.0.2-371-g6315b36
Parallel.cpp
Go to the documentation of this file.
1 /*
2  * Souffle - A Datalog Compiler
3  * Copyright (c) 2018, The Souffle Developers. All rights reserved
4  * Licensed under the Universal Permissive License v 1.0 as shown at:
5  * - https://opensource.org/licenses/UPL
6  * - <souffle root>/licenses/SOUFFLE-UPL.txt
7  */
8 
9 /************************************************************************
10  *
11  * @file Parallel.cpp
12  *
13  ***********************************************************************/
14 
15 #include "ram/transform/Parallel.h"
16 #include "ram/Condition.h"
17 #include "ram/Expression.h"
18 #include "ram/Node.h"
19 #include "ram/Operation.h"
20 #include "ram/Program.h"
21 #include "ram/Relation.h"
22 #include "ram/Statement.h"
23 #include "ram/utility/Visitor.h"
25 #include <functional>
26 #include <memory>
27 #include <utility>
28 #include <vector>
29 
30 namespace souffle::ram::transform {
31 
32 bool ParallelTransformer::parallelizeOperations(Program& program) {
33  bool changed = false;
34 
35  // parallelize the most outer loop only
36  // most outer loops can be scan/choice/indexScan/indexChoice
37  visitDepthFirst(program, [&](const Query& query) {
38  std::function<Own<Node>(Own<Node>)> parallelRewriter = [&](Own<Node> node) -> Own<Node> {
39  if (const Scan* scan = dynamic_cast<Scan*>(node.get())) {
40  const Relation& rel = relAnalysis->lookup(scan->getRelation());
41  if (scan->getTupleId() == 0 && rel.getArity() > 0) {
42  if (!isA<Project>(&scan->getOperation())) {
43  changed = true;
44  return mk<ParallelScan>(scan->getRelation(), scan->getTupleId(),
45  souffle::clone(&scan->getOperation()), scan->getProfileText());
46  }
47  }
48  } else if (const Choice* choice = dynamic_cast<Choice*>(node.get())) {
49  if (choice->getTupleId() == 0) {
50  changed = true;
51  return mk<ParallelChoice>(choice->getRelation(), choice->getTupleId(),
52  souffle::clone(&choice->getCondition()), souffle::clone(&choice->getOperation()),
53  choice->getProfileText());
54  }
55  } else if (const IndexScan* indexScan = dynamic_cast<IndexScan*>(node.get())) {
56  if (indexScan->getTupleId() == 0) {
57  changed = true;
58  RamPattern queryPattern = clone(indexScan->getRangePattern());
59  return mk<ParallelIndexScan>(indexScan->getRelation(), indexScan->getTupleId(),
60  std::move(queryPattern), souffle::clone(&indexScan->getOperation()),
61  indexScan->getProfileText());
62  }
63  } else if (const IndexChoice* indexChoice = dynamic_cast<IndexChoice*>(node.get())) {
64  if (indexChoice->getTupleId() == 0) {
65  changed = true;
66  RamPattern queryPattern = clone(indexChoice->getRangePattern());
67  return mk<ParallelIndexChoice>(indexChoice->getRelation(), indexChoice->getTupleId(),
68  souffle::clone(&indexChoice->getCondition()), std::move(queryPattern),
69  souffle::clone(&indexChoice->getOperation()), indexChoice->getProfileText());
70  }
71  } else if (const Aggregate* aggregate = dynamic_cast<Aggregate*>(node.get())) {
72  const Relation& rel = relAnalysis->lookup(aggregate->getRelation());
73  if (aggregate->getTupleId() == 0 && !rel.isNullary()) {
74  changed = true;
75  return mk<ParallelAggregate>(Own<Operation>(aggregate->getOperation().clone()),
76  aggregate->getFunction(), aggregate->getRelation(),
77  Own<Expression>(aggregate->getExpression().clone()),
78  Own<Condition>(aggregate->getCondition().clone()), aggregate->getTupleId());
79  }
80  } else if (const IndexAggregate* indexAggregate = dynamic_cast<IndexAggregate*>(node.get())) {
81  const Relation& rel = relAnalysis->lookup(indexAggregate->getRelation());
82  if (indexAggregate->getTupleId() == 0 && !rel.isNullary()) {
83  changed = true;
84  RamPattern queryPattern = clone(indexAggregate->getRangePattern());
85  return mk<ParallelIndexAggregate>(Own<Operation>(indexAggregate->getOperation().clone()),
86  indexAggregate->getFunction(), indexAggregate->getRelation(),
87  Own<Expression>(indexAggregate->getExpression().clone()),
88  Own<Condition>(indexAggregate->getCondition().clone()), std::move(queryPattern),
89  indexAggregate->getTupleId());
90  }
91  }
92  node->apply(makeLambdaRamMapper(parallelRewriter));
93  return node;
94  };
95  const_cast<Query*>(&query)->apply(makeLambdaRamMapper(parallelRewriter));
96  });
97  return changed;
98 }
99 
100 } // namespace souffle::ram::transform
souffle::ram::transform
Definition: ChoiceConversion.cpp:30
souffle::ram::Query
A relational algebra query.
Definition: Query.h:50
souffle::ram::transform::Transformer::apply
bool apply(TranslationUnit &translationUnit)
@Brief apply the transformer to a translation unit @Param translationUnit that will be transformed.
Definition: Transformer.cpp:39
souffle::Own
std::unique_ptr< A > Own
Definition: ContainerUtil.h:42
MiscUtil.h
souffle::ram::transform::ParallelTransformer::parallelizeOperations
bool parallelizeOperations(Program &program)
Parallelize operations.
Definition: Parallel.cpp:36
Program.h
Visitor.h
souffle::clone
auto clone(const std::vector< A * > &xs)
Definition: ContainerUtil.h:172
souffle::ram::Relation
An abstract class for performing indexed operations.
Definition: Relation.h:40
Relation.h
souffle::ram::Aggregate
Aggregation function applied on some relation.
Definition: Aggregate.h:53
Condition.h
souffle::ram::IndexChoice
Use an index to find a tuple in a relation such that a given condition holds.
Definition: IndexChoice.h:58
souffle::ram::IndexAggregate
Indexed aggregation on a relation. The index allows us to iterate over a restricted range.
Definition: IndexAggregate.h:51
souffle::ram::Choice
Find a tuple in a relation such that a given condition holds.
Definition: Choice.h:59
souffle::ram::Scan
Iterate all tuples of a relation.
Definition: Scan.h:47
souffle::ram::IndexScan
Search for tuples of a relation matching a criteria.
Definition: IndexScan.h:52
Node.h
Operation.h
souffle::ram::RamPattern
std::pair< RamBound, RamBound > RamPattern
Definition: IndexOperation.h:42
Statement.h
Parallel.h
Expression.h
souffle::ram::transform::ParallelTransformer::relAnalysis
analysis::RelationAnalysis * relAnalysis
Definition: Parallel.h:68
souffle::ram::analysis::RelationAnalysis::lookup
const ram::Relation & lookup(const std::string &name) const
Definition: Relation.cpp:33
souffle::ram::visitDepthFirst
void visitDepthFirst(const Node &root, Visitor< R, Ps... > &visitor, Args &... args)
A utility function visiting all nodes within the RAM fragments rooted by the given node recursively i...
Definition: Visitor.h:357
rel
void rel(size_t limit, bool showLimit=true)
Definition: Tui.h:1086
souffle::ram::makeLambdaRamMapper
LambdaNodeMapper< Lambda > makeLambdaRamMapper(const Lambda &lambda)
Creates a node mapper based on a corresponding lambda expression.
Definition: LambdaNodeMapper.h:67