You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@systemml.apache.org by ba...@apache.org on 2020/06/25 13:34:53 UTC

[systemml] branch master updated: [SYSTEMDS-511] Add protobuf support

This is an automated email from the ASF dual-hosted git repository.

baunsgaard pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/systemml.git


The following commit(s) were added to refs/heads/master by this push:
     new b76915c  [SYSTEMDS-511] Add protobuf support
b76915c is described below

commit b76915c68e02f421027f6673851de7a8caf6d16f
Author: Herbert Mühlburger <ma...@muehlburger.at>
AuthorDate: Thu Jun 25 12:43:50 2020 +0200

    [SYSTEMDS-511] Add protobuf support
    
    Adds support for Protobuf file format, for both reads and write.
    
    AMLS project SS2020, part 1
    
    Closes #971
---
 dev/Tasks.txt                                      |    3 +
 pom.xml                                            |   14 +-
 src/main/java/org/apache/sysds/common/Types.java   |    3 +-
 .../apache/sysds/parser/dml/DmlBaseListener.java   |    2 +-
 .../java/org/apache/sysds/parser/dml/DmlLexer.java |    2 +-
 .../org/apache/sysds/parser/dml/DmlListener.java   |    2 +-
 .../org/apache/sysds/parser/dml/DmlParser.java     |    2 +-
 .../org/apache/sysds/protobuf/SysdsProtos.java     | 3063 ++++++++++++++++++++
 .../sysds/runtime/io/FrameReaderFactory.java       |   39 +-
 .../apache/sysds/runtime/io/FrameReaderProto.java  |   87 +
 .../sysds/runtime/io/FrameWriterFactory.java       |    5 +
 .../apache/sysds/runtime/io/FrameWriterProto.java  |   80 +
 src/main/resources/protobuf/Frame.proto            |   46 +
 .../io/proto/FrameReaderWriterProtoTest.java       |   81 +
 14 files changed, 3404 insertions(+), 25 deletions(-)

diff --git a/dev/Tasks.txt b/dev/Tasks.txt
index c84a523..673c737 100644
--- a/dev/Tasks.txt
+++ b/dev/Tasks.txt
@@ -349,3 +349,6 @@ SYSTEMDS-500 Documentation Webpage Reintroduction
 
 Others:
  * Break append instruction to cbind and rbind 
+
+SYSTEMDS-510 IO formats
+ * 511 Add protobuf support to write and read FrameBlocks to HDFS     OK
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 0e4fe44..54cfb85 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1034,6 +1034,18 @@
 			<artifactId>maven-gpg-plugin</artifactId>
 			<version>1.6</version>
 		</dependency>
-  
+
+		<!-- https://github.com/protocolbuffers/protobuf/tree/master/java -->
+		<dependency>
+			<groupId>com.google.protobuf</groupId>
+			<artifactId>protobuf-java</artifactId>
+			<version>3.12.2</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.google.protobuf</groupId>
+			<artifactId>protobuf-java-util</artifactId>
+			<version>3.12.2</version>
+		</dependency>
 	</dependencies>
 </project>
diff --git a/src/main/java/org/apache/sysds/common/Types.java b/src/main/java/org/apache/sysds/common/Types.java
index 996132f..02b1519 100644
--- a/src/main/java/org/apache/sysds/common/Types.java
+++ b/src/main/java/org/apache/sysds/common/Types.java
@@ -483,7 +483,8 @@ public class Types
 		CSV,    // text dense representation
 		LIBSVM, // text libsvm sparse row representation
 		JSONL,  // text nested JSON (Line) representation
-		BINARY; // binary block representation (dense/sparse/ultra-sparse) 
+		BINARY, // binary block representation (dense/sparse/ultra-sparse)
+		PROTO;  // protocol buffer representation
 		
 		public boolean isIJVFormat() {
 			return this == TEXT || this == MM;
diff --git a/src/main/java/org/apache/sysds/parser/dml/DmlBaseListener.java b/src/main/java/org/apache/sysds/parser/dml/DmlBaseListener.java
index 70e7de4..b165586 100644
--- a/src/main/java/org/apache/sysds/parser/dml/DmlBaseListener.java
+++ b/src/main/java/org/apache/sysds/parser/dml/DmlBaseListener.java
@@ -1,4 +1,4 @@
-// Generated from org/apache/sysds/parser/dml/Dml.g4 by ANTLR 4.5.3
+// Generated from org\apache\sysds\parser\dml\Dml.g4 by ANTLR 4.5.3
 package org.apache.sysds.parser.dml;
 
 /*
diff --git a/src/main/java/org/apache/sysds/parser/dml/DmlLexer.java b/src/main/java/org/apache/sysds/parser/dml/DmlLexer.java
index 8ddedf1..3dd23d2 100644
--- a/src/main/java/org/apache/sysds/parser/dml/DmlLexer.java
+++ b/src/main/java/org/apache/sysds/parser/dml/DmlLexer.java
@@ -1,4 +1,4 @@
-// Generated from org/apache/sysds/parser/dml/Dml.g4 by ANTLR 4.5.3
+// Generated from org\apache\sysds\parser\dml\Dml.g4 by ANTLR 4.5.3
 package org.apache.sysds.parser.dml;
 
 /*
diff --git a/src/main/java/org/apache/sysds/parser/dml/DmlListener.java b/src/main/java/org/apache/sysds/parser/dml/DmlListener.java
index 434d085..36904af 100644
--- a/src/main/java/org/apache/sysds/parser/dml/DmlListener.java
+++ b/src/main/java/org/apache/sysds/parser/dml/DmlListener.java
@@ -1,4 +1,4 @@
-// Generated from org/apache/sysds/parser/dml/Dml.g4 by ANTLR 4.5.3
+// Generated from org\apache\sysds\parser\dml\Dml.g4 by ANTLR 4.5.3
 package org.apache.sysds.parser.dml;
 
 /*
diff --git a/src/main/java/org/apache/sysds/parser/dml/DmlParser.java b/src/main/java/org/apache/sysds/parser/dml/DmlParser.java
index 4a10457..c751526 100644
--- a/src/main/java/org/apache/sysds/parser/dml/DmlParser.java
+++ b/src/main/java/org/apache/sysds/parser/dml/DmlParser.java
@@ -1,4 +1,4 @@
-// Generated from org/apache/sysds/parser/dml/Dml.g4 by ANTLR 4.5.3
+// Generated from org\apache\sysds\parser\dml\Dml.g4 by ANTLR 4.5.3
 package org.apache.sysds.parser.dml;
 
 /*
diff --git a/src/main/java/org/apache/sysds/protobuf/SysdsProtos.java b/src/main/java/org/apache/sysds/protobuf/SysdsProtos.java
new file mode 100644
index 0000000..514d30c
--- /dev/null
+++ b/src/main/java/org/apache/sysds/protobuf/SysdsProtos.java
@@ -0,0 +1,3063 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: src/main/resources/protobuf/Frame.proto
+/*
+ * 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.protobuf;
+
+public final class SysdsProtos {
+	private static final com.google.protobuf.Descriptors.Descriptor internal_static_sysds_Frame_descriptor;
+	private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_sysds_Frame_fieldAccessorTable;
+	private static final com.google.protobuf.Descriptors.Descriptor internal_static_sysds_Row_descriptor;
+	private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_sysds_Row_fieldAccessorTable;
+	private static final com.google.protobuf.Descriptors.Descriptor internal_static_sysds_Schema_descriptor;
+	private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_sysds_Schema_fieldAccessorTable;
+	private static com.google.protobuf.Descriptors.FileDescriptor descriptor;
+
+	static {
+		java.lang.String[] descriptorData = {"\n\'src/main/resources/protobuf/Frame.prot"
+			+ "o\022\005sysds\"!\n\005Frame\022\030\n\004rows\030\001 \003(\0132\n.sysds."
+			+ "Row\"V\n\003Row\022\024\n\014column_names\030\001 \003(\t\022\023\n\013colu"
+			+ "mn_data\030\002 \003(\t\022$\n\rcolumn_schema\030\003 \003(\0132\r.s"
+			+ "ysds.Schema\"\221\001\n\006Schema\022*\n\tvalueType\030\001 \003("
+			+ "\0162\027.sysds.Schema.ValueType\"[\n\tValueType\022"
+			+ "\010\n\004FP32\020\000\022\010\n\004FP64\020\001\022\t\n\005INT32\020\002\022\t\n\005INT64\020"
+			+ "\003\022\013\n\007BOOLEAN\020\004\022\n\n\006STRING\020\005\022\013\n\007UNKNOWN\020\006B"
+			+ "*\n\031org.apache.sysds.protobufB\013SysdsProto" + "sP\000b\006proto3"};
+		descriptor = com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom(descriptorData,
+			new com.google.protobuf.Descriptors.FileDescriptor[] {});
+		internal_static_sysds_Frame_descriptor = getDescriptor().getMessageTypes().get(0);
+		internal_static_sysds_Frame_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+			internal_static_sysds_Frame_descriptor, new java.lang.String[] {"Rows",});
+		internal_static_sysds_Row_descriptor = getDescriptor().getMessageTypes().get(1);
+		internal_static_sysds_Row_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+			internal_static_sysds_Row_descriptor,
+			new java.lang.String[] {"ColumnNames", "ColumnData", "ColumnSchema",});
+		internal_static_sysds_Schema_descriptor = getDescriptor().getMessageTypes().get(2);
+		internal_static_sysds_Schema_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+			internal_static_sysds_Schema_descriptor, new java.lang.String[] {"ValueType",});
+	}
+
+	private SysdsProtos() {
+	}
+
+	public static void registerAllExtensions(com.google.protobuf.ExtensionRegistryLite registry) {
+	}
+
+	public static void registerAllExtensions(com.google.protobuf.ExtensionRegistry registry) {
+		registerAllExtensions((com.google.protobuf.ExtensionRegistryLite) registry);
+	}
+
+	public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() {
+		return descriptor;
+	}
+
+	public interface FrameOrBuilder extends
+		// @@protoc_insertion_point(interface_extends:sysds.Frame)
+		com.google.protobuf.MessageOrBuilder {
+
+		/**
+		 * <code>repeated .sysds.Row rows = 1;</code>
+		 */
+		java.util.List<org.apache.sysds.protobuf.SysdsProtos.Row> getRowsList();
+
+		/**
+		 * <code>repeated .sysds.Row rows = 1;</code>
+		 */
+		org.apache.sysds.protobuf.SysdsProtos.Row getRows(int index);
+
+		/**
+		 * <code>repeated .sysds.Row rows = 1;</code>
+		 */
+		int getRowsCount();
+
+		/**
+		 * <code>repeated .sysds.Row rows = 1;</code>
+		 */
+		java.util.List<? extends org.apache.sysds.protobuf.SysdsProtos.RowOrBuilder> getRowsOrBuilderList();
+
+		/**
+		 * <code>repeated .sysds.Row rows = 1;</code>
+		 */
+		org.apache.sysds.protobuf.SysdsProtos.RowOrBuilder getRowsOrBuilder(int index);
+	}
+
+	public interface RowOrBuilder extends
+		// @@protoc_insertion_point(interface_extends:sysds.Row)
+		com.google.protobuf.MessageOrBuilder {
+
+		/**
+		 * <code>repeated string column_names = 1;</code>
+		 *
+		 * @return A list containing the columnNames.
+		 */
+		java.util.List<java.lang.String> getColumnNamesList();
+
+		/**
+		 * <code>repeated string column_names = 1;</code>
+		 *
+		 * @return The count of columnNames.
+		 */
+		int getColumnNamesCount();
+
+		/**
+		 * <code>repeated string column_names = 1;</code>
+		 *
+		 * @param index The index of the element to return.
+		 * @return The columnNames at the given index.
+		 */
+		java.lang.String getColumnNames(int index);
+
+		/**
+		 * <code>repeated string column_names = 1;</code>
+		 *
+		 * @param index The index of the value to return.
+		 * @return The bytes of the columnNames at the given index.
+		 */
+		com.google.protobuf.ByteString getColumnNamesBytes(int index);
+
+		/**
+		 * <code>repeated string column_data = 2;</code>
+		 *
+		 * @return A list containing the columnData.
+		 */
+		java.util.List<java.lang.String> getColumnDataList();
+
+		/**
+		 * <code>repeated string column_data = 2;</code>
+		 *
+		 * @return The count of columnData.
+		 */
+		int getColumnDataCount();
+
+		/**
+		 * <code>repeated string column_data = 2;</code>
+		 *
+		 * @param index The index of the element to return.
+		 * @return The columnData at the given index.
+		 */
+		java.lang.String getColumnData(int index);
+
+		/**
+		 * <code>repeated string column_data = 2;</code>
+		 *
+		 * @param index The index of the value to return.
+		 * @return The bytes of the columnData at the given index.
+		 */
+		com.google.protobuf.ByteString getColumnDataBytes(int index);
+
+		/**
+		 * <code>repeated .sysds.Schema column_schema = 3;</code>
+		 */
+		java.util.List<org.apache.sysds.protobuf.SysdsProtos.Schema> getColumnSchemaList();
+
+		/**
+		 * <code>repeated .sysds.Schema column_schema = 3;</code>
+		 */
+		org.apache.sysds.protobuf.SysdsProtos.Schema getColumnSchema(int index);
+
+		/**
+		 * <code>repeated .sysds.Schema column_schema = 3;</code>
+		 */
+		int getColumnSchemaCount();
+
+		/**
+		 * <code>repeated .sysds.Schema column_schema = 3;</code>
+		 */
+		java.util.List<? extends org.apache.sysds.protobuf.SysdsProtos.SchemaOrBuilder> getColumnSchemaOrBuilderList();
+
+		/**
+		 * <code>repeated .sysds.Schema column_schema = 3;</code>
+		 */
+		org.apache.sysds.protobuf.SysdsProtos.SchemaOrBuilder getColumnSchemaOrBuilder(int index);
+	}
+
+	public interface SchemaOrBuilder extends
+		// @@protoc_insertion_point(interface_extends:sysds.Schema)
+		com.google.protobuf.MessageOrBuilder {
+
+		/**
+		 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+		 *
+		 * @return A list containing the valueType.
+		 */
+		java.util.List<org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType> getValueTypeList();
+
+		/**
+		 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+		 *
+		 * @return The count of valueType.
+		 */
+		int getValueTypeCount();
+
+		/**
+		 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+		 *
+		 * @param index The index of the element to return.
+		 * @return The valueType at the given index.
+		 */
+		org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType getValueType(int index);
+
+		/**
+		 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+		 *
+		 * @return A list containing the enum numeric values on the wire for valueType.
+		 */
+		java.util.List<java.lang.Integer> getValueTypeValueList();
+
+		/**
+		 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+		 *
+		 * @param index The index of the value to return.
+		 * @return The enum numeric value on the wire of valueType at the given index.
+		 */
+		int getValueTypeValue(int index);
+	}
+
+	/**
+	 * Protobuf type {@code sysds.Frame}
+	 */
+	public static final class Frame extends com.google.protobuf.GeneratedMessageV3 implements
+		// @@protoc_insertion_point(message_implements:sysds.Frame)
+		FrameOrBuilder {
+		public static final int ROWS_FIELD_NUMBER = 1;
+		private static final long serialVersionUID = 0L;
+		// @@protoc_insertion_point(class_scope:sysds.Frame)
+		private static final org.apache.sysds.protobuf.SysdsProtos.Frame DEFAULT_INSTANCE;
+		private static final com.google.protobuf.Parser<Frame> PARSER = new com.google.protobuf.AbstractParser<Frame>() {
+			@java.lang.Override
+			public Frame parsePartialFrom(com.google.protobuf.CodedInputStream input,
+				com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+				throws com.google.protobuf.InvalidProtocolBufferException {
+				return new Frame(input, extensionRegistry);
+			}
+		};
+
+		static {
+			DEFAULT_INSTANCE = new org.apache.sysds.protobuf.SysdsProtos.Frame();
+		}
+
+		private java.util.List<org.apache.sysds.protobuf.SysdsProtos.Row> rows_;
+		private byte memoizedIsInitialized = -1;
+
+		// Use Frame.newBuilder() to construct.
+		private Frame(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+			super(builder);
+		}
+
+		private Frame() {
+			rows_ = java.util.Collections.emptyList();
+		}
+
+		private Frame(com.google.protobuf.CodedInputStream input,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			this();
+			if(extensionRegistry == null) {
+				throw new java.lang.NullPointerException();
+			}
+			int mutable_bitField0_ = 0;
+			com.google.protobuf.UnknownFieldSet.Builder unknownFields = com.google.protobuf.UnknownFieldSet
+				.newBuilder();
+			try {
+				boolean done = false;
+				while(!done) {
+					int tag = input.readTag();
+					switch(tag) {
+						case 0:
+							done = true;
+							break;
+						case 10: {
+							if(!((mutable_bitField0_ & 0x00000001) != 0)) {
+								rows_ = new java.util.ArrayList<org.apache.sysds.protobuf.SysdsProtos.Row>();
+								mutable_bitField0_ |= 0x00000001;
+							}
+							rows_.add(input.readMessage(org.apache.sysds.protobuf.SysdsProtos.Row.parser(),
+								extensionRegistry));
+							break;
+						}
+						default: {
+							if(!parseUnknownField(input, unknownFields, extensionRegistry, tag)) {
+								done = true;
+							}
+							break;
+						}
+					}
+				}
+			}
+			catch(com.google.protobuf.InvalidProtocolBufferException e) {
+				throw e.setUnfinishedMessage(this);
+			}
+			catch(java.io.IOException e) {
+				throw new com.google.protobuf.InvalidProtocolBufferException(e).setUnfinishedMessage(this);
+			}
+			finally {
+				if(((mutable_bitField0_ & 0x00000001) != 0)) {
+					rows_ = java.util.Collections.unmodifiableList(rows_);
+				}
+				this.unknownFields = unknownFields.build();
+				makeExtensionsImmutable();
+			}
+		}
+
+		public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
+			return org.apache.sysds.protobuf.SysdsProtos.internal_static_sysds_Frame_descriptor;
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Frame parseFrom(java.nio.ByteBuffer data)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Frame parseFrom(java.nio.ByteBuffer data,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data, extensionRegistry);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Frame parseFrom(com.google.protobuf.ByteString data)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Frame parseFrom(com.google.protobuf.ByteString data,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data, extensionRegistry);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Frame parseFrom(byte[] data)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Frame parseFrom(byte[] data,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data, extensionRegistry);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Frame parseFrom(java.io.InputStream input)
+			throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Frame parseFrom(java.io.InputStream input,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input, extensionRegistry);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Frame parseDelimitedFrom(java.io.InputStream input)
+			throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Frame parseDelimitedFrom(java.io.InputStream input,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3
+				.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Frame parseFrom(com.google.protobuf.CodedInputStream input)
+			throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Frame parseFrom(com.google.protobuf.CodedInputStream input,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input, extensionRegistry);
+		}
+
+		public static Builder newBuilder() {
+			return DEFAULT_INSTANCE.toBuilder();
+		}
+
+		public static Builder newBuilder(org.apache.sysds.protobuf.SysdsProtos.Frame prototype) {
+			return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Frame getDefaultInstance() {
+			return DEFAULT_INSTANCE;
+		}
+
+		public static com.google.protobuf.Parser<Frame> parser() {
+			return PARSER;
+		}
+
+		@java.lang.Override
+		@SuppressWarnings({"unused"})
+		protected java.lang.Object newInstance(UnusedPrivateParameter unused) {
+			return new Frame();
+		}
+
+		@java.lang.Override
+		public final com.google.protobuf.UnknownFieldSet getUnknownFields() {
+			return this.unknownFields;
+		}
+
+		@java.lang.Override
+		protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() {
+			return org.apache.sysds.protobuf.SysdsProtos.internal_static_sysds_Frame_fieldAccessorTable
+				.ensureFieldAccessorsInitialized(org.apache.sysds.protobuf.SysdsProtos.Frame.class,
+					org.apache.sysds.protobuf.SysdsProtos.Frame.Builder.class);
+		}
+
+		/**
+		 * <code>repeated .sysds.Row rows = 1;</code>
+		 */
+		@java.lang.Override
+		public java.util.List<org.apache.sysds.protobuf.SysdsProtos.Row> getRowsList() {
+			return rows_;
+		}
+
+		/**
+		 * <code>repeated .sysds.Row rows = 1;</code>
+		 */
+		@java.lang.Override
+		public java.util.List<? extends org.apache.sysds.protobuf.SysdsProtos.RowOrBuilder> getRowsOrBuilderList() {
+			return rows_;
+		}
+
+		/**
+		 * <code>repeated .sysds.Row rows = 1;</code>
+		 */
+		@java.lang.Override
+		public int getRowsCount() {
+			return rows_.size();
+		}
+
+		/**
+		 * <code>repeated .sysds.Row rows = 1;</code>
+		 */
+		@java.lang.Override
+		public org.apache.sysds.protobuf.SysdsProtos.Row getRows(int index) {
+			return rows_.get(index);
+		}
+
+		/**
+		 * <code>repeated .sysds.Row rows = 1;</code>
+		 */
+		@java.lang.Override
+		public org.apache.sysds.protobuf.SysdsProtos.RowOrBuilder getRowsOrBuilder(int index) {
+			return rows_.get(index);
+		}
+
+		@java.lang.Override
+		public final boolean isInitialized() {
+			byte isInitialized = memoizedIsInitialized;
+			if(isInitialized == 1)
+				return true;
+			if(isInitialized == 0)
+				return false;
+
+			memoizedIsInitialized = 1;
+			return true;
+		}
+
+		@java.lang.Override
+		public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
+			for(int i = 0; i < rows_.size(); i++) {
+				output.writeMessage(1, rows_.get(i));
+			}
+			unknownFields.writeTo(output);
+		}
+
+		@java.lang.Override
+		public int getSerializedSize() {
+			int size = memoizedSize;
+			if(size != -1)
+				return size;
+
+			size = 0;
+			for(int i = 0; i < rows_.size(); i++) {
+				size += com.google.protobuf.CodedOutputStream.computeMessageSize(1, rows_.get(i));
+			}
+			size += unknownFields.getSerializedSize();
+			memoizedSize = size;
+			return size;
+		}
+
+		@java.lang.Override
+		public boolean equals(final java.lang.Object obj) {
+			if(obj == this) {
+				return true;
+			}
+			if(!(obj instanceof org.apache.sysds.protobuf.SysdsProtos.Frame)) {
+				return super.equals(obj);
+			}
+			org.apache.sysds.protobuf.SysdsProtos.Frame other = (org.apache.sysds.protobuf.SysdsProtos.Frame) obj;
+
+			if(!getRowsList().equals(other.getRowsList()))
+				return false;
+			if(!unknownFields.equals(other.unknownFields))
+				return false;
+			return true;
+		}
+
+		@java.lang.Override
+		public int hashCode() {
+			if(memoizedHashCode != 0) {
+				return memoizedHashCode;
+			}
+			int hash = 41;
+			hash = (19 * hash) + getDescriptor().hashCode();
+			if(getRowsCount() > 0) {
+				hash = (37 * hash) + ROWS_FIELD_NUMBER;
+				hash = (53 * hash) + getRowsList().hashCode();
+			}
+			hash = (29 * hash) + unknownFields.hashCode();
+			memoizedHashCode = hash;
+			return hash;
+		}
+
+		@java.lang.Override
+		public Builder newBuilderForType() {
+			return newBuilder();
+		}
+
+		@java.lang.Override
+		public Builder toBuilder() {
+			return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this);
+		}
+
+		@java.lang.Override
+		protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+			Builder builder = new Builder(parent);
+			return builder;
+		}
+
+		@java.lang.Override
+		public com.google.protobuf.Parser<Frame> getParserForType() {
+			return PARSER;
+		}
+
+		@java.lang.Override
+		public org.apache.sysds.protobuf.SysdsProtos.Frame getDefaultInstanceForType() {
+			return DEFAULT_INSTANCE;
+		}
+
+		/**
+		 * Protobuf type {@code sysds.Frame}
+		 */
+		public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+			// @@protoc_insertion_point(builder_implements:sysds.Frame)
+			org.apache.sysds.protobuf.SysdsProtos.FrameOrBuilder {
+			private int bitField0_;
+			private java.util.List<org.apache.sysds.protobuf.SysdsProtos.Row> rows_ = java.util.Collections.emptyList();
+			private com.google.protobuf.RepeatedFieldBuilderV3<org.apache.sysds.protobuf.SysdsProtos.Row, org.apache.sysds.protobuf.SysdsProtos.Row.Builder, org.apache.sysds.protobuf.SysdsProtos.RowOrBuilder> rowsBuilder_;
+
+			// Construct using org.apache.sysds.protobuf.SysdsProtos.Frame.newBuilder()
+			private Builder() {
+				maybeForceBuilderInitialization();
+			}
+
+			private Builder(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+				super(parent);
+				maybeForceBuilderInitialization();
+			}
+
+			public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
+				return org.apache.sysds.protobuf.SysdsProtos.internal_static_sysds_Frame_descriptor;
+			}
+
+			@java.lang.Override
+			protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() {
+				return org.apache.sysds.protobuf.SysdsProtos.internal_static_sysds_Frame_fieldAccessorTable
+					.ensureFieldAccessorsInitialized(org.apache.sysds.protobuf.SysdsProtos.Frame.class,
+						org.apache.sysds.protobuf.SysdsProtos.Frame.Builder.class);
+			}
+
+			private void maybeForceBuilderInitialization() {
+				if(com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders) {
+					getRowsFieldBuilder();
+				}
+			}
+
+			@java.lang.Override
+			public Builder clear() {
+				super.clear();
+				if(rowsBuilder_ == null) {
+					rows_ = java.util.Collections.emptyList();
+					bitField0_ = (bitField0_ & ~0x00000001);
+				}
+				else {
+					rowsBuilder_.clear();
+				}
+				return this;
+			}
+
+			@java.lang.Override
+			public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() {
+				return org.apache.sysds.protobuf.SysdsProtos.internal_static_sysds_Frame_descriptor;
+			}
+
+			@java.lang.Override
+			public org.apache.sysds.protobuf.SysdsProtos.Frame getDefaultInstanceForType() {
+				return org.apache.sysds.protobuf.SysdsProtos.Frame.getDefaultInstance();
+			}
+
+			@java.lang.Override
+			public org.apache.sysds.protobuf.SysdsProtos.Frame build() {
+				org.apache.sysds.protobuf.SysdsProtos.Frame result = buildPartial();
+				if(!result.isInitialized()) {
+					throw newUninitializedMessageException(result);
+				}
+				return result;
+			}
+
+			@java.lang.Override
+			public org.apache.sysds.protobuf.SysdsProtos.Frame buildPartial() {
+				org.apache.sysds.protobuf.SysdsProtos.Frame result = new org.apache.sysds.protobuf.SysdsProtos.Frame(
+					this);
+				int from_bitField0_ = bitField0_;
+				if(rowsBuilder_ == null) {
+					if(((bitField0_ & 0x00000001) != 0)) {
+						rows_ = java.util.Collections.unmodifiableList(rows_);
+						bitField0_ = (bitField0_ & ~0x00000001);
+					}
+					result.rows_ = rows_;
+				}
+				else {
+					result.rows_ = rowsBuilder_.build();
+				}
+				onBuilt();
+				return result;
+			}
+
+			@java.lang.Override
+			public Builder clone() {
+				return super.clone();
+			}
+
+			@java.lang.Override
+			public Builder setField(com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) {
+				return super.setField(field, value);
+			}
+
+			@java.lang.Override
+			public Builder clearField(com.google.protobuf.Descriptors.FieldDescriptor field) {
+				return super.clearField(field);
+			}
+
+			@java.lang.Override
+			public Builder clearOneof(com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+				return super.clearOneof(oneof);
+			}
+
+			@java.lang.Override
+			public Builder setRepeatedField(com.google.protobuf.Descriptors.FieldDescriptor field, int index,
+				java.lang.Object value) {
+				return super.setRepeatedField(field, index, value);
+			}
+
+			@java.lang.Override
+			public Builder addRepeatedField(com.google.protobuf.Descriptors.FieldDescriptor field,
+				java.lang.Object value) {
+				return super.addRepeatedField(field, value);
+			}
+
+			@java.lang.Override
+			public Builder mergeFrom(com.google.protobuf.Message other) {
+				if(other instanceof org.apache.sysds.protobuf.SysdsProtos.Frame) {
+					return mergeFrom((org.apache.sysds.protobuf.SysdsProtos.Frame) other);
+				}
+				else {
+					super.mergeFrom(other);
+					return this;
+				}
+			}
+
+			public Builder mergeFrom(org.apache.sysds.protobuf.SysdsProtos.Frame other) {
+				if(other == org.apache.sysds.protobuf.SysdsProtos.Frame.getDefaultInstance())
+					return this;
+				if(rowsBuilder_ == null) {
+					if(!other.rows_.isEmpty()) {
+						if(rows_.isEmpty()) {
+							rows_ = other.rows_;
+							bitField0_ = (bitField0_ & ~0x00000001);
+						}
+						else {
+							ensureRowsIsMutable();
+							rows_.addAll(other.rows_);
+						}
+						onChanged();
+					}
+				}
+				else {
+					if(!other.rows_.isEmpty()) {
+						if(rowsBuilder_.isEmpty()) {
+							rowsBuilder_.dispose();
+							rowsBuilder_ = null;
+							rows_ = other.rows_;
+							bitField0_ = (bitField0_ & ~0x00000001);
+							rowsBuilder_ = com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? getRowsFieldBuilder() : null;
+						}
+						else {
+							rowsBuilder_.addAllMessages(other.rows_);
+						}
+					}
+				}
+				this.mergeUnknownFields(other.unknownFields);
+				onChanged();
+				return this;
+			}
+
+			@java.lang.Override
+			public final boolean isInitialized() {
+				return true;
+			}
+
+			@java.lang.Override
+			public Builder mergeFrom(com.google.protobuf.CodedInputStream input,
+				com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
+				org.apache.sysds.protobuf.SysdsProtos.Frame parsedMessage = null;
+				try {
+					parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+				}
+				catch(com.google.protobuf.InvalidProtocolBufferException e) {
+					parsedMessage = (org.apache.sysds.protobuf.SysdsProtos.Frame) e.getUnfinishedMessage();
+					throw e.unwrapIOException();
+				}
+				finally {
+					if(parsedMessage != null) {
+						mergeFrom(parsedMessage);
+					}
+				}
+				return this;
+			}
+
+			private void ensureRowsIsMutable() {
+				if(!((bitField0_ & 0x00000001) != 0)) {
+					rows_ = new java.util.ArrayList<org.apache.sysds.protobuf.SysdsProtos.Row>(rows_);
+					bitField0_ |= 0x00000001;
+				}
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public java.util.List<org.apache.sysds.protobuf.SysdsProtos.Row> getRowsList() {
+				if(rowsBuilder_ == null) {
+					return java.util.Collections.unmodifiableList(rows_);
+				}
+				else {
+					return rowsBuilder_.getMessageList();
+				}
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public int getRowsCount() {
+				if(rowsBuilder_ == null) {
+					return rows_.size();
+				}
+				else {
+					return rowsBuilder_.getCount();
+				}
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public org.apache.sysds.protobuf.SysdsProtos.Row getRows(int index) {
+				if(rowsBuilder_ == null) {
+					return rows_.get(index);
+				}
+				else {
+					return rowsBuilder_.getMessage(index);
+				}
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public Builder setRows(int index, org.apache.sysds.protobuf.SysdsProtos.Row value) {
+				if(rowsBuilder_ == null) {
+					if(value == null) {
+						throw new NullPointerException();
+					}
+					ensureRowsIsMutable();
+					rows_.set(index, value);
+					onChanged();
+				}
+				else {
+					rowsBuilder_.setMessage(index, value);
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public Builder setRows(int index, org.apache.sysds.protobuf.SysdsProtos.Row.Builder builderForValue) {
+				if(rowsBuilder_ == null) {
+					ensureRowsIsMutable();
+					rows_.set(index, builderForValue.build());
+					onChanged();
+				}
+				else {
+					rowsBuilder_.setMessage(index, builderForValue.build());
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public Builder addRows(org.apache.sysds.protobuf.SysdsProtos.Row value) {
+				if(rowsBuilder_ == null) {
+					if(value == null) {
+						throw new NullPointerException();
+					}
+					ensureRowsIsMutable();
+					rows_.add(value);
+					onChanged();
+				}
+				else {
+					rowsBuilder_.addMessage(value);
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public Builder addRows(int index, org.apache.sysds.protobuf.SysdsProtos.Row value) {
+				if(rowsBuilder_ == null) {
+					if(value == null) {
+						throw new NullPointerException();
+					}
+					ensureRowsIsMutable();
+					rows_.add(index, value);
+					onChanged();
+				}
+				else {
+					rowsBuilder_.addMessage(index, value);
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public Builder addRows(org.apache.sysds.protobuf.SysdsProtos.Row.Builder builderForValue) {
+				if(rowsBuilder_ == null) {
+					ensureRowsIsMutable();
+					rows_.add(builderForValue.build());
+					onChanged();
+				}
+				else {
+					rowsBuilder_.addMessage(builderForValue.build());
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public Builder addRows(int index, org.apache.sysds.protobuf.SysdsProtos.Row.Builder builderForValue) {
+				if(rowsBuilder_ == null) {
+					ensureRowsIsMutable();
+					rows_.add(index, builderForValue.build());
+					onChanged();
+				}
+				else {
+					rowsBuilder_.addMessage(index, builderForValue.build());
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public Builder addAllRows(java.lang.Iterable<? extends org.apache.sysds.protobuf.SysdsProtos.Row> values) {
+				if(rowsBuilder_ == null) {
+					ensureRowsIsMutable();
+					com.google.protobuf.AbstractMessageLite.Builder.addAll(values, rows_);
+					onChanged();
+				}
+				else {
+					rowsBuilder_.addAllMessages(values);
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public Builder clearRows() {
+				if(rowsBuilder_ == null) {
+					rows_ = java.util.Collections.emptyList();
+					bitField0_ = (bitField0_ & ~0x00000001);
+					onChanged();
+				}
+				else {
+					rowsBuilder_.clear();
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public Builder removeRows(int index) {
+				if(rowsBuilder_ == null) {
+					ensureRowsIsMutable();
+					rows_.remove(index);
+					onChanged();
+				}
+				else {
+					rowsBuilder_.remove(index);
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public org.apache.sysds.protobuf.SysdsProtos.Row.Builder getRowsBuilder(int index) {
+				return getRowsFieldBuilder().getBuilder(index);
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public org.apache.sysds.protobuf.SysdsProtos.RowOrBuilder getRowsOrBuilder(int index) {
+				if(rowsBuilder_ == null) {
+					return rows_.get(index);
+				}
+				else {
+					return rowsBuilder_.getMessageOrBuilder(index);
+				}
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public java.util.List<? extends org.apache.sysds.protobuf.SysdsProtos.RowOrBuilder> getRowsOrBuilderList() {
+				if(rowsBuilder_ != null) {
+					return rowsBuilder_.getMessageOrBuilderList();
+				}
+				else {
+					return java.util.Collections.unmodifiableList(rows_);
+				}
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public org.apache.sysds.protobuf.SysdsProtos.Row.Builder addRowsBuilder() {
+				return getRowsFieldBuilder().addBuilder(org.apache.sysds.protobuf.SysdsProtos.Row.getDefaultInstance());
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public org.apache.sysds.protobuf.SysdsProtos.Row.Builder addRowsBuilder(int index) {
+				return getRowsFieldBuilder().addBuilder(index,
+					org.apache.sysds.protobuf.SysdsProtos.Row.getDefaultInstance());
+			}
+
+			/**
+			 * <code>repeated .sysds.Row rows = 1;</code>
+			 */
+			public java.util.List<org.apache.sysds.protobuf.SysdsProtos.Row.Builder> getRowsBuilderList() {
+				return getRowsFieldBuilder().getBuilderList();
+			}
+
+			private com.google.protobuf.RepeatedFieldBuilderV3<org.apache.sysds.protobuf.SysdsProtos.Row, org.apache.sysds.protobuf.SysdsProtos.Row.Builder, org.apache.sysds.protobuf.SysdsProtos.RowOrBuilder> getRowsFieldBuilder() {
+				if(rowsBuilder_ == null) {
+					rowsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<org.apache.sysds.protobuf.SysdsProtos.Row, org.apache.sysds.protobuf.SysdsProtos.Row.Builder, org.apache.sysds.protobuf.SysdsProtos.RowOrBuilder>(
+						rows_, ((bitField0_ & 0x00000001) != 0), getParentForChildren(), isClean());
+					rows_ = null;
+				}
+				return rowsBuilder_;
+			}
+
+			@java.lang.Override
+			public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) {
+				return super.setUnknownFields(unknownFields);
+			}
+
+			@java.lang.Override
+			public final Builder mergeUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) {
+				return super.mergeUnknownFields(unknownFields);
+			}
+
+			// @@protoc_insertion_point(builder_scope:sysds.Frame)
+		}
+
+	}
+
+	/**
+	 * Protobuf type {@code sysds.Row}
+	 */
+	public static final class Row extends com.google.protobuf.GeneratedMessageV3 implements
+		// @@protoc_insertion_point(message_implements:sysds.Row)
+		RowOrBuilder {
+		public static final int COLUMN_NAMES_FIELD_NUMBER = 1;
+		public static final int COLUMN_DATA_FIELD_NUMBER = 2;
+		public static final int COLUMN_SCHEMA_FIELD_NUMBER = 3;
+		private static final long serialVersionUID = 0L;
+		// @@protoc_insertion_point(class_scope:sysds.Row)
+		private static final org.apache.sysds.protobuf.SysdsProtos.Row DEFAULT_INSTANCE;
+		private static final com.google.protobuf.Parser<Row> PARSER = new com.google.protobuf.AbstractParser<Row>() {
+			@java.lang.Override
+			public Row parsePartialFrom(com.google.protobuf.CodedInputStream input,
+				com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+				throws com.google.protobuf.InvalidProtocolBufferException {
+				return new Row(input, extensionRegistry);
+			}
+		};
+
+		static {
+			DEFAULT_INSTANCE = new org.apache.sysds.protobuf.SysdsProtos.Row();
+		}
+
+		private com.google.protobuf.LazyStringList columnNames_;
+		private com.google.protobuf.LazyStringList columnData_;
+		private java.util.List<org.apache.sysds.protobuf.SysdsProtos.Schema> columnSchema_;
+		private byte memoizedIsInitialized = -1;
+
+		// Use Row.newBuilder() to construct.
+		private Row(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+			super(builder);
+		}
+
+		private Row() {
+			columnNames_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+			columnData_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+			columnSchema_ = java.util.Collections.emptyList();
+		}
+
+		private Row(com.google.protobuf.CodedInputStream input,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			this();
+			if(extensionRegistry == null) {
+				throw new java.lang.NullPointerException();
+			}
+			int mutable_bitField0_ = 0;
+			com.google.protobuf.UnknownFieldSet.Builder unknownFields = com.google.protobuf.UnknownFieldSet
+				.newBuilder();
+			try {
+				boolean done = false;
+				while(!done) {
+					int tag = input.readTag();
+					switch(tag) {
+						case 0:
+							done = true;
+							break;
+						case 10: {
+							java.lang.String s = input.readStringRequireUtf8();
+							if(!((mutable_bitField0_ & 0x00000001) != 0)) {
+								columnNames_ = new com.google.protobuf.LazyStringArrayList();
+								mutable_bitField0_ |= 0x00000001;
+							}
+							columnNames_.add(s);
+							break;
+						}
+						case 18: {
+							java.lang.String s = input.readStringRequireUtf8();
+							if(!((mutable_bitField0_ & 0x00000002) != 0)) {
+								columnData_ = new com.google.protobuf.LazyStringArrayList();
+								mutable_bitField0_ |= 0x00000002;
+							}
+							columnData_.add(s);
+							break;
+						}
+						case 26: {
+							if(!((mutable_bitField0_ & 0x00000004) != 0)) {
+								columnSchema_ = new java.util.ArrayList<org.apache.sysds.protobuf.SysdsProtos.Schema>();
+								mutable_bitField0_ |= 0x00000004;
+							}
+							columnSchema_.add(input.readMessage(org.apache.sysds.protobuf.SysdsProtos.Schema.parser(),
+								extensionRegistry));
+							break;
+						}
+						default: {
+							if(!parseUnknownField(input, unknownFields, extensionRegistry, tag)) {
+								done = true;
+							}
+							break;
+						}
+					}
+				}
+			}
+			catch(com.google.protobuf.InvalidProtocolBufferException e) {
+				throw e.setUnfinishedMessage(this);
+			}
+			catch(java.io.IOException e) {
+				throw new com.google.protobuf.InvalidProtocolBufferException(e).setUnfinishedMessage(this);
+			}
+			finally {
+				if(((mutable_bitField0_ & 0x00000001) != 0)) {
+					columnNames_ = columnNames_.getUnmodifiableView();
+				}
+				if(((mutable_bitField0_ & 0x00000002) != 0)) {
+					columnData_ = columnData_.getUnmodifiableView();
+				}
+				if(((mutable_bitField0_ & 0x00000004) != 0)) {
+					columnSchema_ = java.util.Collections.unmodifiableList(columnSchema_);
+				}
+				this.unknownFields = unknownFields.build();
+				makeExtensionsImmutable();
+			}
+		}
+
+		public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
+			return org.apache.sysds.protobuf.SysdsProtos.internal_static_sysds_Row_descriptor;
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Row parseFrom(java.nio.ByteBuffer data)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Row parseFrom(java.nio.ByteBuffer data,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data, extensionRegistry);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Row parseFrom(com.google.protobuf.ByteString data)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Row parseFrom(com.google.protobuf.ByteString data,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data, extensionRegistry);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Row parseFrom(byte[] data)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Row parseFrom(byte[] data,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data, extensionRegistry);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Row parseFrom(java.io.InputStream input)
+			throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Row parseFrom(java.io.InputStream input,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input, extensionRegistry);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Row parseDelimitedFrom(java.io.InputStream input)
+			throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Row parseDelimitedFrom(java.io.InputStream input,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3
+				.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Row parseFrom(com.google.protobuf.CodedInputStream input)
+			throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Row parseFrom(com.google.protobuf.CodedInputStream input,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input, extensionRegistry);
+		}
+
+		public static Builder newBuilder() {
+			return DEFAULT_INSTANCE.toBuilder();
+		}
+
+		public static Builder newBuilder(org.apache.sysds.protobuf.SysdsProtos.Row prototype) {
+			return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Row getDefaultInstance() {
+			return DEFAULT_INSTANCE;
+		}
+
+		public static com.google.protobuf.Parser<Row> parser() {
+			return PARSER;
+		}
+
+		@java.lang.Override
+		@SuppressWarnings({"unused"})
+		protected java.lang.Object newInstance(UnusedPrivateParameter unused) {
+			return new Row();
+		}
+
+		@java.lang.Override
+		public final com.google.protobuf.UnknownFieldSet getUnknownFields() {
+			return this.unknownFields;
+		}
+
+		@java.lang.Override
+		protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() {
+			return org.apache.sysds.protobuf.SysdsProtos.internal_static_sysds_Row_fieldAccessorTable
+				.ensureFieldAccessorsInitialized(org.apache.sysds.protobuf.SysdsProtos.Row.class,
+					org.apache.sysds.protobuf.SysdsProtos.Row.Builder.class);
+		}
+
+		/**
+		 * <code>repeated string column_names = 1;</code>
+		 *
+		 * @return A list containing the columnNames.
+		 */
+		public com.google.protobuf.ProtocolStringList getColumnNamesList() {
+			return columnNames_;
+		}
+
+		/**
+		 * <code>repeated string column_names = 1;</code>
+		 *
+		 * @return The count of columnNames.
+		 */
+		public int getColumnNamesCount() {
+			return columnNames_.size();
+		}
+
+		/**
+		 * <code>repeated string column_names = 1;</code>
+		 *
+		 * @param index The index of the element to return.
+		 * @return The columnNames at the given index.
+		 */
+		public java.lang.String getColumnNames(int index) {
+			return columnNames_.get(index);
+		}
+
+		/**
+		 * <code>repeated string column_names = 1;</code>
+		 *
+		 * @param index The index of the value to return.
+		 * @return The bytes of the columnNames at the given index.
+		 */
+		public com.google.protobuf.ByteString getColumnNamesBytes(int index) {
+			return columnNames_.getByteString(index);
+		}
+
+		/**
+		 * <code>repeated string column_data = 2;</code>
+		 *
+		 * @return A list containing the columnData.
+		 */
+		public com.google.protobuf.ProtocolStringList getColumnDataList() {
+			return columnData_;
+		}
+
+		/**
+		 * <code>repeated string column_data = 2;</code>
+		 *
+		 * @return The count of columnData.
+		 */
+		public int getColumnDataCount() {
+			return columnData_.size();
+		}
+
+		/**
+		 * <code>repeated string column_data = 2;</code>
+		 *
+		 * @param index The index of the element to return.
+		 * @return The columnData at the given index.
+		 */
+		public java.lang.String getColumnData(int index) {
+			return columnData_.get(index);
+		}
+
+		/**
+		 * <code>repeated string column_data = 2;</code>
+		 *
+		 * @param index The index of the value to return.
+		 * @return The bytes of the columnData at the given index.
+		 */
+		public com.google.protobuf.ByteString getColumnDataBytes(int index) {
+			return columnData_.getByteString(index);
+		}
+
+		/**
+		 * <code>repeated .sysds.Schema column_schema = 3;</code>
+		 */
+		@java.lang.Override
+		public java.util.List<org.apache.sysds.protobuf.SysdsProtos.Schema> getColumnSchemaList() {
+			return columnSchema_;
+		}
+
+		/**
+		 * <code>repeated .sysds.Schema column_schema = 3;</code>
+		 */
+		@java.lang.Override
+		public java.util.List<? extends org.apache.sysds.protobuf.SysdsProtos.SchemaOrBuilder> getColumnSchemaOrBuilderList() {
+			return columnSchema_;
+		}
+
+		/**
+		 * <code>repeated .sysds.Schema column_schema = 3;</code>
+		 */
+		@java.lang.Override
+		public int getColumnSchemaCount() {
+			return columnSchema_.size();
+		}
+
+		/**
+		 * <code>repeated .sysds.Schema column_schema = 3;</code>
+		 */
+		@java.lang.Override
+		public org.apache.sysds.protobuf.SysdsProtos.Schema getColumnSchema(int index) {
+			return columnSchema_.get(index);
+		}
+
+		/**
+		 * <code>repeated .sysds.Schema column_schema = 3;</code>
+		 */
+		@java.lang.Override
+		public org.apache.sysds.protobuf.SysdsProtos.SchemaOrBuilder getColumnSchemaOrBuilder(int index) {
+			return columnSchema_.get(index);
+		}
+
+		@java.lang.Override
+		public final boolean isInitialized() {
+			byte isInitialized = memoizedIsInitialized;
+			if(isInitialized == 1)
+				return true;
+			if(isInitialized == 0)
+				return false;
+
+			memoizedIsInitialized = 1;
+			return true;
+		}
+
+		@java.lang.Override
+		public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
+			for(int i = 0; i < columnNames_.size(); i++) {
+				com.google.protobuf.GeneratedMessageV3.writeString(output, 1, columnNames_.getRaw(i));
+			}
+			for(int i = 0; i < columnData_.size(); i++) {
+				com.google.protobuf.GeneratedMessageV3.writeString(output, 2, columnData_.getRaw(i));
+			}
+			for(int i = 0; i < columnSchema_.size(); i++) {
+				output.writeMessage(3, columnSchema_.get(i));
+			}
+			unknownFields.writeTo(output);
+		}
+
+		@java.lang.Override
+		public int getSerializedSize() {
+			int size = memoizedSize;
+			if(size != -1)
+				return size;
+
+			size = 0;
+			{
+				int dataSize = 0;
+				for(int i = 0; i < columnNames_.size(); i++) {
+					dataSize += computeStringSizeNoTag(columnNames_.getRaw(i));
+				}
+				size += dataSize;
+				size += 1 * getColumnNamesList().size();
+			}
+			{
+				int dataSize = 0;
+				for(int i = 0; i < columnData_.size(); i++) {
+					dataSize += computeStringSizeNoTag(columnData_.getRaw(i));
+				}
+				size += dataSize;
+				size += 1 * getColumnDataList().size();
+			}
+			for(int i = 0; i < columnSchema_.size(); i++) {
+				size += com.google.protobuf.CodedOutputStream.computeMessageSize(3, columnSchema_.get(i));
+			}
+			size += unknownFields.getSerializedSize();
+			memoizedSize = size;
+			return size;
+		}
+
+		@java.lang.Override
+		public boolean equals(final java.lang.Object obj) {
+			if(obj == this) {
+				return true;
+			}
+			if(!(obj instanceof org.apache.sysds.protobuf.SysdsProtos.Row)) {
+				return super.equals(obj);
+			}
+			org.apache.sysds.protobuf.SysdsProtos.Row other = (org.apache.sysds.protobuf.SysdsProtos.Row) obj;
+
+			if(!getColumnNamesList().equals(other.getColumnNamesList()))
+				return false;
+			if(!getColumnDataList().equals(other.getColumnDataList()))
+				return false;
+			if(!getColumnSchemaList().equals(other.getColumnSchemaList()))
+				return false;
+			if(!unknownFields.equals(other.unknownFields))
+				return false;
+			return true;
+		}
+
+		@java.lang.Override
+		public int hashCode() {
+			if(memoizedHashCode != 0) {
+				return memoizedHashCode;
+			}
+			int hash = 41;
+			hash = (19 * hash) + getDescriptor().hashCode();
+			if(getColumnNamesCount() > 0) {
+				hash = (37 * hash) + COLUMN_NAMES_FIELD_NUMBER;
+				hash = (53 * hash) + getColumnNamesList().hashCode();
+			}
+			if(getColumnDataCount() > 0) {
+				hash = (37 * hash) + COLUMN_DATA_FIELD_NUMBER;
+				hash = (53 * hash) + getColumnDataList().hashCode();
+			}
+			if(getColumnSchemaCount() > 0) {
+				hash = (37 * hash) + COLUMN_SCHEMA_FIELD_NUMBER;
+				hash = (53 * hash) + getColumnSchemaList().hashCode();
+			}
+			hash = (29 * hash) + unknownFields.hashCode();
+			memoizedHashCode = hash;
+			return hash;
+		}
+
+		@java.lang.Override
+		public Builder newBuilderForType() {
+			return newBuilder();
+		}
+
+		@java.lang.Override
+		public Builder toBuilder() {
+			return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this);
+		}
+
+		@java.lang.Override
+		protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+			Builder builder = new Builder(parent);
+			return builder;
+		}
+
+		@java.lang.Override
+		public com.google.protobuf.Parser<Row> getParserForType() {
+			return PARSER;
+		}
+
+		@java.lang.Override
+		public org.apache.sysds.protobuf.SysdsProtos.Row getDefaultInstanceForType() {
+			return DEFAULT_INSTANCE;
+		}
+
+		/**
+		 * Protobuf type {@code sysds.Row}
+		 */
+		public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+			// @@protoc_insertion_point(builder_implements:sysds.Row)
+			org.apache.sysds.protobuf.SysdsProtos.RowOrBuilder {
+			private int bitField0_;
+			private com.google.protobuf.LazyStringList columnNames_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+			private com.google.protobuf.LazyStringList columnData_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+			private java.util.List<org.apache.sysds.protobuf.SysdsProtos.Schema> columnSchema_ = java.util.Collections
+				.emptyList();
+			private com.google.protobuf.RepeatedFieldBuilderV3<org.apache.sysds.protobuf.SysdsProtos.Schema, org.apache.sysds.protobuf.SysdsProtos.Schema.Builder, org.apache.sysds.protobuf.SysdsProtos.SchemaOrBuilder> columnSchemaBuilder_;
+
+			// Construct using org.apache.sysds.protobuf.SysdsProtos.Row.newBuilder()
+			private Builder() {
+				maybeForceBuilderInitialization();
+			}
+
+			private Builder(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+				super(parent);
+				maybeForceBuilderInitialization();
+			}
+
+			public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
+				return org.apache.sysds.protobuf.SysdsProtos.internal_static_sysds_Row_descriptor;
+			}
+
+			@java.lang.Override
+			protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() {
+				return org.apache.sysds.protobuf.SysdsProtos.internal_static_sysds_Row_fieldAccessorTable
+					.ensureFieldAccessorsInitialized(org.apache.sysds.protobuf.SysdsProtos.Row.class,
+						org.apache.sysds.protobuf.SysdsProtos.Row.Builder.class);
+			}
+
+			private void maybeForceBuilderInitialization() {
+				if(com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders) {
+					getColumnSchemaFieldBuilder();
+				}
+			}
+
+			@java.lang.Override
+			public Builder clear() {
+				super.clear();
+				columnNames_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+				bitField0_ = (bitField0_ & ~0x00000001);
+				columnData_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+				bitField0_ = (bitField0_ & ~0x00000002);
+				if(columnSchemaBuilder_ == null) {
+					columnSchema_ = java.util.Collections.emptyList();
+					bitField0_ = (bitField0_ & ~0x00000004);
+				}
+				else {
+					columnSchemaBuilder_.clear();
+				}
+				return this;
+			}
+
+			@java.lang.Override
+			public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() {
+				return org.apache.sysds.protobuf.SysdsProtos.internal_static_sysds_Row_descriptor;
+			}
+
+			@java.lang.Override
+			public org.apache.sysds.protobuf.SysdsProtos.Row getDefaultInstanceForType() {
+				return org.apache.sysds.protobuf.SysdsProtos.Row.getDefaultInstance();
+			}
+
+			@java.lang.Override
+			public org.apache.sysds.protobuf.SysdsProtos.Row build() {
+				org.apache.sysds.protobuf.SysdsProtos.Row result = buildPartial();
+				if(!result.isInitialized()) {
+					throw newUninitializedMessageException(result);
+				}
+				return result;
+			}
+
+			@java.lang.Override
+			public org.apache.sysds.protobuf.SysdsProtos.Row buildPartial() {
+				org.apache.sysds.protobuf.SysdsProtos.Row result = new org.apache.sysds.protobuf.SysdsProtos.Row(this);
+				int from_bitField0_ = bitField0_;
+				if(((bitField0_ & 0x00000001) != 0)) {
+					columnNames_ = columnNames_.getUnmodifiableView();
+					bitField0_ = (bitField0_ & ~0x00000001);
+				}
+				result.columnNames_ = columnNames_;
+				if(((bitField0_ & 0x00000002) != 0)) {
+					columnData_ = columnData_.getUnmodifiableView();
+					bitField0_ = (bitField0_ & ~0x00000002);
+				}
+				result.columnData_ = columnData_;
+				if(columnSchemaBuilder_ == null) {
+					if(((bitField0_ & 0x00000004) != 0)) {
+						columnSchema_ = java.util.Collections.unmodifiableList(columnSchema_);
+						bitField0_ = (bitField0_ & ~0x00000004);
+					}
+					result.columnSchema_ = columnSchema_;
+				}
+				else {
+					result.columnSchema_ = columnSchemaBuilder_.build();
+				}
+				onBuilt();
+				return result;
+			}
+
+			@java.lang.Override
+			public Builder clone() {
+				return super.clone();
+			}
+
+			@java.lang.Override
+			public Builder setField(com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) {
+				return super.setField(field, value);
+			}
+
+			@java.lang.Override
+			public Builder clearField(com.google.protobuf.Descriptors.FieldDescriptor field) {
+				return super.clearField(field);
+			}
+
+			@java.lang.Override
+			public Builder clearOneof(com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+				return super.clearOneof(oneof);
+			}
+
+			@java.lang.Override
+			public Builder setRepeatedField(com.google.protobuf.Descriptors.FieldDescriptor field, int index,
+				java.lang.Object value) {
+				return super.setRepeatedField(field, index, value);
+			}
+
+			@java.lang.Override
+			public Builder addRepeatedField(com.google.protobuf.Descriptors.FieldDescriptor field,
+				java.lang.Object value) {
+				return super.addRepeatedField(field, value);
+			}
+
+			@java.lang.Override
+			public Builder mergeFrom(com.google.protobuf.Message other) {
+				if(other instanceof org.apache.sysds.protobuf.SysdsProtos.Row) {
+					return mergeFrom((org.apache.sysds.protobuf.SysdsProtos.Row) other);
+				}
+				else {
+					super.mergeFrom(other);
+					return this;
+				}
+			}
+
+			public Builder mergeFrom(org.apache.sysds.protobuf.SysdsProtos.Row other) {
+				if(other == org.apache.sysds.protobuf.SysdsProtos.Row.getDefaultInstance())
+					return this;
+				if(!other.columnNames_.isEmpty()) {
+					if(columnNames_.isEmpty()) {
+						columnNames_ = other.columnNames_;
+						bitField0_ = (bitField0_ & ~0x00000001);
+					}
+					else {
+						ensureColumnNamesIsMutable();
+						columnNames_.addAll(other.columnNames_);
+					}
+					onChanged();
+				}
+				if(!other.columnData_.isEmpty()) {
+					if(columnData_.isEmpty()) {
+						columnData_ = other.columnData_;
+						bitField0_ = (bitField0_ & ~0x00000002);
+					}
+					else {
+						ensureColumnDataIsMutable();
+						columnData_.addAll(other.columnData_);
+					}
+					onChanged();
+				}
+				if(columnSchemaBuilder_ == null) {
+					if(!other.columnSchema_.isEmpty()) {
+						if(columnSchema_.isEmpty()) {
+							columnSchema_ = other.columnSchema_;
+							bitField0_ = (bitField0_ & ~0x00000004);
+						}
+						else {
+							ensureColumnSchemaIsMutable();
+							columnSchema_.addAll(other.columnSchema_);
+						}
+						onChanged();
+					}
+				}
+				else {
+					if(!other.columnSchema_.isEmpty()) {
+						if(columnSchemaBuilder_.isEmpty()) {
+							columnSchemaBuilder_.dispose();
+							columnSchemaBuilder_ = null;
+							columnSchema_ = other.columnSchema_;
+							bitField0_ = (bitField0_ & ~0x00000004);
+							columnSchemaBuilder_ = com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? getColumnSchemaFieldBuilder() : null;
+						}
+						else {
+							columnSchemaBuilder_.addAllMessages(other.columnSchema_);
+						}
+					}
+				}
+				this.mergeUnknownFields(other.unknownFields);
+				onChanged();
+				return this;
+			}
+
+			@java.lang.Override
+			public final boolean isInitialized() {
+				return true;
+			}
+
+			@java.lang.Override
+			public Builder mergeFrom(com.google.protobuf.CodedInputStream input,
+				com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
+				org.apache.sysds.protobuf.SysdsProtos.Row parsedMessage = null;
+				try {
+					parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+				}
+				catch(com.google.protobuf.InvalidProtocolBufferException e) {
+					parsedMessage = (org.apache.sysds.protobuf.SysdsProtos.Row) e.getUnfinishedMessage();
+					throw e.unwrapIOException();
+				}
+				finally {
+					if(parsedMessage != null) {
+						mergeFrom(parsedMessage);
+					}
+				}
+				return this;
+			}
+
+			private void ensureColumnNamesIsMutable() {
+				if(!((bitField0_ & 0x00000001) != 0)) {
+					columnNames_ = new com.google.protobuf.LazyStringArrayList(columnNames_);
+					bitField0_ |= 0x00000001;
+				}
+			}
+
+			/**
+			 * <code>repeated string column_names = 1;</code>
+			 *
+			 * @return A list containing the columnNames.
+			 */
+			public com.google.protobuf.ProtocolStringList getColumnNamesList() {
+				return columnNames_.getUnmodifiableView();
+			}
+
+			/**
+			 * <code>repeated string column_names = 1;</code>
+			 *
+			 * @return The count of columnNames.
+			 */
+			public int getColumnNamesCount() {
+				return columnNames_.size();
+			}
+
+			/**
+			 * <code>repeated string column_names = 1;</code>
+			 *
+			 * @param index The index of the element to return.
+			 * @return The columnNames at the given index.
+			 */
+			public java.lang.String getColumnNames(int index) {
+				return columnNames_.get(index);
+			}
+
+			/**
+			 * <code>repeated string column_names = 1;</code>
+			 *
+			 * @param index The index of the value to return.
+			 * @return The bytes of the columnNames at the given index.
+			 */
+			public com.google.protobuf.ByteString getColumnNamesBytes(int index) {
+				return columnNames_.getByteString(index);
+			}
+
+			/**
+			 * <code>repeated string column_names = 1;</code>
+			 *
+			 * @param index The index to set the value at.
+			 * @param value The columnNames to set.
+			 * @return This builder for chaining.
+			 */
+			public Builder setColumnNames(int index, java.lang.String value) {
+				if(value == null) {
+					throw new NullPointerException();
+				}
+				ensureColumnNamesIsMutable();
+				columnNames_.set(index, value);
+				onChanged();
+				return this;
+			}
+
+			/**
+			 * <code>repeated string column_names = 1;</code>
+			 *
+			 * @param value The columnNames to add.
+			 * @return This builder for chaining.
+			 */
+			public Builder addColumnNames(java.lang.String value) {
+				if(value == null) {
+					throw new NullPointerException();
+				}
+				ensureColumnNamesIsMutable();
+				columnNames_.add(value);
+				onChanged();
+				return this;
+			}
+
+			/**
+			 * <code>repeated string column_names = 1;</code>
+			 *
+			 * @param values The columnNames to add.
+			 * @return This builder for chaining.
+			 */
+			public Builder addAllColumnNames(java.lang.Iterable<java.lang.String> values) {
+				ensureColumnNamesIsMutable();
+				com.google.protobuf.AbstractMessageLite.Builder.addAll(values, columnNames_);
+				onChanged();
+				return this;
+			}
+
+			/**
+			 * <code>repeated string column_names = 1;</code>
+			 *
+			 * @return This builder for chaining.
+			 */
+			public Builder clearColumnNames() {
+				columnNames_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+				bitField0_ = (bitField0_ & ~0x00000001);
+				onChanged();
+				return this;
+			}
+
+			/**
+			 * <code>repeated string column_names = 1;</code>
+			 *
+			 * @param value The bytes of the columnNames to add.
+			 * @return This builder for chaining.
+			 */
+			public Builder addColumnNamesBytes(com.google.protobuf.ByteString value) {
+				if(value == null) {
+					throw new NullPointerException();
+				}
+				checkByteStringIsUtf8(value);
+				ensureColumnNamesIsMutable();
+				columnNames_.add(value);
+				onChanged();
+				return this;
+			}
+
+			private void ensureColumnDataIsMutable() {
+				if(!((bitField0_ & 0x00000002) != 0)) {
+					columnData_ = new com.google.protobuf.LazyStringArrayList(columnData_);
+					bitField0_ |= 0x00000002;
+				}
+			}
+
+			/**
+			 * <code>repeated string column_data = 2;</code>
+			 *
+			 * @return A list containing the columnData.
+			 */
+			public com.google.protobuf.ProtocolStringList getColumnDataList() {
+				return columnData_.getUnmodifiableView();
+			}
+
+			/**
+			 * <code>repeated string column_data = 2;</code>
+			 *
+			 * @return The count of columnData.
+			 */
+			public int getColumnDataCount() {
+				return columnData_.size();
+			}
+
+			/**
+			 * <code>repeated string column_data = 2;</code>
+			 *
+			 * @param index The index of the element to return.
+			 * @return The columnData at the given index.
+			 */
+			public java.lang.String getColumnData(int index) {
+				return columnData_.get(index);
+			}
+
+			/**
+			 * <code>repeated string column_data = 2;</code>
+			 *
+			 * @param index The index of the value to return.
+			 * @return The bytes of the columnData at the given index.
+			 */
+			public com.google.protobuf.ByteString getColumnDataBytes(int index) {
+				return columnData_.getByteString(index);
+			}
+
+			/**
+			 * <code>repeated string column_data = 2;</code>
+			 *
+			 * @param index The index to set the value at.
+			 * @param value The columnData to set.
+			 * @return This builder for chaining.
+			 */
+			public Builder setColumnData(int index, java.lang.String value) {
+				if(value == null) {
+					throw new NullPointerException();
+				}
+				ensureColumnDataIsMutable();
+				columnData_.set(index, value);
+				onChanged();
+				return this;
+			}
+
+			/**
+			 * <code>repeated string column_data = 2;</code>
+			 *
+			 * @param value The columnData to add.
+			 * @return This builder for chaining.
+			 */
+			public Builder addColumnData(java.lang.String value) {
+				if(value == null) {
+					throw new NullPointerException();
+				}
+				ensureColumnDataIsMutable();
+				columnData_.add(value);
+				onChanged();
+				return this;
+			}
+
+			/**
+			 * <code>repeated string column_data = 2;</code>
+			 *
+			 * @param values The columnData to add.
+			 * @return This builder for chaining.
+			 */
+			public Builder addAllColumnData(java.lang.Iterable<java.lang.String> values) {
+				ensureColumnDataIsMutable();
+				com.google.protobuf.AbstractMessageLite.Builder.addAll(values, columnData_);
+				onChanged();
+				return this;
+			}
+
+			/**
+			 * <code>repeated string column_data = 2;</code>
+			 *
+			 * @return This builder for chaining.
+			 */
+			public Builder clearColumnData() {
+				columnData_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+				bitField0_ = (bitField0_ & ~0x00000002);
+				onChanged();
+				return this;
+			}
+
+			/**
+			 * <code>repeated string column_data = 2;</code>
+			 *
+			 * @param value The bytes of the columnData to add.
+			 * @return This builder for chaining.
+			 */
+			public Builder addColumnDataBytes(com.google.protobuf.ByteString value) {
+				if(value == null) {
+					throw new NullPointerException();
+				}
+				checkByteStringIsUtf8(value);
+				ensureColumnDataIsMutable();
+				columnData_.add(value);
+				onChanged();
+				return this;
+			}
+
+			private void ensureColumnSchemaIsMutable() {
+				if(!((bitField0_ & 0x00000004) != 0)) {
+					columnSchema_ = new java.util.ArrayList<org.apache.sysds.protobuf.SysdsProtos.Schema>(
+						columnSchema_);
+					bitField0_ |= 0x00000004;
+				}
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public java.util.List<org.apache.sysds.protobuf.SysdsProtos.Schema> getColumnSchemaList() {
+				if(columnSchemaBuilder_ == null) {
+					return java.util.Collections.unmodifiableList(columnSchema_);
+				}
+				else {
+					return columnSchemaBuilder_.getMessageList();
+				}
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public int getColumnSchemaCount() {
+				if(columnSchemaBuilder_ == null) {
+					return columnSchema_.size();
+				}
+				else {
+					return columnSchemaBuilder_.getCount();
+				}
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public org.apache.sysds.protobuf.SysdsProtos.Schema getColumnSchema(int index) {
+				if(columnSchemaBuilder_ == null) {
+					return columnSchema_.get(index);
+				}
+				else {
+					return columnSchemaBuilder_.getMessage(index);
+				}
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public Builder setColumnSchema(int index, org.apache.sysds.protobuf.SysdsProtos.Schema value) {
+				if(columnSchemaBuilder_ == null) {
+					if(value == null) {
+						throw new NullPointerException();
+					}
+					ensureColumnSchemaIsMutable();
+					columnSchema_.set(index, value);
+					onChanged();
+				}
+				else {
+					columnSchemaBuilder_.setMessage(index, value);
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public Builder setColumnSchema(int index,
+				org.apache.sysds.protobuf.SysdsProtos.Schema.Builder builderForValue) {
+				if(columnSchemaBuilder_ == null) {
+					ensureColumnSchemaIsMutable();
+					columnSchema_.set(index, builderForValue.build());
+					onChanged();
+				}
+				else {
+					columnSchemaBuilder_.setMessage(index, builderForValue.build());
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public Builder addColumnSchema(org.apache.sysds.protobuf.SysdsProtos.Schema value) {
+				if(columnSchemaBuilder_ == null) {
+					if(value == null) {
+						throw new NullPointerException();
+					}
+					ensureColumnSchemaIsMutable();
+					columnSchema_.add(value);
+					onChanged();
+				}
+				else {
+					columnSchemaBuilder_.addMessage(value);
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public Builder addColumnSchema(int index, org.apache.sysds.protobuf.SysdsProtos.Schema value) {
+				if(columnSchemaBuilder_ == null) {
+					if(value == null) {
+						throw new NullPointerException();
+					}
+					ensureColumnSchemaIsMutable();
+					columnSchema_.add(index, value);
+					onChanged();
+				}
+				else {
+					columnSchemaBuilder_.addMessage(index, value);
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public Builder addColumnSchema(org.apache.sysds.protobuf.SysdsProtos.Schema.Builder builderForValue) {
+				if(columnSchemaBuilder_ == null) {
+					ensureColumnSchemaIsMutable();
+					columnSchema_.add(builderForValue.build());
+					onChanged();
+				}
+				else {
+					columnSchemaBuilder_.addMessage(builderForValue.build());
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public Builder addColumnSchema(int index,
+				org.apache.sysds.protobuf.SysdsProtos.Schema.Builder builderForValue) {
+				if(columnSchemaBuilder_ == null) {
+					ensureColumnSchemaIsMutable();
+					columnSchema_.add(index, builderForValue.build());
+					onChanged();
+				}
+				else {
+					columnSchemaBuilder_.addMessage(index, builderForValue.build());
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public Builder addAllColumnSchema(
+				java.lang.Iterable<? extends org.apache.sysds.protobuf.SysdsProtos.Schema> values) {
+				if(columnSchemaBuilder_ == null) {
+					ensureColumnSchemaIsMutable();
+					com.google.protobuf.AbstractMessageLite.Builder.addAll(values, columnSchema_);
+					onChanged();
+				}
+				else {
+					columnSchemaBuilder_.addAllMessages(values);
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public Builder clearColumnSchema() {
+				if(columnSchemaBuilder_ == null) {
+					columnSchema_ = java.util.Collections.emptyList();
+					bitField0_ = (bitField0_ & ~0x00000004);
+					onChanged();
+				}
+				else {
+					columnSchemaBuilder_.clear();
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public Builder removeColumnSchema(int index) {
+				if(columnSchemaBuilder_ == null) {
+					ensureColumnSchemaIsMutable();
+					columnSchema_.remove(index);
+					onChanged();
+				}
+				else {
+					columnSchemaBuilder_.remove(index);
+				}
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public org.apache.sysds.protobuf.SysdsProtos.Schema.Builder getColumnSchemaBuilder(int index) {
+				return getColumnSchemaFieldBuilder().getBuilder(index);
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public org.apache.sysds.protobuf.SysdsProtos.SchemaOrBuilder getColumnSchemaOrBuilder(int index) {
+				if(columnSchemaBuilder_ == null) {
+					return columnSchema_.get(index);
+				}
+				else {
+					return columnSchemaBuilder_.getMessageOrBuilder(index);
+				}
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public java.util.List<? extends org.apache.sysds.protobuf.SysdsProtos.SchemaOrBuilder> getColumnSchemaOrBuilderList() {
+				if(columnSchemaBuilder_ != null) {
+					return columnSchemaBuilder_.getMessageOrBuilderList();
+				}
+				else {
+					return java.util.Collections.unmodifiableList(columnSchema_);
+				}
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public org.apache.sysds.protobuf.SysdsProtos.Schema.Builder addColumnSchemaBuilder() {
+				return getColumnSchemaFieldBuilder()
+					.addBuilder(org.apache.sysds.protobuf.SysdsProtos.Schema.getDefaultInstance());
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public org.apache.sysds.protobuf.SysdsProtos.Schema.Builder addColumnSchemaBuilder(int index) {
+				return getColumnSchemaFieldBuilder().addBuilder(index,
+					org.apache.sysds.protobuf.SysdsProtos.Schema.getDefaultInstance());
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema column_schema = 3;</code>
+			 */
+			public java.util.List<org.apache.sysds.protobuf.SysdsProtos.Schema.Builder> getColumnSchemaBuilderList() {
+				return getColumnSchemaFieldBuilder().getBuilderList();
+			}
+
+			private com.google.protobuf.RepeatedFieldBuilderV3<org.apache.sysds.protobuf.SysdsProtos.Schema, org.apache.sysds.protobuf.SysdsProtos.Schema.Builder, org.apache.sysds.protobuf.SysdsProtos.SchemaOrBuilder> getColumnSchemaFieldBuilder() {
+				if(columnSchemaBuilder_ == null) {
+					columnSchemaBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<org.apache.sysds.protobuf.SysdsProtos.Schema, org.apache.sysds.protobuf.SysdsProtos.Schema.Builder, org.apache.sysds.protobuf.SysdsProtos.SchemaOrBuilder>(
+						columnSchema_, ((bitField0_ & 0x00000004) != 0), getParentForChildren(), isClean());
+					columnSchema_ = null;
+				}
+				return columnSchemaBuilder_;
+			}
+
+			@java.lang.Override
+			public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) {
+				return super.setUnknownFields(unknownFields);
+			}
+
+			@java.lang.Override
+			public final Builder mergeUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) {
+				return super.mergeUnknownFields(unknownFields);
+			}
+
+			// @@protoc_insertion_point(builder_scope:sysds.Row)
+		}
+
+	}
+
+	/**
+	 * Protobuf type {@code sysds.Schema}
+	 */
+	public static final class Schema extends com.google.protobuf.GeneratedMessageV3 implements
+		// @@protoc_insertion_point(message_implements:sysds.Schema)
+		SchemaOrBuilder {
+		public static final int VALUETYPE_FIELD_NUMBER = 1;
+		private static final long serialVersionUID = 0L;
+		private static final com.google.protobuf.Internal.ListAdapter.Converter<java.lang.Integer, org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType> valueType_converter_ = new com.google.protobuf.Internal.ListAdapter.Converter<java.lang.Integer, org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType>() {
+			public org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType convert(java.lang.Integer from) {
+				@SuppressWarnings("deprecation")
+				org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType result = org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType
+					.valueOf(from);
+				return result == null ? org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType.UNRECOGNIZED : result;
+			}
+		};
+		// @@protoc_insertion_point(class_scope:sysds.Schema)
+		private static final org.apache.sysds.protobuf.SysdsProtos.Schema DEFAULT_INSTANCE;
+		private static final com.google.protobuf.Parser<Schema> PARSER = new com.google.protobuf.AbstractParser<Schema>() {
+			@java.lang.Override
+			public Schema parsePartialFrom(com.google.protobuf.CodedInputStream input,
+				com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+				throws com.google.protobuf.InvalidProtocolBufferException {
+				return new Schema(input, extensionRegistry);
+			}
+		};
+
+		static {
+			DEFAULT_INSTANCE = new org.apache.sysds.protobuf.SysdsProtos.Schema();
+		}
+
+		private java.util.List<java.lang.Integer> valueType_;
+		private int valueTypeMemoizedSerializedSize;
+		private byte memoizedIsInitialized = -1;
+
+		// Use Schema.newBuilder() to construct.
+		private Schema(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+			super(builder);
+		}
+
+		private Schema() {
+			valueType_ = java.util.Collections.emptyList();
+		}
+
+		private Schema(com.google.protobuf.CodedInputStream input,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			this();
+			if(extensionRegistry == null) {
+				throw new java.lang.NullPointerException();
+			}
+			int mutable_bitField0_ = 0;
+			com.google.protobuf.UnknownFieldSet.Builder unknownFields = com.google.protobuf.UnknownFieldSet
+				.newBuilder();
+			try {
+				boolean done = false;
+				while(!done) {
+					int tag = input.readTag();
+					switch(tag) {
+						case 0:
+							done = true;
+							break;
+						case 8: {
+							int rawValue = input.readEnum();
+							if(!((mutable_bitField0_ & 0x00000001) != 0)) {
+								valueType_ = new java.util.ArrayList<java.lang.Integer>();
+								mutable_bitField0_ |= 0x00000001;
+							}
+							valueType_.add(rawValue);
+							break;
+						}
+						case 10: {
+							int length = input.readRawVarint32();
+							int oldLimit = input.pushLimit(length);
+							while(input.getBytesUntilLimit() > 0) {
+								int rawValue = input.readEnum();
+								if(!((mutable_bitField0_ & 0x00000001) != 0)) {
+									valueType_ = new java.util.ArrayList<java.lang.Integer>();
+									mutable_bitField0_ |= 0x00000001;
+								}
+								valueType_.add(rawValue);
+							}
+							input.popLimit(oldLimit);
+							break;
+						}
+						default: {
+							if(!parseUnknownField(input, unknownFields, extensionRegistry, tag)) {
+								done = true;
+							}
+							break;
+						}
+					}
+				}
+			}
+			catch(com.google.protobuf.InvalidProtocolBufferException e) {
+				throw e.setUnfinishedMessage(this);
+			}
+			catch(java.io.IOException e) {
+				throw new com.google.protobuf.InvalidProtocolBufferException(e).setUnfinishedMessage(this);
+			}
+			finally {
+				if(((mutable_bitField0_ & 0x00000001) != 0)) {
+					valueType_ = java.util.Collections.unmodifiableList(valueType_);
+				}
+				this.unknownFields = unknownFields.build();
+				makeExtensionsImmutable();
+			}
+		}
+
+		public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
+			return org.apache.sysds.protobuf.SysdsProtos.internal_static_sysds_Schema_descriptor;
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Schema parseFrom(java.nio.ByteBuffer data)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Schema parseFrom(java.nio.ByteBuffer data,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data, extensionRegistry);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Schema parseFrom(com.google.protobuf.ByteString data)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Schema parseFrom(com.google.protobuf.ByteString data,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data, extensionRegistry);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Schema parseFrom(byte[] data)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Schema parseFrom(byte[] data,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+			throws com.google.protobuf.InvalidProtocolBufferException {
+			return PARSER.parseFrom(data, extensionRegistry);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Schema parseFrom(java.io.InputStream input)
+			throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Schema parseFrom(java.io.InputStream input,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input, extensionRegistry);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Schema parseDelimitedFrom(java.io.InputStream input)
+			throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Schema parseDelimitedFrom(java.io.InputStream input,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3
+				.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Schema parseFrom(com.google.protobuf.CodedInputStream input)
+			throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Schema parseFrom(com.google.protobuf.CodedInputStream input,
+			com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
+			return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input, extensionRegistry);
+		}
+
+		public static Builder newBuilder() {
+			return DEFAULT_INSTANCE.toBuilder();
+		}
+
+		public static Builder newBuilder(org.apache.sysds.protobuf.SysdsProtos.Schema prototype) {
+			return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+		}
+
+		public static org.apache.sysds.protobuf.SysdsProtos.Schema getDefaultInstance() {
+			return DEFAULT_INSTANCE;
+		}
+
+		public static com.google.protobuf.Parser<Schema> parser() {
+			return PARSER;
+		}
+
+		@java.lang.Override
+		@SuppressWarnings({"unused"})
+		protected java.lang.Object newInstance(UnusedPrivateParameter unused) {
+			return new Schema();
+		}
+
+		@java.lang.Override
+		public final com.google.protobuf.UnknownFieldSet getUnknownFields() {
+			return this.unknownFields;
+		}
+
+		@java.lang.Override
+		protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() {
+			return org.apache.sysds.protobuf.SysdsProtos.internal_static_sysds_Schema_fieldAccessorTable
+				.ensureFieldAccessorsInitialized(org.apache.sysds.protobuf.SysdsProtos.Schema.class,
+					org.apache.sysds.protobuf.SysdsProtos.Schema.Builder.class);
+		}
+
+		/**
+		 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+		 *
+		 * @return A list containing the valueType.
+		 */
+		@java.lang.Override
+		public java.util.List<org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType> getValueTypeList() {
+			return new com.google.protobuf.Internal.ListAdapter<java.lang.Integer, org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType>(
+				valueType_, valueType_converter_);
+		}
+
+		/**
+		 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+		 *
+		 * @return The count of valueType.
+		 */
+		@java.lang.Override
+		public int getValueTypeCount() {
+			return valueType_.size();
+		}
+
+		/**
+		 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+		 *
+		 * @param index The index of the element to return.
+		 * @return The valueType at the given index.
+		 */
+		@java.lang.Override
+		public org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType getValueType(int index) {
+			return valueType_converter_.convert(valueType_.get(index));
+		}
+
+		/**
+		 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+		 *
+		 * @return A list containing the enum numeric values on the wire for valueType.
+		 */
+		@java.lang.Override
+		public java.util.List<java.lang.Integer> getValueTypeValueList() {
+			return valueType_;
+		}
+
+		/**
+		 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+		 *
+		 * @param index The index of the value to return.
+		 * @return The enum numeric value on the wire of valueType at the given index.
+		 */
+		@java.lang.Override
+		public int getValueTypeValue(int index) {
+			return valueType_.get(index);
+		}
+
+		@java.lang.Override
+		public final boolean isInitialized() {
+			byte isInitialized = memoizedIsInitialized;
+			if(isInitialized == 1)
+				return true;
+			if(isInitialized == 0)
+				return false;
+
+			memoizedIsInitialized = 1;
+			return true;
+		}
+
+		@java.lang.Override
+		public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
+			getSerializedSize();
+			if(getValueTypeList().size() > 0) {
+				output.writeUInt32NoTag(10);
+				output.writeUInt32NoTag(valueTypeMemoizedSerializedSize);
+			}
+			for(int i = 0; i < valueType_.size(); i++) {
+				output.writeEnumNoTag(valueType_.get(i));
+			}
+			unknownFields.writeTo(output);
+		}
+
+		@java.lang.Override
+		public int getSerializedSize() {
+			int size = memoizedSize;
+			if(size != -1)
+				return size;
+
+			size = 0;
+			{
+				int dataSize = 0;
+				for(int i = 0; i < valueType_.size(); i++) {
+					dataSize += com.google.protobuf.CodedOutputStream.computeEnumSizeNoTag(valueType_.get(i));
+				}
+				size += dataSize;
+				if(!getValueTypeList().isEmpty()) {
+					size += 1;
+					size += com.google.protobuf.CodedOutputStream.computeUInt32SizeNoTag(dataSize);
+				}
+				valueTypeMemoizedSerializedSize = dataSize;
+			}
+			size += unknownFields.getSerializedSize();
+			memoizedSize = size;
+			return size;
+		}
+
+		@java.lang.Override
+		public boolean equals(final java.lang.Object obj) {
+			if(obj == this) {
+				return true;
+			}
+			if(!(obj instanceof org.apache.sysds.protobuf.SysdsProtos.Schema)) {
+				return super.equals(obj);
+			}
+			org.apache.sysds.protobuf.SysdsProtos.Schema other = (org.apache.sysds.protobuf.SysdsProtos.Schema) obj;
+
+			if(!valueType_.equals(other.valueType_))
+				return false;
+			if(!unknownFields.equals(other.unknownFields))
+				return false;
+			return true;
+		}
+
+		@java.lang.Override
+		public int hashCode() {
+			if(memoizedHashCode != 0) {
+				return memoizedHashCode;
+			}
+			int hash = 41;
+			hash = (19 * hash) + getDescriptor().hashCode();
+			if(getValueTypeCount() > 0) {
+				hash = (37 * hash) + VALUETYPE_FIELD_NUMBER;
+				hash = (53 * hash) + valueType_.hashCode();
+			}
+			hash = (29 * hash) + unknownFields.hashCode();
+			memoizedHashCode = hash;
+			return hash;
+		}
+
+		@java.lang.Override
+		public Builder newBuilderForType() {
+			return newBuilder();
+		}
+
+		@java.lang.Override
+		public Builder toBuilder() {
+			return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this);
+		}
+
+		@java.lang.Override
+		protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+			Builder builder = new Builder(parent);
+			return builder;
+		}
+
+		@java.lang.Override
+		public com.google.protobuf.Parser<Schema> getParserForType() {
+			return PARSER;
+		}
+
+		@java.lang.Override
+		public org.apache.sysds.protobuf.SysdsProtos.Schema getDefaultInstanceForType() {
+			return DEFAULT_INSTANCE;
+		}
+
+		/**
+		 * Protobuf enum {@code sysds.Schema.ValueType}
+		 */
+		public enum ValueType implements com.google.protobuf.ProtocolMessageEnum {
+			/**
+			 * <code>FP32 = 0;</code>
+			 */
+			FP32(0),
+			/**
+			 * <code>FP64 = 1;</code>
+			 */
+			FP64(1),
+			/**
+			 * <code>INT32 = 2;</code>
+			 */
+			INT32(2),
+			/**
+			 * <code>INT64 = 3;</code>
+			 */
+			INT64(3),
+			/**
+			 * <code>BOOLEAN = 4;</code>
+			 */
+			BOOLEAN(4),
+			/**
+			 * <code>STRING = 5;</code>
+			 */
+			STRING(5),
+			/**
+			 * <code>UNKNOWN = 6;</code>
+			 */
+			UNKNOWN(6), UNRECOGNIZED(-1),;
+
+			/**
+			 * <code>FP32 = 0;</code>
+			 */
+			public static final int FP32_VALUE = 0;
+			/**
+			 * <code>FP64 = 1;</code>
+			 */
+			public static final int FP64_VALUE = 1;
+			/**
+			 * <code>INT32 = 2;</code>
+			 */
+			public static final int INT32_VALUE = 2;
+			/**
+			 * <code>INT64 = 3;</code>
+			 */
+			public static final int INT64_VALUE = 3;
+			/**
+			 * <code>BOOLEAN = 4;</code>
+			 */
+			public static final int BOOLEAN_VALUE = 4;
+			/**
+			 * <code>STRING = 5;</code>
+			 */
+			public static final int STRING_VALUE = 5;
+			/**
+			 * <code>UNKNOWN = 6;</code>
+			 */
+			public static final int UNKNOWN_VALUE = 6;
+			private static final com.google.protobuf.Internal.EnumLiteMap<ValueType> internalValueMap = new com.google.protobuf.Internal.EnumLiteMap<ValueType>() {
+				public ValueType findValueByNumber(int number) {
+					return ValueType.forNumber(number);
+				}
+			};
+			private static final ValueType[] VALUES = values();
+			private final int value;
+
+			private ValueType(int value) {
+				this.value = value;
+			}
+
+			/**
+			 * @param value The numeric wire value of the corresponding enum entry.
+			 * @return The enum associated with the given numeric wire value.
+			 * @deprecated Use {@link #forNumber(int)} instead.
+			 */
+			@java.lang.Deprecated
+			public static ValueType valueOf(int value) {
+				return forNumber(value);
+			}
+
+			/**
+			 * @param value The numeric wire value of the corresponding enum entry.
+			 * @return The enum associated with the given numeric wire value.
+			 */
+			public static ValueType forNumber(int value) {
+				switch(value) {
+					case 0:
+						return FP32;
+					case 1:
+						return FP64;
+					case 2:
+						return INT32;
+					case 3:
+						return INT64;
+					case 4:
+						return BOOLEAN;
+					case 5:
+						return STRING;
+					case 6:
+						return UNKNOWN;
+					default:
+						return null;
+				}
+			}
+
+			public static com.google.protobuf.Internal.EnumLiteMap<ValueType> internalGetValueMap() {
+				return internalValueMap;
+			}
+
+			public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() {
+				return org.apache.sysds.protobuf.SysdsProtos.Schema.getDescriptor().getEnumTypes().get(0);
+			}
+
+			public static ValueType valueOf(com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+				if(desc.getType() != getDescriptor()) {
+					throw new java.lang.IllegalArgumentException("EnumValueDescriptor is not for this type.");
+				}
+				if(desc.getIndex() == -1) {
+					return UNRECOGNIZED;
+				}
+				return VALUES[desc.getIndex()];
+			}
+
+			public final int getNumber() {
+				if(this == UNRECOGNIZED) {
+					throw new java.lang.IllegalArgumentException("Can't get the number of an unknown enum value.");
+				}
+				return value;
+			}
+
+			public final com.google.protobuf.Descriptors.EnumValueDescriptor getValueDescriptor() {
+				if(this == UNRECOGNIZED) {
+					throw new java.lang.IllegalStateException(
+						"Can't get the descriptor of an unrecognized enum value.");
+				}
+				return getDescriptor().getValues().get(ordinal());
+			}
+
+			public final com.google.protobuf.Descriptors.EnumDescriptor getDescriptorForType() {
+				return getDescriptor();
+			}
+
+			// @@protoc_insertion_point(enum_scope:sysds.Schema.ValueType)
+		}
+
+		/**
+		 * Protobuf type {@code sysds.Schema}
+		 */
+		public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+			// @@protoc_insertion_point(builder_implements:sysds.Schema)
+			org.apache.sysds.protobuf.SysdsProtos.SchemaOrBuilder {
+			private int bitField0_;
+			private java.util.List<java.lang.Integer> valueType_ = java.util.Collections.emptyList();
+
+			// Construct using org.apache.sysds.protobuf.SysdsProtos.Schema.newBuilder()
+			private Builder() {
+				maybeForceBuilderInitialization();
+			}
+
+			private Builder(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+				super(parent);
+				maybeForceBuilderInitialization();
+			}
+
+			public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
+				return org.apache.sysds.protobuf.SysdsProtos.internal_static_sysds_Schema_descriptor;
+			}
+
+			@java.lang.Override
+			protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() {
+				return org.apache.sysds.protobuf.SysdsProtos.internal_static_sysds_Schema_fieldAccessorTable
+					.ensureFieldAccessorsInitialized(org.apache.sysds.protobuf.SysdsProtos.Schema.class,
+						org.apache.sysds.protobuf.SysdsProtos.Schema.Builder.class);
+			}
+
+			private void maybeForceBuilderInitialization() {
+				if(com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders) {
+				}
+			}
+
+			@java.lang.Override
+			public Builder clear() {
+				super.clear();
+				valueType_ = java.util.Collections.emptyList();
+				bitField0_ = (bitField0_ & ~0x00000001);
+				return this;
+			}
+
+			@java.lang.Override
+			public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() {
+				return org.apache.sysds.protobuf.SysdsProtos.internal_static_sysds_Schema_descriptor;
+			}
+
+			@java.lang.Override
+			public org.apache.sysds.protobuf.SysdsProtos.Schema getDefaultInstanceForType() {
+				return org.apache.sysds.protobuf.SysdsProtos.Schema.getDefaultInstance();
+			}
+
+			@java.lang.Override
+			public org.apache.sysds.protobuf.SysdsProtos.Schema build() {
+				org.apache.sysds.protobuf.SysdsProtos.Schema result = buildPartial();
+				if(!result.isInitialized()) {
+					throw newUninitializedMessageException(result);
+				}
+				return result;
+			}
+
+			@java.lang.Override
+			public org.apache.sysds.protobuf.SysdsProtos.Schema buildPartial() {
+				org.apache.sysds.protobuf.SysdsProtos.Schema result = new org.apache.sysds.protobuf.SysdsProtos.Schema(
+					this);
+				int from_bitField0_ = bitField0_;
+				if(((bitField0_ & 0x00000001) != 0)) {
+					valueType_ = java.util.Collections.unmodifiableList(valueType_);
+					bitField0_ = (bitField0_ & ~0x00000001);
+				}
+				result.valueType_ = valueType_;
+				onBuilt();
+				return result;
+			}
+
+			@java.lang.Override
+			public Builder clone() {
+				return super.clone();
+			}
+
+			@java.lang.Override
+			public Builder setField(com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) {
+				return super.setField(field, value);
+			}
+
+			@java.lang.Override
+			public Builder clearField(com.google.protobuf.Descriptors.FieldDescriptor field) {
+				return super.clearField(field);
+			}
+
+			@java.lang.Override
+			public Builder clearOneof(com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+				return super.clearOneof(oneof);
+			}
+
+			@java.lang.Override
+			public Builder setRepeatedField(com.google.protobuf.Descriptors.FieldDescriptor field, int index,
+				java.lang.Object value) {
+				return super.setRepeatedField(field, index, value);
+			}
+
+			@java.lang.Override
+			public Builder addRepeatedField(com.google.protobuf.Descriptors.FieldDescriptor field,
+				java.lang.Object value) {
+				return super.addRepeatedField(field, value);
+			}
+
+			@java.lang.Override
+			public Builder mergeFrom(com.google.protobuf.Message other) {
+				if(other instanceof org.apache.sysds.protobuf.SysdsProtos.Schema) {
+					return mergeFrom((org.apache.sysds.protobuf.SysdsProtos.Schema) other);
+				}
+				else {
+					super.mergeFrom(other);
+					return this;
+				}
+			}
+
+			public Builder mergeFrom(org.apache.sysds.protobuf.SysdsProtos.Schema other) {
+				if(other == org.apache.sysds.protobuf.SysdsProtos.Schema.getDefaultInstance())
+					return this;
+				if(!other.valueType_.isEmpty()) {
+					if(valueType_.isEmpty()) {
+						valueType_ = other.valueType_;
+						bitField0_ = (bitField0_ & ~0x00000001);
+					}
+					else {
+						ensureValueTypeIsMutable();
+						valueType_.addAll(other.valueType_);
+					}
+					onChanged();
+				}
+				this.mergeUnknownFields(other.unknownFields);
+				onChanged();
+				return this;
+			}
+
+			@java.lang.Override
+			public final boolean isInitialized() {
+				return true;
+			}
+
+			@java.lang.Override
+			public Builder mergeFrom(com.google.protobuf.CodedInputStream input,
+				com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
+				org.apache.sysds.protobuf.SysdsProtos.Schema parsedMessage = null;
+				try {
+					parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+				}
+				catch(com.google.protobuf.InvalidProtocolBufferException e) {
+					parsedMessage = (org.apache.sysds.protobuf.SysdsProtos.Schema) e.getUnfinishedMessage();
+					throw e.unwrapIOException();
+				}
+				finally {
+					if(parsedMessage != null) {
+						mergeFrom(parsedMessage);
+					}
+				}
+				return this;
+			}
+
+			private void ensureValueTypeIsMutable() {
+				if(!((bitField0_ & 0x00000001) != 0)) {
+					valueType_ = new java.util.ArrayList<java.lang.Integer>(valueType_);
+					bitField0_ |= 0x00000001;
+				}
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+			 *
+			 * @return A list containing the valueType.
+			 */
+			public java.util.List<org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType> getValueTypeList() {
+				return new com.google.protobuf.Internal.ListAdapter<java.lang.Integer, org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType>(
+					valueType_, valueType_converter_);
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+			 *
+			 * @return The count of valueType.
+			 */
+			public int getValueTypeCount() {
+				return valueType_.size();
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+			 *
+			 * @param index The index of the element to return.
+			 * @return The valueType at the given index.
+			 */
+			public org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType getValueType(int index) {
+				return valueType_converter_.convert(valueType_.get(index));
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+			 *
+			 * @param index The index to set the value at.
+			 * @param value The valueType to set.
+			 * @return This builder for chaining.
+			 */
+			public Builder setValueType(int index, org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType value) {
+				if(value == null) {
+					throw new NullPointerException();
+				}
+				ensureValueTypeIsMutable();
+				valueType_.set(index, value.getNumber());
+				onChanged();
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+			 *
+			 * @param value The valueType to add.
+			 * @return This builder for chaining.
+			 */
+			public Builder addValueType(org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType value) {
+				if(value == null) {
+					throw new NullPointerException();
+				}
+				ensureValueTypeIsMutable();
+				valueType_.add(value.getNumber());
+				onChanged();
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+			 *
+			 * @param values The valueType to add.
+			 * @return This builder for chaining.
+			 */
+			public Builder addAllValueType(
+				java.lang.Iterable<? extends org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType> values) {
+				ensureValueTypeIsMutable();
+				for(org.apache.sysds.protobuf.SysdsProtos.Schema.ValueType value : values) {
+					valueType_.add(value.getNumber());
+				}
+				onChanged();
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+			 *
+			 * @return This builder for chaining.
+			 */
+			public Builder clearValueType() {
+				valueType_ = java.util.Collections.emptyList();
+				bitField0_ = (bitField0_ & ~0x00000001);
+				onChanged();
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+			 *
+			 * @return A list containing the enum numeric values on the wire for valueType.
+			 */
+			public java.util.List<java.lang.Integer> getValueTypeValueList() {
+				return java.util.Collections.unmodifiableList(valueType_);
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+			 *
+			 * @param index The index of the value to return.
+			 * @return The enum numeric value on the wire of valueType at the given index.
+			 */
+			public int getValueTypeValue(int index) {
+				return valueType_.get(index);
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+			 *
+			 * @param index The index of the value to return.
+			 * @return The enum numeric value on the wire of valueType at the given index.
+			 * @return This builder for chaining.
+			 */
+			public Builder setValueTypeValue(int index, int value) {
+				ensureValueTypeIsMutable();
+				valueType_.set(index, value);
+				onChanged();
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+			 *
+			 * @param value The enum numeric value on the wire for valueType to add.
+			 * @return This builder for chaining.
+			 */
+			public Builder addValueTypeValue(int value) {
+				ensureValueTypeIsMutable();
+				valueType_.add(value);
+				onChanged();
+				return this;
+			}
+
+			/**
+			 * <code>repeated .sysds.Schema.ValueType valueType = 1;</code>
+			 *
+			 * @param values The enum numeric values on the wire for valueType to add.
+			 * @return This builder for chaining.
+			 */
+			public Builder addAllValueTypeValue(java.lang.Iterable<java.lang.Integer> values) {
+				ensureValueTypeIsMutable();
+				for(int value : values) {
+					valueType_.add(value);
+				}
+				onChanged();
+				return this;
+			}
+
+			@java.lang.Override
+			public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) {
+				return super.setUnknownFields(unknownFields);
+			}
+
+			@java.lang.Override
+			public final Builder mergeUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) {
+				return super.mergeUnknownFields(unknownFields);
+			}
+
+			// @@protoc_insertion_point(builder_scope:sysds.Schema)
+		}
+
+	}
+
+	// @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/src/main/java/org/apache/sysds/runtime/io/FrameReaderFactory.java b/src/main/java/org/apache/sysds/runtime/io/FrameReaderFactory.java
index 4510133..9b38d96 100644
--- a/src/main/java/org/apache/sysds/runtime/io/FrameReaderFactory.java
+++ b/src/main/java/org/apache/sysds/runtime/io/FrameReaderFactory.java
@@ -19,51 +19,52 @@
 
 package org.apache.sysds.runtime.io;
 
-import org.apache.sysds.conf.ConfigurationManager;
 import org.apache.sysds.common.Types.FileFormat;
 import org.apache.sysds.conf.CompilerConfig.ConfigType;
+import org.apache.sysds.conf.ConfigurationManager;
 import org.apache.sysds.runtime.DMLRuntimeException;
 
-public class FrameReaderFactory
-{
-	public static FrameReader createFrameReader( FileFormat fmt ) {
-		FileFormatProperties props = (fmt==FileFormat.CSV) ?
-			new FileFormatPropertiesCSV() : null;
+public class FrameReaderFactory {
+	public static FrameReader createFrameReader(FileFormat fmt) {
+		FileFormatProperties props = (fmt == FileFormat.CSV) ? new FileFormatPropertiesCSV() : null;
 		return createFrameReader(fmt, props);
 	}
 
-	public static FrameReader createFrameReader( FileFormat fmt, FileFormatProperties props ) {
+	public static FrameReader createFrameReader(FileFormat fmt, FileFormatProperties props) {
 		FrameReader reader = null;
 
 		switch(fmt) {
 			case TEXT:
-				if( ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_TEXTFORMATS) )
+				if(ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_TEXTFORMATS))
 					reader = new FrameReaderTextCellParallel();
 				else
 					reader = new FrameReaderTextCell();
 				break;
-				
+
 			case CSV:
-				if( props!=null && !(props instanceof FileFormatPropertiesCSV) )
+				if(props != null && !(props instanceof FileFormatPropertiesCSV))
 					throw new DMLRuntimeException("Wrong type of file format properties for CSV writer.");
-				if( ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_TEXTFORMATS) )
-					reader = new FrameReaderTextCSVParallel( (FileFormatPropertiesCSV)props );
+				if(ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_TEXTFORMATS))
+					reader = new FrameReaderTextCSVParallel((FileFormatPropertiesCSV) props);
 				else
-					reader = new FrameReaderTextCSV( (FileFormatPropertiesCSV)props );
+					reader = new FrameReaderTextCSV((FileFormatPropertiesCSV) props);
 				break;
-				
+
 			case BINARY:
-				if( ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_BINARYFORMATS) )
+				if(ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_BINARYFORMATS))
 					reader = new FrameReaderBinaryBlockParallel();
 				else
 					reader = new FrameReaderBinaryBlock();
 				break;
-				
+			case PROTO:
+				// TODO performance improvement: add parallel reader
+				reader = new FrameReaderProto();
+				break;
+
 			default:
-				throw new DMLRuntimeException(
-					"Failed to create frame reader for unknown format: " + fmt.toString());
+				throw new DMLRuntimeException("Failed to create frame reader for unknown format: " + fmt.toString());
 		}
-		
+
 		return reader;
 	}
 }
diff --git a/src/main/java/org/apache/sysds/runtime/io/FrameReaderProto.java b/src/main/java/org/apache/sysds/runtime/io/FrameReaderProto.java
new file mode 100644
index 0000000..34f0dbb
--- /dev/null
+++ b/src/main/java/org/apache/sysds/runtime/io/FrameReaderProto.java
@@ -0,0 +1,87 @@
+/*
+ * 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.runtime.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.hadoop.fs.FSDataInputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.mapred.FileInputFormat;
+import org.apache.hadoop.mapred.JobConf;
+import org.apache.sysds.common.Types;
+import org.apache.sysds.conf.ConfigurationManager;
+import org.apache.sysds.protobuf.SysdsProtos;
+import org.apache.sysds.runtime.DMLRuntimeException;
+import org.apache.sysds.runtime.matrix.data.FrameBlock;
+import org.apache.sysds.runtime.util.UtilFunctions;
+
+public class FrameReaderProto extends FrameReader {
+	@Override
+	public FrameBlock readFrameFromHDFS(String fname, Types.ValueType[] schema, String[] names, long rlen, long clen)
+		throws IOException {
+		// prepare file access
+		JobConf jobConf = new JobConf(ConfigurationManager.getCachedJobConf());
+		Path path = new Path(fname);
+		FileSystem fileSystem = IOUtilFunctions.getFileSystem(path, jobConf);
+		FileInputFormat.addInputPath(jobConf, path);
+
+		// check existence and non-empty file
+		checkValidInputFile(fileSystem, path);
+
+		Types.ValueType[] outputSchema = createOutputSchema(schema, clen);
+		String[] outputNames = createOutputNames(names, clen);
+		FrameBlock outputFrameBlock = createOutputFrameBlock(outputSchema, outputNames, rlen);
+
+		// core read (sequential/parallel)
+		readProtoFrameFromHDFS(path, fileSystem, outputFrameBlock, rlen, clen);
+		return outputFrameBlock;
+	}
+
+	private void readProtoFrameFromHDFS(Path path, FileSystem fileSystem, FrameBlock dest, long rlen, long clen)
+		throws IOException {
+		SysdsProtos.Frame frame = readProtoFrameFromFile(path, fileSystem);
+		for(int row = 0; row < rlen; row++) {
+			for(int column = 0; column < clen; column++) {
+				dest.set(row,
+					column,
+					UtilFunctions.stringToObject(Types.ValueType.STRING, frame.getRows(row).getColumnData(column)));
+			}
+		}
+		IOUtilFunctions.deleteCrcFilesFromLocalFileSystem(fileSystem, path);
+	}
+
+	private SysdsProtos.Frame readProtoFrameFromFile(Path path, FileSystem fileSystem) throws IOException {
+		FSDataInputStream fsDataInputStream = fileSystem.open(path);
+		try {
+			return SysdsProtos.Frame.newBuilder().mergeFrom(fsDataInputStream).build();
+		}
+		finally {
+			IOUtilFunctions.closeSilently(fsDataInputStream);
+		}
+	}
+
+	@Override
+	public FrameBlock readFrameFromInputStream(InputStream is, Types.ValueType[] schema, String[] names, long rlen,
+		long clen) {
+		throw new DMLRuntimeException("Not implemented yet.");
+	}
+}
diff --git a/src/main/java/org/apache/sysds/runtime/io/FrameWriterFactory.java b/src/main/java/org/apache/sysds/runtime/io/FrameWriterFactory.java
index f34e458..3df8191 100644
--- a/src/main/java/org/apache/sysds/runtime/io/FrameWriterFactory.java
+++ b/src/main/java/org/apache/sysds/runtime/io/FrameWriterFactory.java
@@ -55,6 +55,11 @@ public class FrameWriterFactory
 				else
 					writer = new FrameWriterBinaryBlock();
 				break;
+
+			case PROTO:
+				// TODO performance improvement: add parallel reader
+				writer = new FrameWriterProto();
+				break;
 			
 			default:
 				throw new DMLRuntimeException("Failed to create frame writer for unknown format: " + fmt.toString());
diff --git a/src/main/java/org/apache/sysds/runtime/io/FrameWriterProto.java b/src/main/java/org/apache/sysds/runtime/io/FrameWriterProto.java
new file mode 100644
index 0000000..1e0ae4d
--- /dev/null
+++ b/src/main/java/org/apache/sysds/runtime/io/FrameWriterProto.java
@@ -0,0 +1,80 @@
+/*
+ * 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.runtime.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.mapred.JobConf;
+import org.apache.sysds.conf.ConfigurationManager;
+import org.apache.sysds.protobuf.SysdsProtos;
+import org.apache.sysds.runtime.matrix.data.FrameBlock;
+import org.apache.sysds.runtime.util.HDFSTool;
+
+public class FrameWriterProto extends FrameWriter {
+	@Override
+	public void writeFrameToHDFS(FrameBlock src, String fname, long rlen, long clen) throws IOException {
+		// prepare file access
+		JobConf job = new JobConf(ConfigurationManager.getCachedJobConf());
+		Path path = new Path(fname);
+
+		// if the file already exists on HDFS, remove it.
+		HDFSTool.deleteFileIfExistOnHDFS(fname);
+
+		// validity check frame dimensions
+		if(src.getNumRows() != rlen || src.getNumColumns() != clen) {
+			throw new IOException("Frame dimensions mismatch with metadata: " + src.getNumRows() + "x"
+				+ src.getNumColumns() + " vs " + rlen + "x" + clen + ".");
+		}
+
+		writeProtoFrameToHDFS(path, job, src, rlen, clen);
+	}
+
+	protected void writeProtoFrameToHDFS(Path path, JobConf jobConf, FrameBlock src, long rlen, long clen)
+		throws IOException {
+		FileSystem fileSystem = IOUtilFunctions.getFileSystem(path, jobConf);
+		writeProtoFrameToFile(path, fileSystem, src, 0, (int) rlen);
+		IOUtilFunctions.deleteCrcFilesFromLocalFileSystem(fileSystem, path);
+	}
+
+	protected void writeProtoFrameToFile(Path path, FileSystem fileSystem, FrameBlock src, int lowerRowBound,
+		int upperRowBound) throws IOException {
+		// Current Protobuf protocol is based on 32-bit signed arithmetic, meaning potential problems in files of > 2GB.
+		// see:
+		// https://stackoverflow.com/questions/34128872/google-protobuf-maximum-size#:~:text=Protobuf%20has%20a%20hard%20limit,manually%20if%20you%20need%20to.
+		OutputStream outputStream = fileSystem.create(path, true);
+		SysdsProtos.Frame.Builder frameBuilder = SysdsProtos.Frame.newBuilder();
+		try {
+			Iterator<String[]> stringRowIterator = src.getStringRowIterator(lowerRowBound, upperRowBound);
+			while(stringRowIterator.hasNext()) {
+				String[] row = stringRowIterator.next();
+				frameBuilder.addRowsBuilder().addAllColumnData(Arrays.asList(row));
+			}
+			frameBuilder.build().writeTo(outputStream);
+		}
+		finally {
+			IOUtilFunctions.closeSilently(outputStream);
+		}
+	}
+}
diff --git a/src/main/resources/protobuf/Frame.proto b/src/main/resources/protobuf/Frame.proto
new file mode 100644
index 0000000..f459bcf
--- /dev/null
+++ b/src/main/resources/protobuf/Frame.proto
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+syntax = "proto3";
+package sysds;
+option java_package = "org.apache.sysds.protobuf";
+option java_outer_classname = "SysdsProtos";
+option java_multiple_files = false;
+
+message Frame {
+    repeated Row rows = 1;
+}
+
+message Row {
+    repeated string column_names = 1;
+    repeated string column_data = 2;
+    repeated Schema column_schema = 3;
+}
+
+message Schema {
+    enum ValueType {
+        FP32 = 0;
+        FP64 = 1;
+        INT32 = 2;
+        INT64 = 3;
+        BOOLEAN = 4;
+        STRING = 5;
+        UNKNOWN = 6;
+    }
+    repeated ValueType valueType = 1;
+}
diff --git a/src/test/java/org/apache/sysds/test/functions/io/proto/FrameReaderWriterProtoTest.java b/src/test/java/org/apache/sysds/test/functions/io/proto/FrameReaderWriterProtoTest.java
new file mode 100644
index 0000000..38541f5
--- /dev/null
+++ b/src/test/java/org/apache/sysds/test/functions/io/proto/FrameReaderWriterProtoTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.test.functions.io.proto;
+
+import java.io.IOException;
+import java.util.Random;
+
+import org.apache.sysds.common.Types;
+import org.apache.sysds.runtime.io.FrameReader;
+import org.apache.sysds.runtime.io.FrameReaderFactory;
+import org.apache.sysds.runtime.io.FrameWriter;
+import org.apache.sysds.runtime.io.FrameWriterFactory;
+import org.apache.sysds.runtime.matrix.data.FrameBlock;
+import org.apache.sysds.runtime.util.DataConverter;
+import org.apache.sysds.test.TestUtils;
+import org.junit.Test;
+
+public class FrameReaderWriterProtoTest {
+
+	private static final String FILENAME_SINGLE = "target/testTemp/functions/data/FrameReaderWriterProtoTest/testFrameBlock.proto";
+	private static final long SEED = 4669201;
+
+	private FrameWriter frameWriterProto = FrameWriterFactory.createFrameWriter(Types.FileFormat.PROTO);
+	private FrameReader frameReaderProto = FrameReaderFactory.createFrameReader(Types.FileFormat.PROTO);
+
+	@Test
+	public void testWriteReadFrameBlockWithSinleRowAndSingleColumnFromHDFS() throws IOException {
+		testWriteReadFrameBlockWith(1, 1);
+	}
+
+	@Test
+	public void testWriteReadFrameBlockWithSingleRowAndMultipleColumnsFromHDFS() throws IOException {
+		testWriteReadFrameBlockWith(1, 23);
+	}
+
+	@Test
+	public void testWriteReadFrameBlockWithMultipleRowsAndSingleColumnFromHDFS() throws IOException {
+		testWriteReadFrameBlockWith(21, 1);
+	}
+
+	@Test
+	public void testWriteReadFrameBlockWithSmallMultipleRowsAndMultipleColumnsFromHDFS() throws IOException {
+		testWriteReadFrameBlockWith(42, 35);
+	}
+
+	@Test
+	public void testWriteReadFrameBlockWithMediumMultipleRowsAndMultipleColumnsFromHDFS() throws IOException {
+		testWriteReadFrameBlockWith(694, 164);
+	}
+
+	public void testWriteReadFrameBlockWith(int rows, int cols) throws IOException {
+		final Random random = new Random(SEED);
+		Types.ValueType[] schema = TestUtils.generateRandomSchema(cols, random);
+		FrameBlock expectedFrame = TestUtils.generateRandomFrameBlock(rows, cols, schema, random);
+
+		frameWriterProto.writeFrameToHDFS(expectedFrame, FILENAME_SINGLE, rows, cols);
+		FrameBlock actualFrame = frameReaderProto.readFrameFromHDFS(FILENAME_SINGLE, schema, rows, cols);
+
+		String[][] expected = DataConverter.convertToStringFrame(expectedFrame);
+		String[][] actual = DataConverter.convertToStringFrame(actualFrame);
+
+		TestUtils.compareFrames(expected, actual, rows, cols);
+	}
+}