| /* |
| * 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.common; |
| |
| import java.util.Arrays; |
| |
| import org.apache.sysds.runtime.DMLRuntimeException; |
| |
| /** |
| * Common type information for the entire SystemDS. |
| */ |
| public interface Types { |
| |
| /** |
| * Execution mode for entire script. This setting specify which {@link ExecType}s are allowed. |
| */ |
| public enum ExecMode { |
| /** Execute all operations in {@link ExecType#CP}, {@link ExecType#OOC} and if available {@link ExecType#GPU} */ |
| SINGLE_NODE, |
| /** |
| * The default and encouraged ExecMode. Execute operations while leveraging all available options: |
| * {@link ExecType#CP}, distributed in {@link ExecType#SPARK}, and if available {@link ExecType#GPU} |
| */ |
| HYBRID, |
| /** Execute all operations in {@link ExecType#SPARK} */ |
| SPARK |
| } |
| |
| /** Execution type of individual operations. */ |
| public enum ExecType { |
| /** Control Program: This ExecType indicate that the operation should be executed in the controller. */ |
| CP, |
| /** |
| * Control Program File: This ExecType indicate that the operation should be executed in the controller, and the |
| * result be spilled to disk because the intermediate is potentially bigger than memory. |
| */ |
| CP_FILE, |
| /** Spark ExecType indicate that the execution should be performed as a Spark Instruction */ |
| SPARK, |
| /** GPU ExecType indicate that the execution should be performed on a GPU */ |
| GPU, |
| /** FED: indicate that the instruction should be executed as a Federated instruction */ |
| FED, |
| /** Out of Core: indicate that the operation should be executed out of core. */ |
| OOC, |
| /** invalid is used for debugging or if it is undecided where the current instruction should be executed */ |
| INVALID |
| } |
| |
| /** Data types that can contain different ValueTypes internally. */ |
| public enum DataType{ |
| /** N Dimensional numeric DataType */ |
| TENSOR, |
| /** Two or One Dimensional numeric DataType. We use internally Matrix for both Vectors and Matrices */ |
| MATRIX, |
| /** One cell numeric or String based DataType */ |
| SCALAR, |
| /** Two or One Dimensional heterogeneous DataType */ |
| FRAME, |
| /** List primitive able to contain any other DataType at indexes*/ |
| LIST, |
| /** Unknown DataType, used to indicate uncertainty, and for testing */ |
| UNKNOWN, |
| //TODO remove from Data Type -> generic object |
| ENCRYPTED_CIPHER, ENCRYPTED_PLAIN; |
| |
| public boolean isMatrix() { |
| return this == MATRIX; |
| } |
| |
| public boolean isTensor() { |
| return this == TENSOR; |
| } |
| |
| public boolean isFrame() { |
| return this == FRAME; |
| } |
| |
| public boolean isMatrixOrFrame() { |
| return isMatrix() || isFrame(); |
| } |
| |
| public boolean isScalar() { |
| return this == SCALAR; |
| } |
| |
| public boolean isList() { |
| return this == LIST; |
| } |
| |
| public boolean isUnknown() { |
| return this == UNKNOWN; |
| } |
| } |
| |
| /** |
| * Value types (int, double, string, boolean, unknown). |
| */ |
| public enum ValueType { |
| UINT4, UINT8, // Used for parsing in UINT values from numpy. |
| FP32, FP64, INT32, INT64, BOOLEAN, STRING, UNKNOWN, |
| HASH64, HASH32, // Indicate that the value is a hash. |
| CHARACTER; |
| |
| /** |
| * Get if the ValueType is a numeric value. |
| * |
| * @return If it is numeric. |
| */ |
| public boolean isNumeric() { |
| switch(this) { |
| case FP32: |
| case FP64: |
| case UINT4: |
| case UINT8: |
| case INT32: |
| case INT64: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| public boolean isFP() { |
| return this==FP64 || this==FP32; |
| } |
| |
| /** |
| * Helper method to detect Unknown ValueTypes. |
| * |
| * @return If the valuetype is Unknown |
| */ |
| public boolean isUnknown() { |
| return this == UNKNOWN; |
| } |
| |
| /** |
| * If the value is pseudoNumeric, meaning that we can translate it to a number |
| * |
| * @return If the number is indirectly numeric |
| */ |
| public boolean isPseudoNumeric() { |
| switch(this) { |
| case FP32: // Normal numeric |
| case FP64: |
| case UINT4: |
| case UINT8: |
| case INT32: |
| case INT64: |
| case BOOLEAN: // Pseudo Numeric |
| case HASH32: |
| case HASH64: |
| case CHARACTER: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| /** |
| * Convert the internal Enum to an externalizable String, the string indicate how the toString version of a value |
| * type acts. |
| * |
| * @return A capitalized string of the ValueType. |
| */ |
| public String toExternalString() { |
| switch(this) { |
| case FP32: |
| case FP64: return "DOUBLE"; |
| case UINT4: |
| case UINT8: |
| case INT32: |
| case INT64: return "INT"; |
| case BOOLEAN: return "BOOLEAN"; |
| default: return toString(); |
| } |
| } |
| |
| /** |
| * Parse an external string representation to the internal Enum ValueTypes supported. |
| * |
| * @param value The String to parse |
| * @return The internal Enum of the given string |
| * @throws DMLRuntimeException In case the given string is unsupported or invalid. |
| */ |
| public static ValueType fromExternalString(String value) { |
| //for now we support both internal and external strings |
| //until we have completely changed the external types |
| if(value == null) |
| throw new DMLRuntimeException("Unknown null value type"); |
| final String lValue = value.toUpperCase(); |
| switch(lValue) { |
| case "FLOAT": |
| case "FP32": return FP32; |
| case "FP64": |
| case "DOUBLE": return FP64; |
| case "UINT4": return UINT4; |
| case "UINT8": return UINT8; |
| case "INT32": return INT32; |
| case "INT64": |
| case "INT": return INT64; |
| case "BOOL": |
| case "BOOLEAN": return BOOLEAN; |
| case "STR": |
| case "STRING": return STRING; |
| case "CHAR": |
| case "CHARACTER": return CHARACTER; |
| case "UNKNOWN": return UNKNOWN; |
| case "HASH64": return HASH64; |
| case "HASH32": return HASH32; |
| default: |
| throw new DMLRuntimeException("Unknown value type: "+value); |
| } |
| } |
| |
| /** |
| * Given two ValueTypes, would they both print and eternalize similarly. |
| * |
| * @param vt1 The first ValueType to compare |
| * @param vt2 The second ValueType to compare |
| * @return If they behave similarly. |
| */ |
| public static boolean isSameTypeString(ValueType vt1, ValueType vt2) { |
| return vt1.toExternalString().equals(vt2.toExternalString()); |
| } |
| |
| /** |
| * Get the highest common type, where if one inout is UNKNOWN return the other. |
| * <p> |
| * |
| * For instance:<p> |
| * Character and String returns String<p> |
| * INT32 and String returns String<p> |
| * INT32 and FP32 returns FP32<p> |
| * INT32 and INT64 returns INT64<p> |
| * |
| * @param a First value type to analyze |
| * @param b Second Value type to analyze |
| * @return The highest common value |
| */ |
| public static ValueType getHighestCommonTypeSafe(ValueType a, ValueType b) { |
| if(a == b) |
| return a; |
| else |
| return getHighestCommonTypeSwitch(a, b); |
| } |
| |
| /** |
| * Get the highest common type that both ValueTypes can be contained in. |
| * <p> |
| * |
| * For instance:<p> |
| * Character and String returns String<p> |
| * INT32 and String returns String<p> |
| * INT32 and FP32 returns FP32<p> |
| * INT32 and INT64 returns INT64<p> |
| * |
| * @param a First ValueType |
| * @param b Second ValueType |
| * @return The common highest type to represent both |
| * @throws DMLRuntimeException If any input is UNKNOWN. |
| */ |
| public static ValueType getHighestCommonType(ValueType a, ValueType b) { |
| if(a == b) |
| return a; |
| else if(a == UNKNOWN || b == UNKNOWN) |
| throw new DMLRuntimeException( |
| String.format("Invalid or not implemented support for comparing valueType of: %s and %s", a, b)); |
| else |
| return getHighestCommonTypeSwitch(a, b); |
| } |
| |
| private static ValueType getHighestCommonTypeSwitch(ValueType a, ValueType b){ |
| switch(a) { |
| case CHARACTER: |
| switch(b){ |
| case UNKNOWN: |
| return a; |
| default: |
| return STRING; |
| } |
| case HASH32: |
| switch(b) { |
| case UNKNOWN: |
| return a; |
| case CHARACTER: |
| return STRING; |
| case HASH64: |
| case STRING: |
| return b; |
| default: |
| return a; |
| } |
| case HASH64: |
| switch(b) { |
| case UNKNOWN: |
| return a; |
| case CHARACTER: |
| return STRING; |
| case STRING: |
| return b; |
| default: |
| return a; |
| } |
| case STRING: |
| switch(b){ |
| case UNKNOWN: |
| return a; |
| default: |
| return STRING; |
| } |
| case FP64: |
| switch(b) { |
| case HASH64: |
| case HASH32: |
| case CHARACTER: |
| return STRING; |
| case UNKNOWN: |
| return a; |
| case STRING: |
| return b; |
| default: |
| return a; |
| } |
| case FP32: |
| switch(b) { |
| case HASH64: |
| case HASH32: |
| case CHARACTER: |
| return STRING; |
| case STRING: |
| case FP64: |
| return b; |
| case UNKNOWN: |
| default: |
| return a; |
| } |
| case INT64: |
| switch(b) { |
| case HASH64: |
| case HASH32: |
| return b; |
| case CHARACTER: |
| return STRING; |
| case STRING: |
| case FP64: |
| case FP32: |
| return b; |
| case UNKNOWN: |
| default: |
| return a; |
| } |
| case INT32: |
| switch(b) { |
| case HASH64: |
| case HASH32: |
| return b; |
| case CHARACTER: |
| return STRING; |
| case STRING: |
| case FP64: |
| case FP32: |
| case INT64: |
| return b; |
| case UNKNOWN: |
| default: |
| return a; |
| } |
| case UINT4: |
| switch(b) { |
| case HASH64: |
| case HASH32: |
| return b; |
| case CHARACTER: |
| return STRING; |
| case STRING: |
| case FP64: |
| case FP32: |
| case INT64: |
| case INT32: |
| case UINT8: |
| return b; |
| case UNKNOWN: |
| default: |
| return a; |
| } |
| case UINT8: |
| switch(b) { |
| case HASH64: |
| case HASH32: |
| return b; |
| case CHARACTER: |
| return STRING; |
| case STRING: |
| case FP64: |
| case FP32: |
| case INT64: |
| case INT32: |
| return b; |
| case UNKNOWN: |
| default: |
| return a; |
| } |
| case BOOLEAN: |
| switch(b){ |
| case UNKNOWN: |
| return a; |
| case CHARACTER: |
| return STRING; |
| default: |
| return b;// always higher type in b; |
| } |
| case UNKNOWN: |
| default: |
| return b; |
| } |
| } |
| } |
| |
| /** |
| * Serialization block types (empty, dense, sparse, ultra-sparse) |
| */ |
| public enum BlockType{ |
| EMPTY_BLOCK, |
| ULTRA_SPARSE_BLOCK, |
| SPARSE_BLOCK, |
| DENSE_BLOCK, |
| DEDUP_BLOCK, |
| } |
| |
| /** |
| * Type of builtin or user-defined function with regard to its |
| * number of return variables. |
| */ |
| public enum ReturnType { |
| NO_RETURN, |
| SINGLE_RETURN, |
| MULTI_RETURN |
| } |
| |
| |
| /** |
| * Type of aggregation direction |
| */ |
| public enum Direction { |
| RowCol, // full aggregate |
| Row, // row aggregate (e.g., rowSums) |
| Col; // column aggregate (e.g., colSums) |
| public boolean isRow() { |
| return this == Row; |
| } |
| public boolean isCol() { |
| return this == Col; |
| } |
| public boolean isRowCol() { |
| return this == RowCol; |
| } |
| @Override |
| public String toString() { |
| switch(this) { |
| case RowCol: return "RC"; |
| case Row: return "R"; |
| case Col: return "C"; |
| default: |
| throw new RuntimeException("Invalid direction type: " + this); |
| } |
| } |
| } |
| |
| /** Correction location when performing operations leveraging correcting rounding */ |
| public enum CorrectionLocationType { |
| NONE, |
| LASTROW, |
| LASTCOLUMN, |
| LASTTWOROWS, |
| LASTTWOCOLUMNS, |
| LASTFOURROWS, |
| LASTFOURCOLUMNS, |
| INVALID; |
| |
| public int getNumRemovedRowsColumns() { |
| return (this==LASTROW || this==LASTCOLUMN) ? 1 : |
| (this==LASTTWOROWS || this==LASTTWOCOLUMNS) ? 2 : |
| (this==LASTFOURROWS || this==LASTFOURCOLUMNS) ? 4 : 0; |
| } |
| |
| public boolean isRows() { |
| return this == LASTROW || this == LASTTWOROWS || this == LASTFOURROWS; |
| } |
| } |
| |
| /** Aggregation operations |
| * <p> |
| * The AggOp contain identifying integer values that need to match with their native counterparts for instance for spoof CUDA ops. |
| */ |
| public enum AggOp { |
| SUM, SUM_SQ, MIN, MAX, |
| PROD, SUM_PROD, |
| TRACE, MEAN, VAR, |
| MAXINDEX, MININDEX, |
| COUNT_DISTINCT, |
| COUNT_DISTINCT_APPROX, |
| UNIQUE; |
| |
| @Override |
| public String toString() { |
| switch(this) { |
| case SUM: return "+"; |
| case SUM_SQ: return "sq+"; |
| case PROD: return "*"; |
| default: return name().toLowerCase(); |
| } |
| } |
| |
| public static AggOp valueOfByOpcode(String opcode) { |
| switch(opcode) { |
| case "+": return SUM; |
| case "sq+": return SUM_SQ; |
| case "*": return PROD; |
| default: return valueOf(opcode.toUpperCase()); |
| } |
| } |
| } |
| |
| /** Operations that require 1 operand */ |
| public enum OpOp1 { |
| ABS, ACOS, ASIN, ASSERT, ATAN, BROADCAST, |
| CAST_AS_FRAME, CAST_AS_LIST, CAST_AS_MATRIX, CAST_AS_SCALAR, |
| CAST_AS_BOOLEAN, CAST_AS_DOUBLE, CAST_AS_INT, |
| CEIL, CHOLESKY, COS, COSH, CUMMAX, CUMMIN, CUMPROD, CUMSUM, |
| CUMSUMPROD, DET, DETECTSCHEMA, COLNAMES, EIGEN, EXISTS, EXP, FLOOR, INVERSE, |
| IQM, ISNA, ISNAN, ISINF, LENGTH, LINEAGE, LOG, NCOL, NOT, NROW, |
| MEDIAN, PREFETCH, PRINT, ROUND, ROWCUMSUM, SIN, SINH, SIGN, SOFTMAX, SQRT, STOP, _EVICT, |
| SVD, TAN, TANH, TYPEOF, TRIGREMOTE, SQRT_MATRIX_JAVA, |
| //fused ML-specific operators for performance |
| SPROP, //sample proportion: P * (1 - P) |
| SIGMOID, //sigmoid function: 1 / (1 + exp(-X)) |
| LOG_NZ, //sparse-safe log; ppred(X,0,"!=")*log(X) |
| |
| COMPRESS, DECOMPRESS, |
| LOCAL, // instruction to pull data back from spark forcefully and return a CP matrix. |
| |
| //low-level operators //TODO used? |
| MULT2, MINUS1_MULT, MINUS_RIGHT, |
| POW2, SUBTRACT_NZ; |
| |
| |
| public boolean isScalarOutput() { |
| return this == CAST_AS_SCALAR |
| || this == DET |
| || this == NROW || this == NCOL |
| || this == LENGTH || this == EXISTS |
| || this == IQM || this == LINEAGE |
| || this == MEDIAN; |
| } |
| |
| @Override |
| public String toString() { |
| switch(this) { |
| case CAST_AS_SCALAR: return "castdts"; |
| case CAST_AS_MATRIX: return "castdtm"; |
| case CAST_AS_FRAME: return "castdtf"; |
| case CAST_AS_LIST: return "castdtl"; |
| case CAST_AS_DOUBLE: return "castvtd"; |
| case CAST_AS_INT: return "castvti"; |
| case CAST_AS_BOOLEAN: return "castvtb"; |
| case CUMMAX: return Opcodes.UCUMMAX.toString(); |
| case CUMMIN: return Opcodes.UCUMMIN.toString(); |
| case CUMPROD: return Opcodes.UCUMM.toString(); |
| case CUMSUM: return Opcodes.UCUMKP.toString(); |
| case CUMSUMPROD: return Opcodes.UCUMKPM.toString(); |
| case DET: return Opcodes.DET.toString(); |
| case DETECTSCHEMA: return Opcodes.DETECTSCHEMA.toString(); |
| case MULT2: return Opcodes.MULT2.toString(); |
| case NOT: return Opcodes.NOT.toString(); |
| case POW2: return Opcodes.POW2.toString(); |
| case ROWCUMSUM: return Opcodes.UROWCUMKP.toString(); |
| case TYPEOF: return Opcodes.TYPEOF.toString(); |
| default: return name().toLowerCase(); |
| } |
| } |
| |
| //need to be kept consistent with toString |
| public static OpOp1 valueOfByOpcode(String opcode) { |
| switch(opcode) { |
| case "castdts": return CAST_AS_SCALAR; |
| case "castdtm": return CAST_AS_MATRIX; |
| case "castdtf": return CAST_AS_FRAME; |
| case "castdtl": return CAST_AS_LIST; |
| case "castvtd": return CAST_AS_DOUBLE; |
| case "castvti": return CAST_AS_INT; |
| case "castvtb": return CAST_AS_BOOLEAN; |
| case "ucummax": return CUMMAX; |
| case "ucummin": return CUMMIN; |
| case "ucum*": return CUMPROD; |
| case "ucumk+": return CUMSUM; |
| case "urowcumk+": return ROWCUMSUM; |
| case "ucumk+*": return CUMSUMPROD; |
| case "detectSchema": return DETECTSCHEMA; |
| case "*2": return MULT2; |
| case "!": return NOT; |
| case "^2": return POW2; |
| case "typeOf": return TYPEOF; |
| default: return valueOf(opcode.toUpperCase()); |
| } |
| } |
| } |
| |
| /** Operations that require 2 operands */ |
| public enum OpOp2 { |
| AND(true), APPLY_SCHEMA(false), BITWAND(true), BITWOR(true), BITWSHIFTL(true), BITWSHIFTR(true), |
| BITWXOR(true), CBIND(false), COMPRESS(true), CONCAT(false), COV(false), DIV(true), |
| DROP_INVALID_TYPE(false), DROP_INVALID_LENGTH(false), EQUAL(true), |
| FRAME_ROW_REPLICATE(true), GREATER(true), GREATEREQUAL(true), INTDIV(true), |
| INTERQUANTILE(false), IQM(false), LESS(true), |
| LESSEQUAL(true), LOG(true), MAX(true), MEDIAN(false), MIN(true), |
| MINUS(true), MODULUS(true), MOMENT(false), MULT(true), NOTEQUAL(true), OR(true), |
| PLUS(true), POW(true), PRINT(false), QUANTILE(false), SOLVE(false), |
| RBIND(false), VALUE_SWAP(false), XOR(true), |
| CAST_AS_FRAME(false), // cast as frame with column names |
| //fused ML-specific operators for performance |
| MINUS_NZ(false), //sparse-safe minus: X-(mean*ppred(X,0,!=)) |
| LOG_NZ(false), //sparse-safe log; ppred(X,0,"!=")*log(X,0.5) |
| MINUS1_MULT(false), //1-X*Y |
| QUANTIZE_COMPRESS(false), //quantization-fused compression |
| UNION_DISTINCT(false); |
| |
| private final boolean _validOuter; |
| |
| private OpOp2(boolean outer) { |
| _validOuter = outer; |
| } |
| |
| public boolean isValidOuter() { |
| return _validOuter; |
| } |
| |
| @Override |
| public String toString() { |
| switch(this) { |
| case PLUS: return Opcodes.PLUS.toString(); |
| case MINUS: return Opcodes.MINUS.toString(); |
| case MINUS_NZ: return Opcodes.MINUS_NZ.toString(); |
| case MINUS1_MULT: return Opcodes.MINUS1_MULT.toString(); |
| case MULT: return Opcodes.MULT.toString(); |
| case DIV: return Opcodes.DIV.toString(); |
| case MODULUS: return Opcodes.MODULUS.toString(); |
| case INTDIV: return Opcodes.INTDIV.toString(); |
| case LESSEQUAL: return Opcodes.LESSEQUAL.toString(); |
| case LESS: return Opcodes.LESS.toString(); |
| case GREATEREQUAL: return Opcodes.GREATEREQUAL.toString(); |
| case GREATER: return Opcodes.GREATER.toString(); |
| case EQUAL: return Opcodes.EQUAL.toString(); |
| case NOTEQUAL: return Opcodes.NOTEQUAL.toString(); |
| case OR: return Opcodes.OR.toString(); |
| case AND: return Opcodes.AND.toString(); |
| case POW: return Opcodes.POW.toString(); |
| case IQM: return "IQM"; |
| case MOMENT: return Opcodes.CM.toString(); |
| case BITWAND: return Opcodes.BITWAND.toString(); |
| case BITWOR: return Opcodes.BITWOR.toString(); |
| case BITWXOR: return Opcodes.BITWXOR.toString(); |
| case BITWSHIFTL: return Opcodes.BITWSHIFTL.toString(); |
| case BITWSHIFTR: return Opcodes.BITWSHIFTR.toString(); |
| case DROP_INVALID_TYPE: return Opcodes.DROPINVALIDTYPE.toString(); |
| case DROP_INVALID_LENGTH: return Opcodes.DROPINVALIDLENGTH.toString(); |
| case FRAME_ROW_REPLICATE: return Opcodes.FREPLICATE.toString(); |
| case VALUE_SWAP: return Opcodes.VALUESWAP.toString(); |
| case APPLY_SCHEMA: return Opcodes.APPLYSCHEMA.toString(); |
| default: return name().toLowerCase(); |
| } |
| } |
| |
| //need to be kept consistent with toString |
| public static OpOp2 valueOfByOpcode(String opcode) { |
| switch(opcode) { |
| case "+": return PLUS; |
| case "-": return MINUS; |
| case "-nz": return MINUS_NZ; |
| case "1-*": return MINUS1_MULT; |
| case "*": return MULT; |
| case "/": return DIV; |
| case "%%": return MODULUS; |
| case "%/%": return INTDIV; |
| case "<=": return LESSEQUAL; |
| case "<": return LESS; |
| case ">=": return GREATEREQUAL; |
| case ">": return GREATER; |
| case "==": return EQUAL; |
| case "!=": return NOTEQUAL; |
| case "||": return OR; |
| case "&&": return AND; |
| case "^": return POW; |
| case "IQM": return IQM; |
| case "cm": return MOMENT; |
| case "bitwAnd": return BITWAND; |
| case "bitwOr": return BITWOR; |
| case "bitwXor": return BITWXOR; |
| case "bitwShiftL": return BITWSHIFTL; |
| case "bitwShiftR": return BITWSHIFTR; |
| case "dropInvalidType": return DROP_INVALID_TYPE; |
| case "dropInvalidLength": return DROP_INVALID_LENGTH; |
| case "freplicate": return FRAME_ROW_REPLICATE; |
| case "valueSwap": return VALUE_SWAP; |
| case "applySchema": return APPLY_SCHEMA; |
| default: return valueOf(opcode.toUpperCase()); |
| } |
| } |
| } |
| |
| /** Operations that require 3 operands */ |
| public enum OpOp3 { |
| QUANTILE, INTERQUANTILE, CTABLE, MOMENT, COV, PLUS_MULT, MINUS_MULT, IFELSE, MAP; |
| |
| @Override |
| public String toString() { |
| switch(this) { |
| case MOMENT: return Opcodes.CM.toString(); |
| case PLUS_MULT: return Opcodes.PM.toString(); |
| case MINUS_MULT: return Opcodes.MINUSMULT.toString(); |
| case MAP: return Opcodes.MAP.toString(); |
| default: return name().toLowerCase(); |
| } |
| } |
| |
| public static OpOp3 valueOfByOpcode(String opcode) { |
| switch(opcode) { |
| case "cm": return MOMENT; |
| case "+*": return PLUS_MULT; |
| case "-*": return MINUS_MULT; |
| case "_map": return MAP; |
| default: return valueOf(opcode.toUpperCase()); |
| } |
| } |
| } |
| |
| /** Operations that require 4 operands */ |
| public enum OpOp4 { |
| WSLOSS, //weighted sloss mm |
| WSIGMOID, //weighted sigmoid mm |
| WDIVMM, //weighted divide mm |
| WCEMM, //weighted cross entropy mm |
| WUMM; //weighted unary mm |
| |
| @Override |
| public String toString() { |
| return name().toLowerCase(); |
| } |
| } |
| |
| /** Operations that require a variable number of operands*/ |
| public enum OpOpN { |
| PRINTF, CBIND, RBIND, MIN, MAX, PLUS, MULT, EVAL, LIST, EINSUM; |
| |
| public boolean isCellOp() { |
| return this == MIN || this == MAX || this == PLUS || this == MULT; |
| } |
| } |
| |
| /** Operations that perform internal reorganization of an allocation */ |
| public enum ReOrgOp { |
| DIAG, //DIAG_V2M and DIAG_M2V could not be distinguished if sizes unknown |
| RESHAPE, REV, ROLL, SORT, TRANS; |
| |
| public boolean preservesValues() { |
| return this != DIAG && this != SORT; |
| } |
| |
| @Override |
| public String toString() { |
| switch(this) { |
| case DIAG: return Opcodes.DIAG.toString(); |
| case TRANS: return Opcodes.TRANSPOSE.toString(); |
| case RESHAPE: return Opcodes.RESHAPE.toString(); |
| default: return name().toLowerCase(); |
| } |
| } |
| |
| public static ReOrgOp valueOfByOpcode(String opcode) { |
| switch(opcode) { |
| case "rdiag": return DIAG; |
| case "r'": return TRANS; |
| case "rshape": return RESHAPE; |
| default: return valueOf(opcode.toUpperCase()); |
| } |
| } |
| } |
| |
| /** Parameterized operations that require named variable arguments */ |
| public enum ParamBuiltinOp { |
| AUTODIFF, CDF, CONTAINS, INVALID, INVCDF, GROUPEDAGG, RMEMPTY, REPLACE, REXPAND, |
| LOWER_TRI, UPPER_TRI, |
| TRANSFORMAPPLY, TRANSFORMDECODE, TRANSFORMCOLMAP, TRANSFORMMETA, |
| TOKENIZE, TOSTRING, LIST, PARAMSERV |
| } |
| |
| /** Deep Neural Network specific operations */ |
| public enum OpOpDnn { |
| MAX_POOL, MAX_POOL_BACKWARD, AVG_POOL, AVG_POOL_BACKWARD, |
| CONV2D, CONV2D_BACKWARD_FILTER, CONV2D_BACKWARD_DATA, |
| BIASADD, BIASMULT, BATCH_NORM2D_TEST, CHANNEL_SUMS, |
| UPDATE_NESTEROV_X, |
| //fused operators |
| CONV2D_BIAS_ADD, RELU_MAX_POOL, RELU_MAX_POOL_BACKWARD, RELU_BACKWARD |
| } |
| |
| /** Data generation operations */ |
| public enum OpOpDG { |
| RAND, SEQ, FRAMEINIT, SINIT, SAMPLE, TIME |
| } |
| |
| /** Data specific operations, related to reading and writing to and from memory */ |
| public enum OpOpData { |
| PERSISTENTREAD, PERSISTENTWRITE, |
| TRANSIENTREAD, TRANSIENTWRITE, |
| FUNCTIONOUTPUT, |
| SQLREAD, FEDERATED, |
| TEE; |
| |
| public boolean isTransient() { |
| return this == TRANSIENTREAD || this == TRANSIENTWRITE; |
| } |
| public boolean isPersistent() { |
| return this == PERSISTENTREAD || this == PERSISTENTWRITE; |
| } |
| public boolean isWrite() { |
| return this == TRANSIENTWRITE || this == PERSISTENTWRITE; |
| } |
| public boolean isRead() { |
| return this == TRANSIENTREAD || this == PERSISTENTREAD; |
| } |
| |
| @Override |
| public String toString() { |
| switch(this) { |
| case PERSISTENTREAD: return "PRead"; |
| case PERSISTENTWRITE: return "PWrite"; |
| case TRANSIENTREAD: return "TRead"; |
| case TRANSIENTWRITE: return "TWrite"; |
| case FUNCTIONOUTPUT: return "FunOut"; |
| case SQLREAD: return Opcodes.SQL.toString(); |
| case FEDERATED: return "Fed"; |
| case TEE: return "Tee"; |
| default: return "Invalid"; |
| } |
| } |
| } |
| |
| /** File formats supported */ |
| public enum FileFormat { |
| TEXT, // text cell IJV representation (mm w/o header) |
| MM, // text matrix market IJV representation |
| CSV, // text dense representation |
| COMPRESSED, // Internal SYSTEMDS compressed format |
| LIBSVM, // text libsvm sparse row representation |
| JSONL, // text nested JSON (Line) representation |
| BINARY, // binary block representation (dense/sparse/ultra-sparse) |
| FEDERATED, // A federated matrix |
| PROTO, // protocol buffer representation |
| HDF5, // Hierarchical Data Format (HDF) |
| COG, // Cloud-optimized GeoTIFF |
| PARQUET, // parquet format for columnar data storage |
| UNKNOWN; |
| |
| public boolean isIJV() { |
| return this == TEXT || this == MM; |
| } |
| |
| public boolean isTextFormat() { |
| return this != BINARY && this != COMPRESSED; |
| } |
| |
| public static boolean isTextFormat(String fmt) { |
| try { |
| return valueOf(fmt.toUpperCase()).isTextFormat(); |
| } |
| catch(Exception ex) { |
| return false; |
| } |
| } |
| |
| public boolean isDelimitedFormat() { |
| return this == CSV || this == LIBSVM; |
| } |
| |
| public static boolean isDelimitedFormat(String fmt) { |
| try { |
| return valueOf(fmt.toUpperCase()).isDelimitedFormat(); |
| } |
| catch(Exception ex) { |
| return false; |
| } |
| } |
| |
| @Override |
| public String toString() { |
| return name().toLowerCase(); |
| } |
| |
| public static FileFormat defaultFormat() { |
| return TEXT; |
| } |
| |
| public static String defaultFormatString() { |
| return defaultFormat().toString(); |
| } |
| |
| public static FileFormat safeValueOf(String fmt) { |
| try { |
| return valueOf(fmt.toUpperCase()); |
| } |
| catch(Exception ex) { |
| throw new DMLRuntimeException("Unknown file format: "+fmt |
| + " (valid values: " + Arrays.toString(FileFormat.values())+")"); |
| } |
| } |
| } |
| |
| /** Common type for both function statement blocks and function program blocks **/ |
| public static interface FunctionBlock { |
| public FunctionBlock cloneFunctionBlock(); |
| } |
| } |