Repository: incubator-systemml Updated Branches: refs/heads/master 149562eca -> 0d625a05e
[SYSTEMML-1525,1526] Fix codegen size propagation and cplan cleanup This patch fixes the output size propagation of row and multi-aggregate templates as well as plan cleanups of multi-aggregate templates where the output nodes themselves can be indexing operations. Project: http://git-wip-us.apache.org/repos/asf/incubator-systemml/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-systemml/commit/1cd62866 Tree: http://git-wip-us.apache.org/repos/asf/incubator-systemml/tree/1cd62866 Diff: http://git-wip-us.apache.org/repos/asf/incubator-systemml/diff/1cd62866 Branch: refs/heads/master Commit: 1cd62866b7848bdb5eeded39259cd23b0ff172c8 Parents: 149562e Author: Matthias Boehm <[email protected]> Authored: Fri Apr 14 20:57:51 2017 -0700 Committer: Matthias Boehm <[email protected]> Committed: Fri Apr 14 20:57:51 2017 -0700 ---------------------------------------------------------------------- .../sysml/hops/codegen/SpoofCompiler.java | 53 +++++++++++++------- .../apache/sysml/hops/codegen/SpoofFusedOp.java | 5 ++ .../sysml/hops/codegen/cplan/CNodeMultiAgg.java | 2 +- .../sysml/hops/codegen/cplan/CNodeRow.java | 11 ++-- .../hops/codegen/template/TemplateUtils.java | 13 ++++- 5 files changed, 61 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/1cd62866/src/main/java/org/apache/sysml/hops/codegen/SpoofCompiler.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/codegen/SpoofCompiler.java b/src/main/java/org/apache/sysml/hops/codegen/SpoofCompiler.java index 1f0644b..43b88b0 100644 --- a/src/main/java/org/apache/sysml/hops/codegen/SpoofCompiler.java +++ b/src/main/java/org/apache/sysml/hops/codegen/SpoofCompiler.java @@ -583,21 +583,10 @@ public class SpoofCompiler tmp.toArray(new Hop[0]),tpl)); } - //remove spurious lookups on main input of cell template - if( tpl instanceof CNodeCell || tpl instanceof CNodeOuterProduct ) { - CNodeData in1 = (CNodeData)tpl.getInput().get(0); - rFindAndRemoveLookup(tpl.getOutput(), in1); - } - else if( tpl instanceof CNodeMultiAgg ) { - CNodeData in1 = (CNodeData)tpl.getInput().get(0); - for( CNode output : ((CNodeMultiAgg)tpl).getOutputs() ) - rFindAndRemoveLookup(output, in1); - } - //remove invalid plans with column indexing on main input if( tpl instanceof CNodeCell ) { CNodeData in1 = (CNodeData)tpl.getInput().get(0); - if( rHasLookupRC1(tpl.getOutput(), in1) ) { + if( rHasLookupRC1(tpl.getOutput(), in1) || isLookupRC1(tpl.getOutput(), in1) ) { cplans2.remove(e.getKey()); if( LOG.isTraceEnabled() ) LOG.trace("Removed cplan due to invalid rc1 indexing on main input."); @@ -606,16 +595,26 @@ public class SpoofCompiler else if( tpl instanceof CNodeMultiAgg ) { CNodeData in1 = (CNodeData)tpl.getInput().get(0); for( CNode output : ((CNodeMultiAgg)tpl).getOutputs() ) - if( rHasLookupRC1(output, in1) ) { + if( rHasLookupRC1(output, in1) || isLookupRC1(output, in1) ) { cplans2.remove(e.getKey()); if( LOG.isTraceEnabled() ) LOG.trace("Removed cplan due to invalid rc1 indexing on main input."); } } + //remove spurious lookups on main input of cell template + if( tpl instanceof CNodeCell || tpl instanceof CNodeOuterProduct ) { + CNodeData in1 = (CNodeData)tpl.getInput().get(0); + rFindAndRemoveLookup(tpl.getOutput(), in1); + } + else if( tpl instanceof CNodeMultiAgg ) { + CNodeData in1 = (CNodeData)tpl.getInput().get(0); + rFindAndRemoveLookupMultiAgg((CNodeMultiAgg)tpl, in1); + } + //remove cplan w/ single op and w/o agg - if( tpl instanceof CNodeCell && ((CNodeCell)tpl).getCellType()==CellType.NO_AGG - && TemplateUtils.hasSingleOperation(tpl) ) + if( tpl instanceof CNodeCell && ((((CNodeCell)tpl).getCellType()==CellType.NO_AGG + && TemplateUtils.hasSingleOperation(tpl))|| TemplateUtils.hasNoOperation(tpl)) ) cplans2.remove(e.getKey()); //remove cplan if empty @@ -636,6 +635,20 @@ public class SpoofCompiler rCollectLeafIDs(c, leafs); } + private static void rFindAndRemoveLookupMultiAgg(CNodeMultiAgg node, CNodeData mainInput) { + //process all outputs individually + for( CNode output : node.getOutputs() ) + rFindAndRemoveLookup(output, mainInput); + + //handle special case, of lookup being itself the output node + for( int i=0; i < node.getOutputs().size(); i++) { + CNode tmp = node.getOutputs().get(i); + if( TemplateUtils.isLookup(tmp) && tmp.getInput().get(0) instanceof CNodeData + && ((CNodeData)tmp.getInput().get(0)).getHopID()==mainInput.getHopID() ) + node.getOutputs().set(i, tmp.getInput().get(0)); + } + } + private static void rFindAndRemoveLookup(CNode node, CNodeData mainInput) { for( int i=0; i<node.getInput().size(); i++ ) { CNode tmp = node.getInput().get(i); @@ -653,9 +666,7 @@ public class SpoofCompiler boolean ret = false; for( int i=0; i<node.getInput().size() && !ret; i++ ) { CNode tmp = node.getInput().get(i); - if( tmp instanceof CNodeTernary && ((CNodeTernary)tmp).getType()==TernaryType.LOOKUP_RC1 - && tmp.getInput().get(0) instanceof CNodeData - && ((CNodeData)tmp.getInput().get(0)).getHopID() == mainInput.getHopID()) + if( isLookupRC1(tmp, mainInput) ) ret = true; else ret |= rHasLookupRC1(tmp, mainInput); @@ -663,6 +674,12 @@ public class SpoofCompiler return ret; } + private static boolean isLookupRC1(CNode node, CNodeData mainInput) { + return (node instanceof CNodeTernary && ((CNodeTernary)node).getType()==TernaryType.LOOKUP_RC1 + && node.getInput().get(0) instanceof CNodeData + && ((CNodeData)node.getInput().get(0)).getHopID() == mainInput.getHopID()); + } + /** * This plan cache maps CPlans to compiled and loaded classes in order * to reduce javac and JIT compilation overhead. It uses a simple LRU http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/1cd62866/src/main/java/org/apache/sysml/hops/codegen/SpoofFusedOp.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/codegen/SpoofFusedOp.java b/src/main/java/org/apache/sysml/hops/codegen/SpoofFusedOp.java index 357d41c..89d205b 100644 --- a/src/main/java/org/apache/sysml/hops/codegen/SpoofFusedOp.java +++ b/src/main/java/org/apache/sysml/hops/codegen/SpoofFusedOp.java @@ -41,6 +41,7 @@ public class SpoofFusedOp extends Hop implements MultiThreadedHop COLUMN_DIMS_ROWS, COLUMN_DIMS_COLS, SCALAR, + MULTI_SCALAR, ROW_RANK_DIMS, // right wdivmm COLUMN_RANK_DIMS // left wdivmm } @@ -160,6 +161,10 @@ public class SpoofFusedOp extends Hop implements MultiThreadedHop setDim1(0); setDim2(0); break; + case MULTI_SCALAR: + setDim1(1); //row vector + //dim2 statically set from outside + break; case ROW_RANK_DIMS: setDim1(getInput().get(0).getDim1()); setDim2(getInput().get(1).getDim2()); http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/1cd62866/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeMultiAgg.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeMultiAgg.java b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeMultiAgg.java index 95e1f75..aa84a00 100644 --- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeMultiAgg.java +++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeMultiAgg.java @@ -137,7 +137,7 @@ public class CNodeMultiAgg extends CNodeTpl @Override public SpoofOutputDimsType getOutputDimType() { - return SpoofOutputDimsType.COLUMN_DIMS_COLS; //row vector + return SpoofOutputDimsType.MULTI_SCALAR; } @Override http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/1cd62866/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java index 3cc2e3b..ac2a394 100644 --- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java +++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java @@ -123,9 +123,14 @@ public class CNodeRow extends CNodeTpl @Override public SpoofOutputDimsType getOutputDimType() { - return (_output._cols==1) ? - SpoofOutputDimsType.COLUMN_DIMS_ROWS : //column vector - SpoofOutputDimsType.COLUMN_DIMS_COLS; //row vector + switch( _type ) { + case NO_AGG: return SpoofOutputDimsType.INPUT_DIMS; + case ROW_AGG: return SpoofOutputDimsType.ROW_DIMS; + case COL_AGG: return SpoofOutputDimsType.COLUMN_DIMS_COLS; //row vector + case COL_AGG_T: return SpoofOutputDimsType.COLUMN_DIMS_ROWS; //column vector + default: + throw new RuntimeException("Unsupported row type: "+_type.toString()); + } } @Override http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/1cd62866/src/main/java/org/apache/sysml/hops/codegen/template/TemplateUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/codegen/template/TemplateUtils.java b/src/main/java/org/apache/sysml/hops/codegen/template/TemplateUtils.java index 0a19b56..89211db 100644 --- a/src/main/java/org/apache/sysml/hops/codegen/template/TemplateUtils.java +++ b/src/main/java/org/apache/sysml/hops/codegen/template/TemplateUtils.java @@ -267,13 +267,19 @@ public class TemplateUtils } public static boolean isLookup(CNode node) { - return isUnary(node, UnaryType.LOOKUP_R, UnaryType.LOOKUP_C, UnaryType.LOOKUP_RC); + return isUnary(node, UnaryType.LOOKUP_R, UnaryType.LOOKUP_C, UnaryType.LOOKUP_RC) + || isTernary(node, TernaryType.LOOKUP_RC1); } public static boolean isUnary(CNode node, UnaryType...types) { return node instanceof CNodeUnary && ArrayUtils.contains(types, ((CNodeUnary)node).getType()); } + + public static boolean isTernary(CNode node, TernaryType...types) { + return node instanceof CNodeTernary + && ArrayUtils.contains(types, ((CNodeTernary)node).getType()); + } public static CNodeData createCNodeData(Hop hop, boolean compileLiterals) { CNodeData cdata = new CNodeData(hop); @@ -312,6 +318,11 @@ public class TemplateUtils || output instanceof CNodeTernary) && hasOnlyDataNodeOrLookupInputs(output); } + public static boolean hasNoOperation(CNodeTpl tpl) { + return tpl.getOutput() instanceof CNodeData + || isLookup(tpl.getOutput()); + } + public static boolean hasOnlyDataNodeOrLookupInputs(CNode node) { boolean ret = true; for( CNode c : node.getInput() )
