/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.sysml.lops;
import org.apache.sysml.lops.LopProperties.ExecLocation;
import org.apache.sysml.lops.LopProperties.ExecType;
import org.apache.sysml.lops.compile.JobType;
import org.apache.sysml.parser.Expression.DataType;
import org.apache.sysml.parser.Expression.ValueType;
/**
* Lop to perform an operation on a variable number of operands.
*
*/
public class MultipleCP extends Lop {
public enum OperationType {
PRINTF
};
OperationType operationType;
public MultipleCP(OperationType operationType, DataType dt, ValueType vt, Lop... inputLops) {
super(Lop.Type.MULTIPLE_CP, dt, vt);
this.operationType = operationType;
for (Lop inputLop : inputLops) {
addInput(inputLop);
inputLop.addOutput(this);
}
boolean breaksAlignment = false; // ?
boolean aligner = false; // ?
boolean definesMRJob = false; // ?
lps.addCompatibility(JobType.INVALID); // ?
this.lps.setProperties(inputs, ExecType.CP, ExecLocation.ControlProgram, breaksAlignment, aligner,
definesMRJob); // ?
}
@Override
public String toString() {
return "Operation Type: " + operationType;
}
public OperationType getOperationType() {
return operationType;
}
/**
* Generate the complete instruction string for this Lop. This instruction
* string can have a variable number of input operands. It displays the
* following:
*
* <ul>
* <li>Execution type (CP, SPARK, etc.)
* <li>Operand delimiter (°)
* <li>Opcode (printf, etc.)
* <li>Operand delimiter (°)
* <li>Variable number of inputs, each followed by an operand delimiter
* (°)
* <ul>
* <li>Input consists of (label · data type · value type
* · is literal)
* </ul>
* <li>Output consisting of (label · data type · value
* type)
* </ul>
*
* Example: <br>
* The following DML<br>
* <code>print('hello %s', 'world')</code><br>
* generates the instruction string:<br>
* <code>CP°printf°hello %s·SCALAR·STRING·true°world·SCALAR·STRING·true°_Var1·SCALAR·STRING</code><br>
*
* Note: This generated instruction string is parsed in the
* parseInstruction() method of BuiltinMultipleCPInstruction, which parses
* the instruction string to generate an instruction object that is a
* subclass of BuiltinMultipleCPInstruction.
*/
@Override
public String getInstructions(String output) throws LopsException {
String opString = getOpcode();
StringBuilder sb = new StringBuilder();
sb.append(getExecType());
sb.append(Lop.OPERAND_DELIMITOR);
sb.append(opString);
sb.append(OPERAND_DELIMITOR);
for (Lop input : inputs) {
sb.append(input.prepScalarInputOperand(getExecType()));
sb.append(OPERAND_DELIMITOR);
}
sb.append(prepOutputOperand(output));
return sb.toString();
}
private String getOpcode() throws LopsException {
switch (operationType) {
case PRINTF:
return OperationType.PRINTF.toString().toLowerCase();
default:
throw new UnsupportedOperationException(
"MultipleCP operation type (" + operationType + ") is not defined.");
}
}
}