You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@systemml.apache.org by mb...@apache.org on 2016/07/06 16:54:40 UTC

[1/2] incubator-systemml git commit: [SYSTEMML-561] Fix recompile literal replacement / rewrites for frames

Repository: incubator-systemml
Updated Branches:
  refs/heads/master a75ae23a3 -> 1570ee0e1


[SYSTEMML-561] Fix recompile literal replacement / rewrites for frames 

Project: http://git-wip-us.apache.org/repos/asf/incubator-systemml/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-systemml/commit/d8e17990
Tree: http://git-wip-us.apache.org/repos/asf/incubator-systemml/tree/d8e17990
Diff: http://git-wip-us.apache.org/repos/asf/incubator-systemml/diff/d8e17990

Branch: refs/heads/master
Commit: d8e17990d5357c3fb21b5575b2438894fe01c239
Parents: a75ae23
Author: Matthias Boehm <mb...@us.ibm.com>
Authored: Tue Jul 5 18:38:19 2016 -0700
Committer: Matthias Boehm <mb...@us.ibm.com>
Committed: Tue Jul 5 18:38:19 2016 -0700

----------------------------------------------------------------------
 .../sysml/hops/recompile/LiteralReplacement.java    |  6 ++++--
 .../RewriteAlgebraicSimplificationDynamic.java      | 16 ++++++++--------
 2 files changed, 12 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/d8e17990/src/main/java/org/apache/sysml/hops/recompile/LiteralReplacement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/recompile/LiteralReplacement.java b/src/main/java/org/apache/sysml/hops/recompile/LiteralReplacement.java
index 393e07b..eefd8d0 100644
--- a/src/main/java/org/apache/sysml/hops/recompile/LiteralReplacement.java
+++ b/src/main/java/org/apache/sysml/hops/recompile/LiteralReplacement.java
@@ -252,7 +252,8 @@ public class LiteralReplacement
 		
 		//as.scalar/matrix read - literal replacement
 		if( c instanceof UnaryOp && ((UnaryOp)c).getOp() == OpOp1.CAST_AS_SCALAR 
-			&& c.getInput().get(0) instanceof DataOp )
+			&& c.getInput().get(0) instanceof DataOp
+			&& c.getInput().get(0).getDataType() == DataType.MATRIX )
 		{
 			Data dat = vars.get(c.getInput().get(0).getName());
 			if( dat != null ) //required for selective constant propagation
@@ -287,7 +288,8 @@ public class LiteralReplacement
 		
 		//as.scalar/right indexing w/ literals/vars and matrix less than 10^6 cells
 		if( c instanceof UnaryOp && ((UnaryOp)c).getOp() == OpOp1.CAST_AS_SCALAR 
-			&& c.getInput().get(0) instanceof IndexingOp )
+			&& c.getInput().get(0) instanceof IndexingOp
+			&& c.getInput().get(0).getDataType() == DataType.MATRIX)
 		{
 			IndexingOp rix = (IndexingOp)c.getInput().get(0);
 			Hop data = rix.getInput().get(0);

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/d8e17990/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationDynamic.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationDynamic.java b/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationDynamic.java
index 7003afa..8205e83 100644
--- a/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationDynamic.java
+++ b/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationDynamic.java
@@ -199,7 +199,7 @@ public class RewriteAlgebraicSimplificationDynamic extends HopRewriteRule
 	private Hop removeEmptyRightIndexing(Hop parent, Hop hi, int pos) 
 		throws HopsException
 	{
-		if( hi instanceof IndexingOp  ) //indexing op
+		if( hi instanceof IndexingOp && hi.getDataType()==DataType.MATRIX  ) //indexing op
 		{	
 			Hop input = hi.getInput().get(0);
 			if( input.getNnz()==0 && //nnz input known and empty
@@ -230,11 +230,11 @@ public class RewriteAlgebraicSimplificationDynamic extends HopRewriteRule
 	 */
 	private Hop removeUnnecessaryRightIndexing(Hop parent, Hop hi, int pos)
 	{
-		if( hi instanceof IndexingOp  ) //indexing op
+		if( hi instanceof IndexingOp ) //indexing op
 		{
 			Hop input = hi.getInput().get(0);
 			if( HopRewriteUtils.isEqualSize(hi, input)     //equal dims
-				&& !(hi.getDim1()==1 && hi.getDim2()==1) ) //not 1-1 matrix	
+				&& !(hi.getDim1()==1 && hi.getDim2()==1) ) //not 1-1 matrix/frame	
 			{
 				//equal dims of right indexing input and output -> no need for indexing
 				//(not applied for 1-1 matrices because low potential and issues w/ error
@@ -264,7 +264,7 @@ public class RewriteAlgebraicSimplificationDynamic extends HopRewriteRule
 	private Hop removeEmptyLeftIndexing(Hop parent, Hop hi, int pos) 
 		throws HopsException
 	{
-		if( hi instanceof LeftIndexingOp  ) //left indexing op
+		if( hi instanceof LeftIndexingOp && hi.getDataType() == DataType.MATRIX  ) //left indexing op
 		{
 			Hop input1 = hi.getInput().get(0); //lhs matrix
 			Hop input2 = hi.getInput().get(1); //rhs matrix
@@ -297,7 +297,7 @@ public class RewriteAlgebraicSimplificationDynamic extends HopRewriteRule
 	{
 		if( hi instanceof LeftIndexingOp  ) //left indexing op
 		{
-			Hop input = hi.getInput().get(1); //rhs matrix
+			Hop input = hi.getInput().get(1); //rhs matrix/frame
 			
 			if( HopRewriteUtils.isEqualSize(hi, input) ) //equal dims
 			{
@@ -327,7 +327,7 @@ public class RewriteAlgebraicSimplificationDynamic extends HopRewriteRule
 	{
 		boolean applied = false;
 		
-		//pattern1: X[,1]=A; X[,2]=B -> X=cbind(A,B)
+		//pattern1: X[,1]=A; X[,2]=B -> X=cbind(A,B); matrix / frame
 		if( hi instanceof LeftIndexingOp                      //first lix 
 			&& HopRewriteUtils.isFullColumnIndexing((LeftIndexingOp)hi)
 			&& hi.getInput().get(0) instanceof LeftIndexingOp //second lix	
@@ -342,7 +342,7 @@ public class RewriteAlgebraicSimplificationDynamic extends HopRewriteRule
 			
 			if( pred1 instanceof LiteralOp && HopRewriteUtils.getDoubleValueSafe((LiteralOp)pred1)==1
 				&& pred2 instanceof LiteralOp && HopRewriteUtils.getDoubleValueSafe((LiteralOp)pred2)==2
-				&& input1.getDataType()==DataType.MATRIX && input2.getDataType()==DataType.MATRIX )
+				&& input1.getDataType()!=DataType.SCALAR && input2.getDataType()!=DataType.SCALAR )
 			{
 				//create new cbind operation and rewrite inputs
 				HopRewriteUtils.removeChildReference(parent, hi);		
@@ -369,7 +369,7 @@ public class RewriteAlgebraicSimplificationDynamic extends HopRewriteRule
 			
 			if( pred1 instanceof LiteralOp && HopRewriteUtils.getDoubleValueSafe((LiteralOp)pred1)==1
 				&& pred2 instanceof LiteralOp && HopRewriteUtils.getDoubleValueSafe((LiteralOp)pred2)==2
-				&& input1.getDataType()==DataType.MATRIX && input2.getDataType()==DataType.MATRIX )
+				&& input1.getDataType()!=DataType.SCALAR && input2.getDataType()!=DataType.SCALAR )
 			{
 				//create new cbind operation and rewrite inputs
 				HopRewriteUtils.removeChildReference(parent, hi);		


[2/2] incubator-systemml git commit: [SYSTEMML-573] Fix meta data handling of binary frame readers/writers

Posted by mb...@apache.org.
[SYSTEMML-573] Fix meta data handling of binary frame readers/writers

Project: http://git-wip-us.apache.org/repos/asf/incubator-systemml/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-systemml/commit/1570ee0e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-systemml/tree/1570ee0e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-systemml/diff/1570ee0e

Branch: refs/heads/master
Commit: 1570ee0e10b0e31890f3909de2b4b7ff133e2611
Parents: d8e1799
Author: Matthias Boehm <mb...@us.ibm.com>
Authored: Tue Jul 5 21:15:59 2016 -0700
Committer: Matthias Boehm <mb...@us.ibm.com>
Committed: Tue Jul 5 21:15:59 2016 -0700

----------------------------------------------------------------------
 .../context/SparkExecutionContext.java          |  14 +-
 .../runtime/io/FrameReaderBinaryBlock.java      |  10 +-
 .../runtime/io/FrameWriterBinaryBlock.java      |   4 +-
 .../sysml/runtime/matrix/data/FrameBlock.java   |  34 ++--
 .../functions/frame/FrameMetaReadWriteTest.java | 157 +++++++++++++++++++
 .../functions/frame/FrameMetaReadWrite.dml      |  26 +++
 .../functions/frame/ZPackageSuite.java          |   1 +
 7 files changed, 225 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/1570ee0e/src/main/java/org/apache/sysml/runtime/controlprogram/context/SparkExecutionContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/controlprogram/context/SparkExecutionContext.java b/src/main/java/org/apache/sysml/runtime/controlprogram/context/SparkExecutionContext.java
index a2e2f79..58027ce 100644
--- a/src/main/java/org/apache/sysml/runtime/controlprogram/context/SparkExecutionContext.java
+++ b/src/main/java/org/apache/sysml/runtime/controlprogram/context/SparkExecutionContext.java
@@ -711,12 +711,13 @@ public class SparkExecutionContext extends ExecutionContext
 
 			FrameBlock block = new FrameBlock(src.getSchema());
 			
-			//copy submatrix to block
-			src.sliceOperations( roffset, roffset+maxRow-1, 
-					             0, src.getNumColumns()-1, block );							
+			//copy sub frame to block, incl meta data on first
+			src.sliceOperations( roffset, roffset+maxRow-1, 0, src.getNumColumns()-1, block );		
+			if( roffset == 0 )
+				block.setColumnMetadata(src.getColumnMetadata());
 			
 			//append block to sequence file
-			list.addLast(new Tuple2<Long,FrameBlock>(new Long(roffset+1), block));
+			list.addLast(new Tuple2<Long,FrameBlock>((long)roffset+1, block));
 		}
 		
 		JavaPairRDD<Long,FrameBlock> result = sc.parallelizePairs(list);
@@ -977,8 +978,9 @@ public class SparkExecutionContext extends ExecutionContext
 			FrameBlock block = keyval._2();
 		
 			//copy into output frame
-			out.copy( ix, ix+block.getNumRows()-1, 
-					  0, block.getNumColumns()-1, block );	
+			out.copy( ix, ix+block.getNumRows()-1, 0, block.getNumColumns()-1, block );
+			if( ix == 0 )
+				out.setColumnMetadata(block.getColumnMetadata());
 		}
 		
 		if (DMLScript.STATISTICS) {

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/1570ee0e/src/main/java/org/apache/sysml/runtime/io/FrameReaderBinaryBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/io/FrameReaderBinaryBlock.java b/src/main/java/org/apache/sysml/runtime/io/FrameReaderBinaryBlock.java
index f2a4a8a..88e3d96 100644
--- a/src/main/java/org/apache/sysml/runtime/io/FrameReaderBinaryBlock.java
+++ b/src/main/java/org/apache/sysml/runtime/io/FrameReaderBinaryBlock.java
@@ -116,13 +116,11 @@ public class FrameReaderBinaryBlock extends FrameReader
 		
 		try
 		{
-			//note: next(key, value) does not yet exploit the given serialization classes, record reader does but is generally slower.
 			while( reader.next(key, value) ) {	
 				int row_offset = (int)(key.get()-1);
-				
 				int rows = value.getNumRows();
 				int cols = value.getNumColumns();
-
+				
 				if(rows == 0 || cols == 0)	//Empty block, ignore it.
 					continue;
 				
@@ -132,8 +130,10 @@ public class FrameReaderBinaryBlock extends FrameReader
 							              "out of overall frame range [1:"+rlen+",1:"+clen+"].");
 				}
 		
-				dest.copy( row_offset, row_offset+rows-1, 
-						0, cols-1, value);
+				//copy block into target frame, incl meta on first
+				dest.copy( row_offset, row_offset+rows-1, 0, cols-1, value);
+				if( row_offset==0 )
+					dest.setColumnMetadata(value.getColumnMetadata());
 			}
 		}
 		finally {

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/1570ee0e/src/main/java/org/apache/sysml/runtime/io/FrameWriterBinaryBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/io/FrameWriterBinaryBlock.java b/src/main/java/org/apache/sysml/runtime/io/FrameWriterBinaryBlock.java
index dc96c3e..2b5f056 100644
--- a/src/main/java/org/apache/sysml/runtime/io/FrameWriterBinaryBlock.java
+++ b/src/main/java/org/apache/sysml/runtime/io/FrameWriterBinaryBlock.java
@@ -130,9 +130,11 @@ public class FrameWriterBinaryBlock extends FrameWriter
 				for(int bi = rl; bi < ru; bi += blen) {
 					int len = Math.min(blen,  src.getNumRows()-bi);
 					
-					//get reuse frame block and copy subpart to block
+					//get reuse frame block and copy subpart to block (incl meta on first)
 					FrameBlock block = getFrameBlockForReuse(blocks);
 					src.sliceOperations( bi, bi+len-1, 0, src.getNumColumns()-1, block );
+					if( bi==0 ) //first block
+						block.setColumnMetadata(src.getColumnMetadata());
 					
 					//append block to sequence file
 					index.set(bi+1);

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/1570ee0e/src/main/java/org/apache/sysml/runtime/matrix/data/FrameBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/matrix/data/FrameBlock.java b/src/main/java/org/apache/sysml/runtime/matrix/data/FrameBlock.java
index d9d4b3b..d5787ca 100644
--- a/src/main/java/org/apache/sysml/runtime/matrix/data/FrameBlock.java
+++ b/src/main/java/org/apache/sysml/runtime/matrix/data/FrameBlock.java
@@ -193,6 +193,16 @@ public class FrameBlock implements Writable, CacheBlock, Externalizable
 	
 	/**
 	 * 
+	 * @param c
+	 * @return
+	 */
+	public boolean isColumnMetadataDefault(int c) {
+		return _colmeta.get(c).getMvValue() == null
+			&& _colmeta.get(c).getNumDistinct() == 0;
+	}
+	
+	/**
+	 * 
 	 * @param colmeta
 	 */
 	public void setColumnMetadata(List<ColumnMetadata> colmeta) {
@@ -315,18 +325,20 @@ public class FrameBlock implements Writable, CacheBlock, Externalizable
 		_coldata.get(c).set(r, UtilFunctions.objectToObject(_schema.get(c), val));
 	}
 
-	public void reset(int nrow) 
-	{
+	public void reset(int nrow)  {
 		getSchema().clear();
 		getColumnNames().clear();
-		
-		if(_coldata != null)
-			for(int i=0; i < _coldata.size(); ++i)
+		if( _colmeta != null ) {
+			for( int i=0; i<_colmeta.size(); i++ )
+				_colmeta.get(i).reset();
+		}
+		if(_coldata != null) {
+			for( int i=0; i < _coldata.size(); i++ )
 				_coldata.get(i)._size = nrow;
+		}
 	}
 
-	public void reset() 
-	{
+	public void reset() {
 		reset(0);
 	}
 	
@@ -1237,7 +1249,7 @@ public class FrameBlock implements Writable, CacheBlock, Externalizable
 	 * 
 	 */
 	public static class ColumnMetadata {
-		private long _ndistinct = -1;
+		private long _ndistinct = 0;
 		private String _mvValue = null;
 		
 		public ColumnMetadata(long ndistinct, String mvval) {
@@ -1247,7 +1259,11 @@ public class FrameBlock implements Writable, CacheBlock, Externalizable
 		public ColumnMetadata(long ndistinct) {
 			_ndistinct = ndistinct;
 		}
-
+		public void reset() {
+			_ndistinct = 0;
+			_mvValue = null;
+		}
+		
 		public long getNumDistinct() {
 			return _ndistinct;
 		}		

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/1570ee0e/src/test/java/org/apache/sysml/test/integration/functions/frame/FrameMetaReadWriteTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/sysml/test/integration/functions/frame/FrameMetaReadWriteTest.java b/src/test/java/org/apache/sysml/test/integration/functions/frame/FrameMetaReadWriteTest.java
new file mode 100644
index 0000000..c71eac6
--- /dev/null
+++ b/src/test/java/org/apache/sysml/test/integration/functions/frame/FrameMetaReadWriteTest.java
@@ -0,0 +1,157 @@
+/*
+ * 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.test.integration.functions.frame;
+
+import org.apache.sysml.api.DMLScript;
+import org.apache.sysml.api.DMLScript.RUNTIME_PLATFORM;
+import org.apache.sysml.hops.OptimizerUtils;
+import org.apache.sysml.lops.LopProperties.ExecType;
+import org.apache.sysml.parser.Expression.ValueType;
+import org.apache.sysml.runtime.io.FrameReaderFactory;
+import org.apache.sysml.runtime.io.FrameWriterFactory;
+import org.apache.sysml.runtime.matrix.data.FrameBlock;
+import org.apache.sysml.runtime.matrix.data.OutputInfo;
+import org.apache.sysml.runtime.util.DataConverter;
+import org.apache.sysml.test.integration.AutomatedTestBase;
+import org.apache.sysml.test.integration.TestConfiguration;
+import org.apache.sysml.test.utils.TestUtils;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class FrameMetaReadWriteTest extends AutomatedTestBase
+{
+	private final static String TEST_DIR = "functions/frame/";
+	private final static String TEST_NAME = "FrameMetaReadWrite";
+	private final static String TEST_CLASS_DIR = TEST_DIR + FrameMetaReadWriteTest.class.getSimpleName() + "/";
+	
+	private final static int rows = 1382;
+	private final static int cols = 7;
+	
+	@Override
+	public void setUp() {
+		TestUtils.clearAssertionInformation();
+		addTestConfiguration(TEST_NAME, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME, new String[] {"B"}));
+	}
+
+	@Test
+	public void testFrameBinaryCP()  {
+		runFrameReadWriteTest(OutputInfo.BinaryBlockOutputInfo, ExecType.CP);
+	}
+
+// TODO: add meta data support for text formats (requires consolidation with file-based transform first) 	
+//	@Test
+//	public void testFrameCsvCP()  {
+//		runFrameReadWriteTest(OutputInfo.CSVOutputInfo, ExecType.CP);
+//	}
+//	
+//	@Test
+//	public void testFrameTextcellCP()  {
+//		runFrameReadWriteTest(OutputInfo.TextCellOutputInfo, ExecType.CP);
+//	}
+	
+	@Test
+	public void testFrameBinarySpark()  {
+		runFrameReadWriteTest(OutputInfo.BinaryBlockOutputInfo, ExecType.SPARK);
+	}
+
+// TODO: add meta data support for text formats (requires consolidation with file-based transform first)
+//	@Test
+//	public void testFrameCsvSpark()  {
+//		runFrameReadWriteTest(OutputInfo.CSVOutputInfo, ExecType.SPARK);
+//	}
+//	
+//	@Test
+//	public void testFrameTextcellSpark()  {
+//		runFrameReadWriteTest(OutputInfo.TextCellOutputInfo, ExecType.SPARK);
+//	}
+
+	
+	/**
+	 * 
+	 * @param sparseM1
+	 * @param sparseM2
+	 * @param instType
+	 */
+	private void runFrameReadWriteTest( OutputInfo oinfo, ExecType et)
+	{
+		//rtplatform for MR
+		RUNTIME_PLATFORM platformOld = rtplatform;
+		switch( et ){
+			case MR: rtplatform = RUNTIME_PLATFORM.HADOOP; break;
+			case SPARK: rtplatform = RUNTIME_PLATFORM.SPARK; break;
+			default: rtplatform = RUNTIME_PLATFORM.HYBRID; break;
+		}
+	
+		boolean sparkConfigOld = DMLScript.USE_LOCAL_SPARK_CONFIG;
+		if( rtplatform == RUNTIME_PLATFORM.SPARK )
+			DMLScript.USE_LOCAL_SPARK_CONFIG = true;
+	
+		String ofmt = OutputInfo.outputInfoToStringExternal(oinfo);
+
+		boolean csvReblockOld = OptimizerUtils.ALLOW_FRAME_CSV_REBLOCK;
+		if( ofmt.equals("csv") )
+			OptimizerUtils.ALLOW_FRAME_CSV_REBLOCK = true;
+		
+		try
+		{
+			TestConfiguration config = getTestConfiguration(TEST_NAME);
+			loadTestConfiguration(config);
+			
+			String HOME = SCRIPT_DIR + TEST_DIR;
+			fullDMLScriptName = HOME + TEST_NAME + ".dml";
+			programArgs = new String[]{"-explain","-args", input("A"), 
+					String.valueOf(rows), String.valueOf(cols), ofmt, output("B") };
+			
+			//data generation and write input
+			double[][] A = getRandomMatrix(rows, cols, -10, 10, 0.7, 3412); 
+			FrameBlock fA = DataConverter.convertToFrameBlock(
+					DataConverter.convertToMatrixBlock(A), ValueType.STRING);
+			for( int j=0; j<cols; j++ ) {
+				fA.getColumnMetadata(j).setMvValue(String.valueOf(j+1));
+				fA.getColumnMetadata(j).setNumDistinct(j+1);
+			}
+			FrameWriterFactory.createFrameWriter(oinfo)
+				.writeFrameToHDFS(fA, input("A"), rows, cols);
+			
+			//run testcase
+			runTest(true, false, null, -1);
+			
+			//read output and compare meta data
+			FrameBlock fB = FrameReaderFactory
+					.createFrameReader(OutputInfo.getMatchingInputInfo(oinfo))
+					.readFrameFromHDFS(output("B"), rows, cols);
+			for( int j=0; j<cols; j++ ) {
+				Assert.assertEquals("MV meta data wrong!",
+						fA.getColumnMetadata(j).getMvValue(), fB.getColumnMetadata(j).getMvValue());
+				Assert.assertEquals("Distinct meta data wrong!",
+						fA.getColumnMetadata(j).getNumDistinct(), fB.getColumnMetadata(j).getNumDistinct());
+			}
+		}
+		catch(Exception ex) {
+			ex.printStackTrace();
+			throw new RuntimeException(ex);
+		}
+		finally {
+			rtplatform = platformOld;
+			DMLScript.USE_LOCAL_SPARK_CONFIG = sparkConfigOld;
+			OptimizerUtils.ALLOW_FRAME_CSV_REBLOCK = csvReblockOld;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/1570ee0e/src/test/scripts/functions/frame/FrameMetaReadWrite.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/frame/FrameMetaReadWrite.dml b/src/test/scripts/functions/frame/FrameMetaReadWrite.dml
new file mode 100644
index 0000000..8c4130d
--- /dev/null
+++ b/src/test/scripts/functions/frame/FrameMetaReadWrite.dml
@@ -0,0 +1,26 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+A = read($1, data_type="frame", rows=$2, cols=$3, format=$4);
+if(1==1){}
+
+B = A;
+write(B, $5, format=$4);

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/1570ee0e/src/test_suites/java/org/apache/sysml/test/integration/functions/frame/ZPackageSuite.java
----------------------------------------------------------------------
diff --git a/src/test_suites/java/org/apache/sysml/test/integration/functions/frame/ZPackageSuite.java b/src/test_suites/java/org/apache/sysml/test/integration/functions/frame/ZPackageSuite.java
index b376777..25127ce 100644
--- a/src/test_suites/java/org/apache/sysml/test/integration/functions/frame/ZPackageSuite.java
+++ b/src/test_suites/java/org/apache/sysml/test/integration/functions/frame/ZPackageSuite.java
@@ -33,6 +33,7 @@ import org.junit.runners.Suite;
 	FrameGetSetTest.class,
 	FrameIndexingTest.class,
 	FrameMatrixCastingTest.class,
+	FrameMetaReadWriteTest.class,
 	FrameReadWriteTest.class,
 	FrameScalarCastingTest.class,
 	FrameSchemaReadTest.class,