blob: 2b054d9b2b76dd623ccc829db01043464e656fe1 [file]
/* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
package org.apache.sysds.lops.rewrite;
import org.apache.sysds.lops.Lop;
import org.apache.sysds.parser.DMLProgram;
import org.apache.sysds.parser.ForStatement;
import org.apache.sysds.parser.ForStatementBlock;
import org.apache.sysds.parser.FunctionStatement;
import org.apache.sysds.parser.FunctionStatementBlock;
import org.apache.sysds.parser.IfStatement;
import org.apache.sysds.parser.IfStatementBlock;
import org.apache.sysds.parser.StatementBlock;
import org.apache.sysds.parser.WhileStatement;
import org.apache.sysds.parser.WhileStatementBlock;
import java.util.ArrayList;
import java.util.List;
public class LopRewriter
{
private ArrayList<LopRewriteRule> _lopSBRuleSet = null;
public LopRewriter() {
_lopSBRuleSet = new ArrayList<>();
// Add rewrite rules (single and multi-statement block)
_lopSBRuleSet.add(new RewriteAddPrefetchLop());
_lopSBRuleSet.add(new RewriteAddBroadcastLop());
_lopSBRuleSet.add(new RewriteAddChkpointLop());
_lopSBRuleSet.add(new RewriteAddChkpointInLoop());
_lopSBRuleSet.add(new RewriteUpdateGPUPlacements());
// TODO: A rewrite pass to remove less effective chkpoints
// Last rewrite to reset Lop IDs in a depth-first manner
_lopSBRuleSet.add(new RewriteFixIDs());
}
public void rewriteProgramLopDAGs(DMLProgram dmlp) {
for (String namespaceKey : dmlp.getNamespaces().keySet())
// for each namespace, handle function statement blocks
for (String fname : dmlp.getFunctionStatementBlocks(namespaceKey).keySet()) {
FunctionStatementBlock fsblock = dmlp.getFunctionStatementBlock(namespaceKey,fname);
rewriteLopDAGsFunction(fsblock);
}
if (!_lopSBRuleSet.isEmpty()) {
ArrayList<StatementBlock> sbs = rRewriteLops(dmlp.getStatementBlocks());
dmlp.setStatementBlocks(sbs);
}
}
public void rewriteLopDAGsFunction(FunctionStatementBlock fsb) {
if( !_lopSBRuleSet.isEmpty() )
rRewriteLop(fsb);
}
public ArrayList<Lop> rewriteLopDAG(StatementBlock sb, ArrayList<Lop> lops) {
//StatementBlock sb = new StatementBlock();
sb.setLops(lops);
return rRewriteLop(sb).get(0).getLops();
}
public ArrayList<StatementBlock> rRewriteLops(ArrayList<StatementBlock> sbs) {
// Apply rewrite rules to the lops of the list of statement blocks
List<StatementBlock> tmp = sbs;
for(LopRewriteRule r : _lopSBRuleSet)
tmp = r.rewriteLOPinStatementBlocks(tmp);
// Recursively rewrite lops in statement blocks
List<StatementBlock> tmp2 = new ArrayList<>();
for( StatementBlock sb : tmp )
tmp2.addAll(rRewriteLop(sb));
// Prepare output list
sbs.clear();
sbs.addAll(tmp2);
return sbs;
}
public ArrayList<StatementBlock> rRewriteLop(StatementBlock sb) {
ArrayList<StatementBlock> ret = new ArrayList<>();
ret.add(sb);
// Recursive invocation
if (sb instanceof FunctionStatementBlock) {
FunctionStatementBlock fsb = (FunctionStatementBlock)sb;
FunctionStatement fstmt = (FunctionStatement)fsb.getStatement(0);
fstmt.setBody(rRewriteLops(fstmt.getBody()));
}
else if (sb instanceof WhileStatementBlock) {
WhileStatementBlock wsb = (WhileStatementBlock) sb;
WhileStatement wstmt = (WhileStatement)wsb.getStatement(0);
wstmt.setBody(rRewriteLops(wstmt.getBody()));
}
else if (sb instanceof IfStatementBlock) {
IfStatementBlock isb = (IfStatementBlock) sb;
IfStatement istmt = (IfStatement)isb.getStatement(0);
istmt.setIfBody(rRewriteLops(istmt.getIfBody()));
istmt.setElseBody(rRewriteLops(istmt.getElseBody()));
}
else if (sb instanceof ForStatementBlock) { //incl parfor
//TODO: parfor statement blocks
ForStatementBlock fsb = (ForStatementBlock) sb;
ForStatement fstmt = (ForStatement)fsb.getStatement(0);
fstmt.setBody(rRewriteLops(fstmt.getBody()));
}
// Apply rewrite rules to individual statement blocks
for(LopRewriteRule r : _lopSBRuleSet) {
ArrayList<StatementBlock> tmp = new ArrayList<>();
for( StatementBlock sbc : ret )
tmp.addAll( r.rewriteLOPinStatementBlock(sbc) );
// Take over set of rewritten sbs
ret.clear();
ret.addAll(tmp);
}
return ret;
}
}