in src/main/java/org/apache/sysds/parser/BuiltinFunctionExpression.java [131:758]
public void validateExpression(MultiAssignmentStatement stmt, HashMap<String, DataIdentifier> ids, HashMap<String, ConstIdentifier> constVars, boolean conditional)
{
if (this.getFirstExpr() instanceof FunctionCallIdentifier){
raiseValidateError("UDF function call not supported as parameter to built-in function call", false);
}
this.getFirstExpr().validateExpression(ids, constVars, conditional);
Expression [] expr = getAllExpr();
if(expr != null && expr.length > 1) {
for(int i = 1; i < expr.length; i++) {
if (expr[i] instanceof FunctionCallIdentifier){
raiseValidateError("UDF function call not supported as parameter to built-in function call", false);
}
expr[i].validateExpression(ids, constVars, conditional);
}
}
_outputs = new Identifier[stmt.getTargetList().size()];
int count = 0;
for (DataIdentifier outParam: stmt.getTargetList()){
DataIdentifier tmp = new DataIdentifier(outParam);
tmp.setParseInfo(this);
_outputs[count++] = tmp;
}
switch (_opcode) {
case QR:
checkNumParameters(1);
checkMatrixParam(getFirstExpr());
// setup output properties
DataIdentifier qrOut1 = (DataIdentifier) getOutputs()[0];
DataIdentifier qrOut2 = (DataIdentifier) getOutputs()[1];
long rows = getFirstExpr().getOutput().getDim1();
long cols = getFirstExpr().getOutput().getDim2();
// Output1 - Q
qrOut1.setDataType(DataType.MATRIX);
qrOut1.setValueType(ValueType.FP64);
qrOut1.setDimensions(rows, cols);
qrOut1.setBlocksize(getFirstExpr().getOutput().getBlocksize());
// Output2 - R
qrOut2.setDataType(DataType.MATRIX);
qrOut2.setValueType(ValueType.FP64);
qrOut2.setDimensions(rows, cols);
qrOut2.setBlocksize(getFirstExpr().getOutput().getBlocksize());
break;
case LU:
checkNumParameters(1);
checkMatrixParam(getFirstExpr());
// setup output properties
DataIdentifier luOut1 = (DataIdentifier) getOutputs()[0];
DataIdentifier luOut2 = (DataIdentifier) getOutputs()[1];
DataIdentifier luOut3 = (DataIdentifier) getOutputs()[2];
long inrows = getFirstExpr().getOutput().getDim1();
long incols = getFirstExpr().getOutput().getDim2();
if (inrows != incols) {
raiseValidateError("LU Decomposition requires a square matrix. Matrix " + getFirstExpr() + " is "
+ inrows + "x" + incols + ".", conditional);
}
// Output1 - P
luOut1.setDataType(DataType.MATRIX);
luOut1.setValueType(ValueType.FP64);
luOut1.setDimensions(inrows, inrows);
luOut1.setBlocksize(getFirstExpr().getOutput().getBlocksize());
// Output2 - L
luOut2.setDataType(DataType.MATRIX);
luOut2.setValueType(ValueType.FP64);
luOut2.setDimensions(inrows, inrows);
luOut2.setBlocksize(getFirstExpr().getOutput().getBlocksize());
// Output3 - U
luOut3.setDataType(DataType.MATRIX);
luOut3.setValueType(ValueType.FP64);
luOut3.setDimensions(inrows, inrows);
luOut3.setBlocksize(getFirstExpr().getOutput().getBlocksize());
break;
case LSTM:
{
//TODO: LSTM on GPU has different INPUT/OUTPUT than LSTM on CPU
// X, W, bias, out0, c0, return_sequences
checkNumParameters(6);
checkMatrixParam(getFirstExpr());
checkMatrixParam(getSecondExpr());
checkMatrixParam(getThirdExpr());
checkMatrixParam(getFourthExpr());
checkMatrixParam(getFifthExpr());
// setup output properties, on CPU there are 3 more additionally outputs (cache_out, cache_c, cache_ifog)
if(getOutputs() == null || (getOutputs().length != 2 && getOutputs().length != 5)) {
int numOutputs = getOutputs() == null ? 0 : getOutputs().length;
raiseValidateError("The builtin function lstm has two outputs, but instead found: " + numOutputs, conditional);
}
DataIdentifier out = (DataIdentifier) getOutputs()[0];
DataIdentifier cy = (DataIdentifier) getOutputs()[1];
// Output1 - out: If `return_sequences` is True, outputs for all timesteps, else outputs for the final timestep.
out.setDataType(DataType.MATRIX);
out.setValueType(ValueType.FP64);
out.setDimensions(-1, -1);
out.setBlocksize(getFirstExpr().getOutput().getBlocksize());
// Output2 - Cell state for final timestep.
cy.setDataType(DataType.MATRIX);
cy.setValueType(ValueType.FP64);
cy.setDimensions(getExpr(4).getOutput().getDim1(), getExpr(4).getOutput().getDim2());
cy.setBlocksize(getExpr(4).getOutput().getBlocksize());
if(getOutputs().length == 5){
DataIdentifier cache_out = (DataIdentifier) getOutputs()[2];
DataIdentifier cache_c = (DataIdentifier) getOutputs()[3];
DataIdentifier cache_ifog = (DataIdentifier) getOutputs()[4];
// Output3 - cache_out: (T,N*M) T is unknown upfront
cache_out.setDataType(DataType.MATRIX);
cache_out.setValueType(ValueType.FP64);
cache_out.setDimensions(-1, -1);
cache_out.setBlocksize(getFirstExpr().getOutput().getBlocksize());
// Output4 - cache_c: (T,N*M)
cache_c.setDataType(DataType.MATRIX);
cache_c.setValueType(ValueType.FP64);
cache_out.setDimensions(-1, -1);
cache_out.setBlocksize(getFirstExpr().getOutput().getBlocksize());
// Output5 - cache_ifog: (T,N*M)
cache_ifog.setDataType(DataType.MATRIX);
cache_ifog.setValueType(ValueType.FP64);
cache_ifog.setDimensions(-1, -1);
cache_ifog.setBlocksize(getFirstExpr().getOutput().getBlocksize());
}
break;
}
case LSTM_BACKWARD:
{
// Input: X, W, b, out0, c0, return_sequences, dout, cy
checkNumParameters(8);
checkMatrixParam(getFirstExpr());
checkMatrixParam(getSecondExpr());
checkMatrixParam(getThirdExpr());
checkMatrixParam(getFourthExpr());
checkMatrixParam(getFifthExpr());
checkMatrixParam(getSeventhExpr());
checkMatrixParam(getEighthExpr());
// Output: dx, dw, db, dout0, dc0
// setup output properties
if(getOutputs().length != 5)
raiseValidateError("lstm_backward has 5 outputs", false);
DataIdentifier dx = (DataIdentifier) getOutputs()[0];
DataIdentifier dw = (DataIdentifier) getOutputs()[1];
DataIdentifier db = (DataIdentifier) getOutputs()[2];
DataIdentifier dout0 = (DataIdentifier) getOutputs()[3];
DataIdentifier dc0 = (DataIdentifier) getOutputs()[4];
setDimensions(dx, getFirstExpr());
setDimensions(dw, getSecondExpr());
setDimensions(db, getThirdExpr());
setDimensions(dout0, getFourthExpr());
setDimensions(dc0, getFifthExpr());
break;
}
case BATCH_NORM2D:
{
// Input: image, scale, bias, runningMean, runningVar, mode, epsilon, exponentialAverageFactor
checkNumParameters(8);
checkMatrixParam(getFirstExpr());
checkMatrixParam(getSecondExpr());
checkMatrixParam(getThirdExpr());
checkMatrixParam(getFourthExpr());
checkMatrixParam(getFifthExpr());
// Output: ret, retRunningMean, retRunningVar, resultSaveMean, resultSaveInvVariance
// setup output properties
if(getOutputs().length != 5)
raiseValidateError("batch_norm2d has 5 outputs", false);
DataIdentifier ret = (DataIdentifier) getOutputs()[0];
DataIdentifier retRunningMean = (DataIdentifier) getOutputs()[1];
DataIdentifier retRunningVar = (DataIdentifier) getOutputs()[2];
DataIdentifier resultSaveMean = (DataIdentifier) getOutputs()[3];
DataIdentifier resultSaveInvVariance = (DataIdentifier) getOutputs()[4];
setDimensions(ret, getFirstExpr());
setDimensions(retRunningMean, getFourthExpr());
setDimensions(retRunningVar, getFourthExpr());
setDimensions(resultSaveMean, getFourthExpr());
setDimensions(resultSaveInvVariance, getFourthExpr());
break;
}
case BATCH_NORM2D_BACKWARD:
{
// Input: image, dout, scale, epsilon, savedMean, savedInvVariance
checkNumParameters(6);
checkMatrixParam(getFirstExpr());
checkMatrixParam(getSecondExpr());
checkMatrixParam(getThirdExpr());
checkMatrixParam(getFifthExpr());
checkMatrixParam(getSixthExpr());
// Output: dX, dScale, dBias
// setup output properties
if(getOutputs().length != 3)
raiseValidateError("batch_norm2d_backward has 3 outputs", false);
DataIdentifier dX = (DataIdentifier) getOutputs()[0];
DataIdentifier dScale = (DataIdentifier) getOutputs()[1];
DataIdentifier dBias = (DataIdentifier) getOutputs()[2];
setDimensions(dX, getFirstExpr());
setDimensions(dScale, getThirdExpr());
setDimensions(dBias, getThirdExpr());
break;
}
case EIGEN: {
checkNumParameters(1);
checkMatrixParam(getFirstExpr());
// setup output properties
DataIdentifier eigenOut1 = (DataIdentifier) getOutputs()[0];
DataIdentifier eigenOut2 = (DataIdentifier) getOutputs()[1];
if ( getFirstExpr().getOutput().getDim1() != getFirstExpr().getOutput().getDim2() ) {
raiseValidateError("Eigen Decomposition can only be done on a square matrix. Input matrix is rectangular (rows=" + getFirstExpr().getOutput().getDim1() + ", cols="+ getFirstExpr().getOutput().getDim2() +")", conditional);
}
// Output1 - Eigen Values
eigenOut1.setDataType(DataType.MATRIX);
eigenOut1.setValueType(ValueType.FP64);
eigenOut1.setDimensions(getFirstExpr().getOutput().getDim1(), 1);
eigenOut1.setBlocksize(getFirstExpr().getOutput().getBlocksize());
// Output2 - Eigen Vectors
eigenOut2.setDataType(DataType.MATRIX);
eigenOut2.setValueType(ValueType.FP64);
eigenOut2.setDimensions(getFirstExpr().getOutput().getDim1(), getFirstExpr().getOutput().getDim2());
eigenOut2.setBlocksize(getFirstExpr().getOutput().getBlocksize());
break;
}
case RCM: {
checkNumParameters(2);
checkMatrixParam(getFirstExpr());
checkMatrixParam(getSecondExpr());
long nr = Math.max(getFirstExpr().getOutput().getDim1(),
getSecondExpr().getOutput().getDim1());
long nc = Math.max(getFirstExpr().getOutput().getDim2(),
getSecondExpr().getOutput().getDim2());
for(int i=0; i<2; i++) {
DataIdentifier out = (DataIdentifier) getOutputs()[i];
out.setDataType(DataType.MATRIX);
out.setValueType(ValueType.FP64);
out.setDimensions(nr, nc);
out.setBlocksize(getFirstExpr().getOutput().getBlocksize());
}
break;
}
case FFT: {
Expression expressionOne = getFirstExpr();
Expression expressionTwo = getSecondExpr();
if(expressionOne == null) {
raiseValidateError("The first argument to " + _opcode + " cannot be null.", false,
LanguageErrorCodes.INVALID_PARAMETERS);
}
else if(expressionOne.getOutput() == null || expressionOne.getOutput().getDim1() == 0 ||
expressionOne.getOutput().getDim2() == 0) {
raiseValidateError("The first argument to " + _opcode + " cannot be an empty matrix.", false,
LanguageErrorCodes.INVALID_PARAMETERS);
}
else if(expressionTwo != null) {
raiseValidateError("Too many arguments. This FFT implementation is only defined for real inputs.", false,
LanguageErrorCodes.INVALID_PARAMETERS);
}
else if(!isPowerOfTwo(expressionOne.getOutput().getDim1()) ||
!isPowerOfTwo(expressionOne.getOutput().getDim2())) {
raiseValidateError(
"This FFT implementation is only defined for matrices with dimensions that are powers of 2.", false,
LanguageErrorCodes.INVALID_PARAMETERS);
}
checkNumParameters(1);
checkMatrixParam(expressionOne);
DataIdentifier fftOut1 = (DataIdentifier) getOutputs()[0];
DataIdentifier fftOut2 = (DataIdentifier) getOutputs()[1];
fftOut1.setDataType(DataType.MATRIX);
fftOut1.setValueType(ValueType.FP64);
fftOut1.setDimensions(getFirstExpr().getOutput().getDim1(), getFirstExpr().getOutput().getDim2());
fftOut1.setBlocksize(getFirstExpr().getOutput().getBlocksize());
fftOut2.setDataType(DataType.MATRIX);
fftOut2.setValueType(ValueType.FP64);
fftOut2.setDimensions(getFirstExpr().getOutput().getDim1(), getFirstExpr().getOutput().getDim2());
fftOut2.setBlocksize(getFirstExpr().getOutput().getBlocksize());
break;
}
case IFFT: {
Expression expressionTwo = getSecondExpr();
Expression expressionOne = getFirstExpr();
if(expressionOne == null) {
raiseValidateError("The first argument to " + _opcode + " cannot be null.", false,
LanguageErrorCodes.INVALID_PARAMETERS);
}
else if(expressionOne.getOutput() == null || expressionOne.getOutput().getDim1() == 0 ||
expressionOne.getOutput().getDim2() == 0) {
raiseValidateError("The first argument to " + _opcode + " cannot be an empty matrix.", false,
LanguageErrorCodes.INVALID_PARAMETERS);
}
else if(expressionTwo != null) {
if(expressionTwo.getOutput() == null || expressionTwo.getOutput().getDim1() == 0 ||
expressionTwo.getOutput().getDim2() == 0) {
raiseValidateError("The second argument to " + _opcode
+ " cannot be an empty matrix. Provide either only a real matrix or a filled real and imaginary one.",
false, LanguageErrorCodes.INVALID_PARAMETERS);
}
}
checkNumParameters(expressionTwo != null ? 2 : 1);
checkMatrixParam(expressionOne);
if(expressionTwo != null && expressionOne != null) {
checkMatrixParam(expressionTwo);
if(expressionOne.getOutput().getDim1() != expressionTwo.getOutput().getDim1() ||
expressionOne.getOutput().getDim2() != expressionTwo.getOutput().getDim2())
raiseValidateError("The real and imaginary part of the provided matrix are of different dimensions.",
false);
else if(!isPowerOfTwo(expressionTwo.getOutput().getDim1()) ||
!isPowerOfTwo(expressionTwo.getOutput().getDim2())) {
raiseValidateError(
"This IFFT implementation is only defined for matrices with dimensions that are powers of 2.", false,
LanguageErrorCodes.INVALID_PARAMETERS);
}
}
else if(expressionOne != null) {
if(!isPowerOfTwo(expressionOne.getOutput().getDim1()) ||
!isPowerOfTwo(expressionOne.getOutput().getDim2())) {
raiseValidateError(
"This IFFT implementation is only defined for matrices with dimensions that are powers of 2.", false,
LanguageErrorCodes.INVALID_PARAMETERS);
}
}
DataIdentifier ifftOut1 = (DataIdentifier) getOutputs()[0];
DataIdentifier ifftOut2 = (DataIdentifier) getOutputs()[1];
ifftOut1.setDataType(DataType.MATRIX);
ifftOut1.setValueType(ValueType.FP64);
ifftOut1.setDimensions(getFirstExpr().getOutput().getDim1(), getFirstExpr().getOutput().getDim2());
ifftOut1.setBlocksize(getFirstExpr().getOutput().getBlocksize());
// Output2 - ifft Vectors
ifftOut2.setDataType(DataType.MATRIX);
ifftOut2.setValueType(ValueType.FP64);
ifftOut2.setDimensions(getFirstExpr().getOutput().getDim1(), getFirstExpr().getOutput().getDim2());
ifftOut2.setBlocksize(getFirstExpr().getOutput().getBlocksize());
break;
}
case FFT_LINEARIZED: {
Expression expressionOne = getFirstExpr();
Expression expressionTwo = getSecondExpr();
if(expressionOne == null) {
raiseValidateError("The first argument to " + _opcode + " cannot be null.", false,
LanguageErrorCodes.INVALID_PARAMETERS);
}
else if(expressionOne.getOutput() == null || expressionOne.getOutput().getDim1() == 0 ||
expressionOne.getOutput().getDim2() == 0) {
raiseValidateError("The first argument to " + _opcode + " cannot be an empty matrix.", false,
LanguageErrorCodes.INVALID_PARAMETERS);
}
else if(expressionTwo != null) {
raiseValidateError(
"Too many arguments. This FFT_LINEARIZED implementation is only defined for real inputs.", false,
LanguageErrorCodes.INVALID_PARAMETERS);
}
else if(!isPowerOfTwo(expressionOne.getOutput().getDim2())) {
raiseValidateError(
"This FFT_LINEARIZED implementation is only defined for matrices with columns that are powers of 2.",
false, LanguageErrorCodes.INVALID_PARAMETERS);
}
checkNumParameters(1);
checkMatrixParam(expressionOne);
DataIdentifier fftOut1 = (DataIdentifier) getOutputs()[0];
DataIdentifier fftOut2 = (DataIdentifier) getOutputs()[1];
fftOut1.setDataType(DataType.MATRIX);
fftOut1.setValueType(ValueType.FP64);
fftOut1.setDimensions(getFirstExpr().getOutput().getDim1(), getFirstExpr().getOutput().getDim2());
fftOut1.setBlocksize(getFirstExpr().getOutput().getBlocksize());
fftOut2.setDataType(DataType.MATRIX);
fftOut2.setValueType(ValueType.FP64);
fftOut2.setDimensions(getFirstExpr().getOutput().getDim1(), getFirstExpr().getOutput().getDim2());
fftOut2.setBlocksize(getFirstExpr().getOutput().getBlocksize());
break;
}
case IFFT_LINEARIZED: {
Expression expressionTwo = getSecondExpr();
Expression expressionOne = getFirstExpr();
if(expressionOne == null) {
raiseValidateError("The first argument to " + _opcode + " cannot be null.", false,
LanguageErrorCodes.INVALID_PARAMETERS);
}
else if(expressionOne.getOutput() == null || expressionOne.getOutput().getDim1() == 0 ||
expressionOne.getOutput().getDim2() == 0) {
raiseValidateError("The first argument to " + _opcode + " cannot be an empty matrix.", false,
LanguageErrorCodes.INVALID_PARAMETERS);
}
else if(expressionTwo != null) {
if(expressionTwo.getOutput() == null || expressionTwo.getOutput().getDim1() == 0 ||
expressionTwo.getOutput().getDim2() == 0) {
raiseValidateError("The second argument to " + _opcode
+ " cannot be an empty matrix. Provide either only a real matrix or a filled real and imaginary one.",
false, LanguageErrorCodes.INVALID_PARAMETERS);
}
}
checkNumParameters(expressionTwo != null ? 2 : 1);
checkMatrixParam(expressionOne);
if(expressionTwo != null && expressionOne != null) {
checkMatrixParam(expressionTwo);
if(expressionOne.getOutput().getDim1() != expressionTwo.getOutput().getDim1() ||
expressionOne.getOutput().getDim2() != expressionTwo.getOutput().getDim2())
raiseValidateError("The real and imaginary part of the provided matrix are of different dimensions.",
false);
else if(!isPowerOfTwo(expressionTwo.getOutput().getDim2())) {
raiseValidateError(
"This IFFT_LINEARIZED implementation is only defined for matrices with columns that are powers of 2.",
false, LanguageErrorCodes.INVALID_PARAMETERS);
}
}
else if(expressionOne != null) {
if(!isPowerOfTwo(expressionOne.getOutput().getDim2())) {
raiseValidateError(
"This IFFT_LINEARIZED implementation is only defined for matrices with columns that are powers of 2.",
false, LanguageErrorCodes.INVALID_PARAMETERS);
}
}
DataIdentifier ifftOut1 = (DataIdentifier) getOutputs()[0];
DataIdentifier ifftOut2 = (DataIdentifier) getOutputs()[1];
ifftOut1.setDataType(DataType.MATRIX);
ifftOut1.setValueType(ValueType.FP64);
ifftOut1.setDimensions(getFirstExpr().getOutput().getDim1(), getFirstExpr().getOutput().getDim2());
ifftOut1.setBlocksize(getFirstExpr().getOutput().getBlocksize());
ifftOut2.setDataType(DataType.MATRIX);
ifftOut2.setValueType(ValueType.FP64);
ifftOut2.setDimensions(getFirstExpr().getOutput().getDim1(), getFirstExpr().getOutput().getDim2());
ifftOut2.setBlocksize(getFirstExpr().getOutput().getBlocksize());
break;
}
case STFT: {
checkMatrixParam(getFirstExpr());
if((getFirstExpr() == null || getSecondExpr() == null || getThirdExpr() == null) && _args.length > 0) {
raiseValidateError("Missing argument for function " + this.getOpCode(), false,
LanguageErrorCodes.INVALID_PARAMETERS);
}
else if(getFifthExpr() != null) {
raiseValidateError("Invalid number of arguments for function " + this.getOpCode().toString().toLowerCase()
+ "(). This function only takes 3 or 4 arguments.", false);
}
else if(_args.length == 3) {
checkScalarParam(getSecondExpr());
checkScalarParam(getThirdExpr());
if(!isPowerOfTwo(((ConstIdentifier) getSecondExpr().getOutput()).getLongValue())) {
raiseValidateError(
"This FFT implementation is only defined for matrices with dimensions that are powers of 2."
+ "The window size (2nd argument) is not a power of two",
false, LanguageErrorCodes.INVALID_PARAMETERS);
}
else if(((ConstIdentifier) getSecondExpr().getOutput())
.getLongValue() <= ((ConstIdentifier) getThirdExpr().getOutput()).getLongValue()) {
raiseValidateError("Overlap can't be larger than or equal to the window size.", false,
LanguageErrorCodes.INVALID_PARAMETERS);
}
}
else if(_args.length == 4) {
checkMatrixParam(getSecondExpr());
checkScalarParam(getThirdExpr());
checkScalarParam(getFourthExpr());
if(!isPowerOfTwo(((ConstIdentifier) getThirdExpr().getOutput()).getLongValue())) {
raiseValidateError(
"This FFT implementation is only defined for matrices with dimensions that are powers of 2."
+ "The window size (3rd argument) is not a power of two",
false, LanguageErrorCodes.INVALID_PARAMETERS);
}
else if(getFirstExpr().getOutput().getDim1() != getSecondExpr().getOutput().getDim1() ||
getFirstExpr().getOutput().getDim2() != getSecondExpr().getOutput().getDim2()) {
raiseValidateError("The real and imaginary part of the provided matrix are of different dimensions.",
false);
}
else if(((ConstIdentifier) getThirdExpr().getOutput())
.getLongValue() <= ((ConstIdentifier) getFourthExpr().getOutput()).getLongValue()) {
raiseValidateError("Overlap can't be larger than or equal to the window size.", false,
LanguageErrorCodes.INVALID_PARAMETERS);
}
}
// setup output properties
DataIdentifier stftOut1 = (DataIdentifier) getOutputs()[0];
DataIdentifier stftOut2 = (DataIdentifier) getOutputs()[1];
// Output1 - stft Values
stftOut1.setDataType(DataType.MATRIX);
stftOut1.setValueType(ValueType.FP64);
stftOut1.setDimensions(getFirstExpr().getOutput().getDim1(), getFirstExpr().getOutput().getDim2());
stftOut1.setBlocksize(getFirstExpr().getOutput().getBlocksize());
// Output2 - stft Vectors
stftOut2.setDataType(DataType.MATRIX);
stftOut2.setValueType(ValueType.FP64);
stftOut2.setDimensions(getFirstExpr().getOutput().getDim1(), getFirstExpr().getOutput().getDim2());
stftOut2.setBlocksize(getFirstExpr().getOutput().getBlocksize());
break;
}
case REMOVE: {
checkNumParameters(2);
checkListParam(getFirstExpr());
// setup output properties
DataIdentifier out1 = (DataIdentifier) getOutputs()[0];
DataIdentifier out2 = (DataIdentifier) getOutputs()[1];
// Output1 - list after removal
long nrow = getFirstExpr().getOutput().getDim1() > 0 ?
getFirstExpr().getOutput().getDim1() + 1 : -1;
out1.setDataType(DataType.LIST);
out1.setValueType(getFirstExpr().getOutput().getValueType());
out1.setDimensions(nrow, 1);
out1.setBlocksize(getFirstExpr().getOutput().getBlocksize());
// Output2 - list of removed element
out2.setDataType(DataType.LIST);
out2.setValueType(getFirstExpr().getOutput().getValueType());
out2.setDimensions(1, 1);
out2.setBlocksize(getFirstExpr().getOutput().getBlocksize());
break;
}
case SVD:
checkNumParameters(1);
checkMatrixParam(getFirstExpr());
long minMN = Math.min(getFirstExpr().getOutput().getDim1(), getFirstExpr().getOutput().getDim2());
// setup output properties
DataIdentifier svdOut1 = (DataIdentifier) getOutputs()[0];
DataIdentifier svdOut2 = (DataIdentifier) getOutputs()[1];
DataIdentifier svdOut3 = (DataIdentifier) getOutputs()[2];
// Output 1
svdOut1.setDataType(DataType.MATRIX);
svdOut1.setValueType(ValueType.FP64);
svdOut1.setDimensions(getFirstExpr().getOutput().getDim1(), minMN);
svdOut1.setBlocksize(getFirstExpr().getOutput().getBlocksize());
// Output 2
svdOut2.setDataType(DataType.MATRIX);
svdOut2.setValueType(ValueType.FP64);
svdOut2.setDimensions(minMN, minMN);
svdOut2.setBlocksize(getFirstExpr().getOutput().getBlocksize());
// Output 3
svdOut3.setDataType(DataType.MATRIX);
svdOut3.setValueType(ValueType.FP64);
svdOut3.setDimensions(getFirstExpr().getOutput().getDim2(), minMN);
svdOut3.setBlocksize(getFirstExpr().getOutput().getBlocksize());
break;
case COMPRESS:
if(OptimizerUtils.ALLOW_SCRIPT_LEVEL_COMPRESS_COMMAND) {
Expression expressionTwo = getSecondExpr();
checkNumParameters(getSecondExpr() != null ? 2 : 1);
checkMatrixFrameParam(getFirstExpr());
if(expressionTwo != null)
checkMatrixParam(getSecondExpr());
Identifier compressInput1 = getFirstExpr().getOutput();
// Identifier compressInput2 = getSecondExpr().getOutput();
DataIdentifier compressOutput = (DataIdentifier) getOutputs()[0];
compressOutput.setDataType(DataType.MATRIX);
compressOutput.setDimensions(compressInput1.getDim1(), compressInput1.getDim2());
compressOutput.setBlocksize(compressInput1.getBlocksize());
compressOutput.setValueType(compressInput1.getValueType());
DataIdentifier metaOutput = (DataIdentifier) getOutputs()[1];
metaOutput.setDataType(DataType.FRAME);
metaOutput.setDimensions(compressInput1.getDim1(), -1);
}
else
raiseValidateError("Compress/DeCompress instruction not allowed in dml script");
break;
default: //always unconditional
raiseValidateError("Unknown Builtin Function opcode: " + _opcode, false);
}
}