All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.sysml.hops.globalopt.Plan Maven / Gradle / Ivy

There is a newer version: 1.2.0
Show newest version
/*
 * 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.sysml.hops.globalopt;

import java.util.ArrayList;

import org.apache.sysml.hops.DataOp;
import org.apache.sysml.hops.FunctionOp;
import org.apache.sysml.hops.Hop.DataOpTypes;
import org.apache.sysml.hops.OptimizerUtils;
import org.apache.sysml.hops.globalopt.gdfgraph.GDFNode;
import org.apache.sysml.hops.globalopt.gdfgraph.GDFNode.NodeType;
import org.apache.sysml.lops.LopProperties.ExecType;
import org.apache.sysml.parser.Expression.DataType;
import org.apache.sysml.runtime.controlprogram.parfor.util.IDSequence;


public class Plan 
{
	private static IDSequence _seqID   = new IDSequence();
	
	private long _ID                   = -1;
	private GDFNode _node              = null;
	
	private InterestingProperties _ips = null;
	private RewriteConfig _conf        = null;
	private ArrayList _childs    = null;
	private double _costs = -1;
	
	public Plan(GDFNode node, InterestingProperties ips, RewriteConfig rc, ArrayList childs)
	{
		_ID = _seqID.getNextID();
		_node = node;
		_ips = ips;
		_conf = rc;
		if( childs != null && !childs.isEmpty() )
			_childs = childs;
		else
			_childs = new ArrayList();
	}
	
	public Plan( Plan p )
	{	
		_ID = _seqID.getNextID();
		_node = p._node;
		_ips = new InterestingProperties(p._ips);
		_conf = new RewriteConfig(p._conf);
		_costs = p._costs;
		
		if( p._childs != null && !p._childs.isEmpty() )
			_childs = new ArrayList(p._childs);
		else
			_childs = new ArrayList();
	}
	
	public GDFNode getNode()
	{
		return _node;
	}
	
	public void addChild( Plan c )
	{
		_childs.add(c);
	}
	
	public ArrayList getChilds()
	{
		return _childs;
	}
	
	public InterestingProperties getInterestingProperties()
	{
		return _ips;
	}
	
	public RewriteConfig getRewriteConfig()
	{
		return _conf;
	}
	
	public void setCosts( double costs )
	{
		_costs = costs;
	}
	
	public double getCosts()
	{
		return _costs;
	}
	
	/**
	 * If operation is executed in MR, all input blocksizes need to match.
	 * Note that the output blocksize can be different since we would add
	 * additional reblocks after that operation.
	 * 
	 * @return
	 */
	public boolean checkValidBlocksizesInMR()
	{
		boolean ret = true;
		ExecType CLUSTER = OptimizerUtils.isSparkExecutionMode() ? ExecType.SPARK : ExecType.MR;
		
		if( _conf.getExecType()==CLUSTER 
			&& _childs != null && _childs.size() > 1 ) 
		{
			int size0 = _childs.get(0)._conf.getBlockSize();
			if( size0 > 0 ) { //-1 compatible with everything
				for( Plan c : _childs )
					ret &= (  c._conf.getBlockSize() == size0
					        ||c._conf.getBlockSize() <= 0 );
			}
		}
		
		return ret;
	}

	/**
	 * 
	 * @return
	 */
	public boolean checkValidBlocksizesTRead()
	{
		boolean ret = true;
		
		if( _node.getNodeType() == NodeType.HOP_NODE
			&& _node.getHop() instanceof DataOp 
			&& ((DataOp)_node.getHop()).getDataOpType() == DataOpTypes.TRANSIENTREAD )
		{
			for( Plan c : _childs )
				ret &= (  _conf.getBlockSize() == c._conf.getBlockSize() );
		}
		
		if( _node.getNodeType() == NodeType.CROSS_BLOCK_NODE )
		{
			for( Plan c : _childs )
				ret &= (  _conf.getBlockSize() == c._conf.getBlockSize() );
		}

		return ret;
	}
	
	/**
	 * If operation is executed in MR, only certain operations allow
	 * all formats. In general, unary operations also allow for cell inputs. 
	 * TODO: check and test current format assumptions
	 * 
	 * @param node
	 * @return
	 */
	public boolean checkValidFormatInMR()
	{
		boolean ret = true;
		ExecType CLUSTER = OptimizerUtils.isSparkExecutionMode() ? ExecType.SPARK : ExecType.MR;
		
		if( _conf.getExecType()==CLUSTER ) 
		{
			if( _childs != null )
				for( Plan c : _childs )
					ret &= _node.isValidInputFormatForOperation(c._conf.getFormat());
		}
		
		return ret;
	}
	
	public boolean checkValidExecutionType()
	{
		boolean ret = true;
		
		ret &= !( _node.getHop() instanceof FunctionOp && _conf.getExecType()!=ExecType.CP );
		//unnecessary, because reblock now merged into base hop
		//ret &= !( _node.getHop() instanceof ReblockOp &&  _conf.getExecType()!=ExecType.MR );
		
		return ret;
	}
	
	/**
	 * A plan is defined as preferred if its output interesting properties
	 * match the interesting properties of all its matrix inputs.
	 * 
	 * @return
	 */
	public boolean isPreferredPlan()
	{
		boolean ret = true;
		
		for( Plan c : _childs )
			if( c.getNode().getDataType()==DataType.MATRIX )
				ret &= _ips.equals( c.getInterestingProperties() );
		
		return ret;
	}
	
	@Override
	public String toString()
	{
		StringBuilder sb = new StringBuilder();
		sb.append("PLAN("+_ID+") [");
		sb.append(_ips.toString());
		sb.append(",");
		sb.append(_conf.toString());
		sb.append(",{");
		for( Plan c : _childs ){
			sb.append(c._ID);
			sb.append(",");
		}
		sb.setLength(sb.length()-1);
		sb.append("},");	
		sb.append(_costs);
		sb.append("]");
		
		return sb.toString();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy