This is an automated email from the ASF dual-hosted git repository.
mboehm7 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/systemds.git
The following commit(s) were added to refs/heads/master by this push:
new 8fc1995 [SYSTEMDS-2747] Federated quaternary operations wdivmm and
wumm
8fc1995 is described below
commit 8fc199532146b50643d30609435102c8dc6d819f
Author: ywcb00 <[email protected]>
AuthorDate: Sat Jan 23 22:45:50 2021 +0100
[SYSTEMDS-2747] Federated quaternary operations wdivmm and wumm
Closes #1161.
---
.../instructions/fed/QuaternaryFEDInstruction.java | 82 ++++--
.../fed/QuaternaryWDivMMFEDInstruction.java | 164 +++++++++++
.../fed/QuaternaryWSLossFEDInstruction.java | 8 +-
.../fed/QuaternaryWSigmoidFEDInstruction.java | 4 +-
...tion.java => QuaternaryWUMMFEDInstruction.java} | 20 +-
.../FederatedWeightedDivMatrixMultTest.java | 311 +++++++++++++++++++++
.../FederatedWeightedUnaryMatrixMultTest.java | 202 +++++++++++++
.../quaternary/FederatedWDivMMBasicMultTest.dml | 30 ++
.../FederatedWDivMMBasicMultTestReference.dml | 28 ++
.../quaternary/FederatedWDivMMLeftEps2Test.dml | 31 ++
.../FederatedWDivMMLeftEps2TestReference.dml | 29 ++
.../quaternary/FederatedWDivMMLeftEps3Test.dml | 31 ++
.../FederatedWDivMMLeftEps3TestReference.dml | 29 ++
.../quaternary/FederatedWDivMMLeftEpsTest.dml | 31 ++
.../FederatedWDivMMLeftEpsTestReference.dml | 29 ++
.../FederatedWDivMMLeftMultMinus4Test.dml | 32 +++
.../FederatedWDivMMLeftMultMinus4TestReference.dml | 30 ++
.../FederatedWDivMMLeftMultMinusTest.dml | 30 ++
.../FederatedWDivMMLeftMultMinusTestReference.dml | 28 ++
.../quaternary/FederatedWDivMMLeftMultTest.dml | 30 ++
.../FederatedWDivMMLeftMultTestReference.dml | 28 ++
.../quaternary/FederatedWDivMMLeftTest.dml | 30 ++
.../FederatedWDivMMLeftTestReference.dml | 28 ++
.../quaternary/FederatedWDivMMRightEpsTest.dml | 31 ++
.../FederatedWDivMMRightEpsTestReference.dml | 29 ++
.../FederatedWDivMMRightMultMinus4Test.dml | 32 +++
...FederatedWDivMMRightMultMinus4TestReference.dml | 30 ++
.../FederatedWDivMMRightMultMinusTest.dml | 30 ++
.../FederatedWDivMMRightMultMinusTestReference.dml | 28 ++
.../quaternary/FederatedWDivMMRightMultTest.dml | 30 ++
.../FederatedWDivMMRightMultTestReference.dml | 28 ++
.../quaternary/FederatedWDivMMRightTest.dml | 30 ++
.../FederatedWDivMMRightTestReference.dml | 28 ++
.../quaternary/FederatedWUMMExpDivTest.dml | 30 ++
.../FederatedWUMMExpDivTestReference.dml | 28 ++
.../quaternary/FederatedWUMMExpMultTest.dml | 30 ++
.../FederatedWUMMExpMultTestReference.dml | 28 ++
.../quaternary/FederatedWUMMMult2Test.dml | 30 ++
.../quaternary/FederatedWUMMMult2TestReference.dml | 28 ++
.../federated/quaternary/FederatedWUMMPow2Test.dml | 30 ++
.../quaternary/FederatedWUMMPow2TestReference.dml | 28 ++
41 files changed, 1756 insertions(+), 37 deletions(-)
diff --git
a/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryFEDInstruction.java
b/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryFEDInstruction.java
index ffb385d..b931dcd 100644
---
a/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryFEDInstruction.java
+++
b/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryFEDInstruction.java
@@ -22,9 +22,18 @@ package org.apache.sysds.runtime.instructions.fed;
import org.apache.sysds.common.Types.DataType;
import org.apache.sysds.common.Types.ExecType;
import org.apache.sysds.lops.Lop;
+import org.apache.sysds.lops.WeightedCrossEntropy;
import org.apache.sysds.lops.WeightedCrossEntropy.WCeMMType;
+import org.apache.sysds.lops.WeightedDivMM;
+import org.apache.sysds.lops.WeightedDivMMR;
+import org.apache.sysds.lops.WeightedDivMM.WDivMMType;
+import org.apache.sysds.lops.WeightedSigmoid;
import org.apache.sysds.lops.WeightedSigmoid.WSigmoidType;
+import org.apache.sysds.lops.WeightedSquaredLoss;
+import org.apache.sysds.lops.WeightedSquaredLossR;
import org.apache.sysds.lops.WeightedSquaredLoss.WeightsType;
+import org.apache.sysds.lops.WeightedUnaryMM;
+import org.apache.sysds.lops.WeightedUnaryMM.WUMMType;
import org.apache.sysds.runtime.DMLRuntimeException;
import org.apache.sysds.runtime.instructions.InstructionUtils;
import org.apache.sysds.runtime.instructions.cp.CPOperand;
@@ -48,39 +57,30 @@ public abstract class QuaternaryFEDInstruction extends
ComputationFEDInstruction
public static QuaternaryFEDInstruction parseInstruction(String str) {
if(str.startsWith(ExecType.SPARK.name())) {
// rewrite the spark instruction to a cp instruction
- str = str.replace(ExecType.SPARK.name(),
ExecType.CP.name());
- str = str.replace("mapwcemm", "wcemm");
- str = str.replace("mapwsloss", "wsloss");
- if(str.contains("redwsloss")) {
- str = str.replace("redwsloss", "wsloss");
- // remove booleans which indicate cacheU and
cacheV for redwsloss
- str = str.replace(Lop.OPERAND_DELIMITOR +
"true", "");
- str = str.replace(Lop.OPERAND_DELIMITOR +
"false", "");
- }
- str = str.replace("mapwsigmoid", "wsigmoid");
- str += Lop.OPERAND_DELIMITOR + "1"; // num threads
+ str = rewriteSparkInstructionToCP(str);
}
String[] parts =
InstructionUtils.getInstructionPartsWithValueType(str);
String opcode = parts[0];
- int addInput4 = (opcode.equals("wcemm") ||
opcode.equals("wsloss")) ? 1 : 0;
+ int addInput4 = (opcode.equals(WeightedCrossEntropy.OPCODE_CP)
|| opcode.equals(WeightedSquaredLoss.OPCODE_CP) ||
opcode.equals(WeightedDivMM.OPCODE_CP)) ? 1 : 0;
+ int addUOpcode = (opcode.equals(WeightedUnaryMM.OPCODE_CP) ? 1
: 0);
- InstructionUtils.checkNumFields(parts, 6 + addInput4);
+ InstructionUtils.checkNumFields(parts, 6 + addInput4 +
addUOpcode);
- CPOperand in1 = new CPOperand(parts[1]);
- CPOperand in2 = new CPOperand(parts[2]);
- CPOperand in3 = new CPOperand(parts[3]);
- CPOperand out = new CPOperand(parts[4 + addInput4]);
+ CPOperand in1 = new CPOperand(parts[1 + addUOpcode]);
+ CPOperand in2 = new CPOperand(parts[2 + addUOpcode]);
+ CPOperand in3 = new CPOperand(parts[3 + addUOpcode]);
+ CPOperand out = new CPOperand(parts[4 + addInput4 +
addUOpcode]);
checkDataTypes(DataType.MATRIX, in1, in2, in3);
QuaternaryOperator qop = null;
- if(addInput4 == 1) // wcemm, wsloss
+ if(addInput4 == 1) // wcemm, wsloss, wdivmm
{
CPOperand in4 = new CPOperand(parts[4]);
- if(opcode.equals("wcemm")) {
+ if(opcode.equals(WeightedCrossEntropy.OPCODE_CP)) {
final WCeMMType wcemm_type =
WCeMMType.valueOf(parts[6]);
if(wcemm_type.hasFourInputs())
checkDataTypes(new DataType[]
{DataType.SCALAR, DataType.MATRIX}, in4);
@@ -88,7 +88,15 @@ public abstract class QuaternaryFEDInstruction extends
ComputationFEDInstruction
Double.parseDouble(in4.getName())) :
new QuaternaryOperator(wcemm_type));
return new QuaternaryWCeMMFEDInstruction(qop,
in1, in2, in3, in4, out, opcode, str);
}
- else if(opcode.equals("wsloss")) {
+ else if(opcode.equals(WeightedDivMM.OPCODE_CP))
+ {
+ final WDivMMType wdivmm_type =
WDivMMType.valueOf(parts[6]);
+ if(wdivmm_type.hasFourInputs())
+ checkDataTypes(new
DataType[]{DataType.SCALAR, DataType.MATRIX}, in4);
+ qop = new QuaternaryOperator(wdivmm_type);
+ return new QuaternaryWDivMMFEDInstruction(qop,
in1, in2, in3, in4, out, opcode, str);
+ }
+ else if(opcode.equals(WeightedSquaredLoss.OPCODE_CP)) {
final WeightsType weights_type =
WeightsType.valueOf(parts[6]);
if(weights_type.hasFourInputs())
checkDataTypes(DataType.MATRIX, in4);
@@ -96,11 +104,18 @@ public abstract class QuaternaryFEDInstruction extends
ComputationFEDInstruction
return new QuaternaryWSLossFEDInstruction(qop,
in1, in2, in3, in4, out, opcode, str);
}
}
- else if(opcode.equals("wsigmoid")) {
+ else if(opcode.equals(WeightedSigmoid.OPCODE_CP)) {
final WSigmoidType wsigmoid_type =
WSigmoidType.valueOf(parts[5]);
qop = new QuaternaryOperator(wsigmoid_type);
return new QuaternaryWSigmoidFEDInstruction(qop, in1,
in2, in3, out, opcode, str);
}
+ else if(opcode.equals(WeightedUnaryMM.OPCODE_CP))
+ {
+ final WUMMType wumm_type = WUMMType.valueOf(parts[6]);
+ String uopcode = parts[1];
+ qop = new QuaternaryOperator(wumm_type, uopcode);
+ return new QuaternaryWUMMFEDInstruction(qop, in1, in2,
in3, out, opcode, str);
+ }
throw new DMLRuntimeException("Unsupported opcode (" + opcode +
") for QuaternaryFEDInstruction.");
}
@@ -125,4 +140,29 @@ public abstract class QuaternaryFEDInstruction extends
ComputationFEDInstruction
}
return false;
}
+
+ private static String rewriteSparkInstructionToCP(String inst_str) {
+ // rewrite the spark instruction to a cp instruction
+ inst_str = inst_str.replace(ExecType.SPARK.name(),
ExecType.CP.name());
+ if(inst_str.contains(WeightedCrossEntropy.OPCODE))
+ inst_str =
inst_str.replace(WeightedCrossEntropy.OPCODE, WeightedCrossEntropy.OPCODE_CP);
+ else if(inst_str.contains(WeightedDivMM.OPCODE))
+ inst_str = inst_str.replace(WeightedDivMM.OPCODE,
WeightedDivMM.OPCODE_CP);
+ else if(inst_str.contains(WeightedSigmoid.OPCODE))
+ inst_str = inst_str.replace(WeightedSigmoid.OPCODE,
WeightedSigmoid.OPCODE_CP);
+ else if(inst_str.contains(WeightedSquaredLoss.OPCODE))
+ inst_str = inst_str.replace(WeightedSquaredLoss.OPCODE,
WeightedSquaredLoss.OPCODE_CP);
+ else if(inst_str.contains(WeightedUnaryMM.OPCODE))
+ inst_str = inst_str.replace(WeightedUnaryMM.OPCODE,
WeightedUnaryMM.OPCODE_CP);
+ else if(inst_str.contains(WeightedDivMMR.OPCODE) ||
inst_str.contains(WeightedSquaredLossR.OPCODE)) {
+ inst_str = inst_str.replace(WeightedDivMMR.OPCODE,
WeightedDivMM.OPCODE_CP);
+ inst_str =
inst_str.replace(WeightedSquaredLossR.OPCODE, WeightedSquaredLoss.OPCODE_CP);
+ // remove booleans which indicate cacheU and cacheV for
redwsloss
+ inst_str = inst_str.replace(Lop.OPERAND_DELIMITOR +
"true", "");
+ inst_str = inst_str.replace(Lop.OPERAND_DELIMITOR +
"false", "");
+ }
+ inst_str += Lop.OPERAND_DELIMITOR + "1"; // num threads
+
+ return inst_str;
+ }
}
diff --git
a/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryWDivMMFEDInstruction.java
b/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryWDivMMFEDInstruction.java
new file mode 100644
index 0000000..5ba2b59
--- /dev/null
+++
b/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryWDivMMFEDInstruction.java
@@ -0,0 +1,164 @@
+/*
+ * 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.instructions.fed;
+
+import org.apache.sysds.runtime.instructions.InstructionUtils;
+import org.apache.sysds.runtime.matrix.operators.AggregateUnaryOperator;
+import org.apache.sysds.common.Types.DataType;
+import org.apache.sysds.lops.WeightedDivMM.WDivMMType;
+import org.apache.sysds.runtime.controlprogram.caching.MatrixObject;
+import org.apache.sysds.runtime.controlprogram.context.ExecutionContext;
+import org.apache.sysds.runtime.controlprogram.federated.FederatedRequest;
+import
org.apache.sysds.runtime.controlprogram.federated.FederatedRequest.RequestType;
+import org.apache.sysds.runtime.controlprogram.federated.FederatedResponse;
+import org.apache.sysds.runtime.controlprogram.federated.FederationMap;
+import org.apache.sysds.runtime.controlprogram.federated.FederationMap.FType;
+import org.apache.sysds.runtime.controlprogram.federated.FederationUtils;
+import org.apache.sysds.runtime.DMLRuntimeException;
+import org.apache.sysds.runtime.instructions.cp.CPOperand;
+import org.apache.sysds.runtime.instructions.cp.DoubleObject;
+import org.apache.sysds.runtime.instructions.cp.ScalarObject;
+import org.apache.sysds.runtime.matrix.operators.Operator;
+import org.apache.sysds.runtime.matrix.operators.QuaternaryOperator;
+
+import java.util.concurrent.Future;
+
+public class QuaternaryWDivMMFEDInstruction extends QuaternaryFEDInstruction
+{
+ /**
+ * This instruction performs:
+ *
+ * Z = X * (U %*% t(V));
+ * Z = (X / (U %*% t(V) + eps)) %*% V;
+ * and many more
+ *
+ * @param operator Weighted Div Matrix Multiplication Federated
Instruction.
+ * @param in1 X
+ * @param in2 U
+ * @param in3 V
+ * @param in4 W (=epsilon)
+ * @param out The Federated Result Z
+ * @param opcode ...
+ * @param instruction_str ...
+ */
+ protected QuaternaryWDivMMFEDInstruction(Operator operator,
+ CPOperand in1, CPOperand in2, CPOperand in3, CPOperand in4,
CPOperand out, String opcode, String instruction_str)
+ {
+ super(FEDType.Quaternary, operator, in1, in2, in3, in4, out,
opcode, instruction_str);
+ }
+
+ @Override
+ public void processInstruction(ExecutionContext ec)
+ {
+ QuaternaryOperator qop = (QuaternaryOperator) _optr;
+ final WDivMMType wdivmm_type = qop.wtype3;
+ MatrixObject X = ec.getMatrixObject(input1);
+ MatrixObject U = ec.getMatrixObject(input2);
+ MatrixObject V = ec.getMatrixObject(input3);
+ ScalarObject eps = null;
+ MatrixObject MX = null;
+
+ if(qop.hasFourInputs()) {
+ if(wdivmm_type == WDivMMType.MULT_MINUS_4_LEFT ||
wdivmm_type == WDivMMType.MULT_MINUS_4_RIGHT) {
+ MX = ec.getMatrixObject(_input4);
+ }
+ else {
+ eps = (_input4.getDataType() ==
DataType.SCALAR) ?
+ ec.getScalarInput(_input4) :
+ new
DoubleObject(ec.getMatrixInput(_input4.getName()).quickGetValue(0, 0));
+ }
+ }
+
+ if(!(X.isFederated(FType.ROW) && !U.isFederated() &&
!V.isFederated()))
+ throw new DMLRuntimeException("Unsupported federated
inputs (X, U, V) = ("
+ +X.isFederated()+", "+U.isFederated()+",
"+V.isFederated() + ")");
+
+ FederationMap fedMap = X.getFedMapping();
+ FederatedRequest[] frInit1 = fedMap.broadcastSliced(U, false);
+ FederatedRequest frInit2 = fedMap.broadcast(V);
+
+ FederatedRequest frInit3 = null;
+ FederatedRequest frInit3Arr[] = null;
+ FederatedRequest frCompute1 = null;
+ // broadcast scalar epsilon if there are four inputs
+ if(eps != null) {
+ frInit3 = fedMap.broadcast(eps);
+ // change the is_literal flag from true to false
because when broadcasted it is no literal anymore
+ instString = instString.replace("true", "false");
+ frCompute1 =
FederationUtils.callInstruction(instString, output,
+ new CPOperand[]{input1, input2, input3,
_input4},
+ new long[]{fedMap.getID(), frInit1[0].getID(),
frInit2.getID(), frInit3.getID()});
+ }
+ else if(MX != null) {
+ frInit3Arr = fedMap.broadcastSliced(MX, false);
+ frCompute1 =
FederationUtils.callInstruction(instString, output,
+ new CPOperand[]{input1, input2, input3,
_input4},
+ new long[]{fedMap.getID(), frInit1[0].getID(),
frInit2.getID(), frInit3Arr[0].getID()});
+ }
+ else {
+ frCompute1 =
FederationUtils.callInstruction(instString, output,
+ new CPOperand[]{input1, input2, input3},
+ new long[]{fedMap.getID(), frInit1[0].getID(),
frInit2.getID()});
+ }
+
+ // get partial results from federated workers
+ FederatedRequest frGet1 = new
FederatedRequest(RequestType.GET_VAR, frCompute1.getID());
+
+ FederatedRequest frCleanup1 = fedMap.cleanup(getTID(),
frCompute1.getID());
+ FederatedRequest frCleanup2 = fedMap.cleanup(getTID(),
frInit1[0].getID());
+ FederatedRequest frCleanup3 = fedMap.cleanup(getTID(),
frInit2.getID());
+
+ // execute federated instructions
+ Future<FederatedResponse>[] response;
+ if(frInit3 != null) {
+ FederatedRequest frCleanup4 = fedMap.cleanup(getTID(),
frInit3.getID());
+ response = fedMap.execute(getTID(), true,
+ frInit1, frInit2, frInit3,
+ frCompute1, frGet1,
+ frCleanup1, frCleanup2, frCleanup3, frCleanup4);
+ }
+ else if(frInit3Arr != null) {
+ FederatedRequest frCleanup4 = fedMap.cleanup(getTID(),
frInit3Arr[0].getID());
+ fedMap.execute(getTID(), true, frInit1, frInit2);
+ response = fedMap.execute(getTID(), true, frInit3Arr,
+ frCompute1, frGet1,
+ frCleanup1, frCleanup2, frCleanup3, frCleanup4);
+ }
+ else {
+ response = fedMap.execute(getTID(), true,
+ frInit1, frInit2,
+ frCompute1, frGet1,
+ frCleanup1, frCleanup2, frCleanup3);
+ }
+
+ if(wdivmm_type.isLeft()) {
+ // aggregate partial results from federated responses
+ AggregateUnaryOperator aop =
InstructionUtils.parseBasicAggregateUnaryOperator("uak+");
+ ec.setMatrixOutput(output.getName(),
FederationUtils.aggMatrix(aop, response, fedMap));
+ }
+ else if(wdivmm_type.isRight() || wdivmm_type.isBasic()) {
+ // bind partial results from federated responses
+ ec.setMatrixOutput(output.getName(),
FederationUtils.bind(response, false));
+ }
+ else {
+ throw new DMLRuntimeException("Federated WDivMM only
supported for BASIC, LEFT or RIGHT variants.");
+ }
+ }
+}
diff --git
a/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryWSLossFEDInstruction.java
b/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryWSLossFEDInstruction.java
index 2cd38a6..664fbdc 100644
---
a/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryWSLossFEDInstruction.java
+++
b/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryWSLossFEDInstruction.java
@@ -39,10 +39,10 @@ public class QuaternaryWSLossFEDInstruction extends
QuaternaryFEDInstruction {
/**
* This Instruction performs a Weighted Sigmoid Loss function as
follows:
- *
+ *
* Z = sum(W * (X - (U %*% t(V))) ^ 2)
- *
- * @param operator Weighted Sigmoid Loss
+ *
+ * @param operator Weighted Sigmoid Loss
* @param in1 X
* @param in2 U
* @param in3 V
@@ -71,7 +71,7 @@ public class QuaternaryWSLossFEDInstruction extends
QuaternaryFEDInstruction {
if(!(X.isFederated() && !U.isFederated() && !V.isFederated() &&
(W == null || !W.isFederated())))
throw new DMLRuntimeException("Unsupported federated
inputs (X, U, V, W) = (" + X.isFederated() + ", "
- + U.isFederated() + ", " + V.isFederated() + (W
!= null ? W.isFederated() : "none") + ")");
+ + U.isFederated() + ", " + V.isFederated() + ",
" + (W != null ? W.isFederated() : "none") + ")");
FederationMap fedMap = X.getFedMapping();
FederatedRequest[] frInit1 = fedMap.broadcastSliced(U, false);
diff --git
a/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryWSigmoidFEDInstruction.java
b/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryWSigmoidFEDInstruction.java
index 10456f8..9884e3b 100644
---
a/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryWSigmoidFEDInstruction.java
+++
b/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryWSigmoidFEDInstruction.java
@@ -36,9 +36,9 @@ public class QuaternaryWSigmoidFEDInstruction extends
QuaternaryFEDInstruction {
/**
* This instruction performs:
- *
+ *
* UV = U %*% t(V); Z = X * log(1 / (1 + exp(-UV)));
- *
+ *
* @param operator Weighted Sigmoid Federated Instruction.
* @param in1 X
* @param in2 U
diff --git
a/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryWSigmoidFEDInstruction.java
b/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryWUMMFEDInstruction.java
similarity index 86%
copy from
src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryWSigmoidFEDInstruction.java
copy to
src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryWUMMFEDInstruction.java
index 10456f8..82bc9e2 100644
---
a/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryWSigmoidFEDInstruction.java
+++
b/src/main/java/org/apache/sysds/runtime/instructions/fed/QuaternaryWUMMFEDInstruction.java
@@ -28,18 +28,20 @@ import
org.apache.sysds.runtime.controlprogram.federated.FederatedRequest;
import
org.apache.sysds.runtime.controlprogram.federated.FederatedRequest.RequestType;
import org.apache.sysds.runtime.controlprogram.federated.FederatedResponse;
import org.apache.sysds.runtime.controlprogram.federated.FederationMap;
+import org.apache.sysds.runtime.controlprogram.federated.FederationMap.FType;
import org.apache.sysds.runtime.controlprogram.federated.FederationUtils;
import org.apache.sysds.runtime.instructions.cp.CPOperand;
import org.apache.sysds.runtime.matrix.operators.Operator;
-public class QuaternaryWSigmoidFEDInstruction extends QuaternaryFEDInstruction
{
+public class QuaternaryWUMMFEDInstruction extends QuaternaryFEDInstruction {
/**
* This instruction performs:
- *
- * UV = U %*% t(V); Z = X * log(1 / (1 + exp(-UV)));
- *
- * @param operator Weighted Sigmoid Federated Instruction.
+ *
+ * Z = X / exp(U %*% t(V));
+ *
+ *
+ * @param operator Weighted Unary Matrix Multiplication
Federated Instruction.
* @param in1 X
* @param in2 U
* @param in3 V
@@ -47,7 +49,7 @@ public class QuaternaryWSigmoidFEDInstruction extends
QuaternaryFEDInstruction {
* @param opcode ...
* @param instruction_str ...
*/
- protected QuaternaryWSigmoidFEDInstruction(Operator operator, CPOperand
in1, CPOperand in2, CPOperand in3,
+ protected QuaternaryWUMMFEDInstruction(Operator operator, CPOperand
in1, CPOperand in2, CPOperand in3,
CPOperand out, String opcode, String instruction_str) {
super(FEDType.Quaternary, operator, in1, in2, in3, out, opcode,
instruction_str);
}
@@ -58,7 +60,7 @@ public class QuaternaryWSigmoidFEDInstruction extends
QuaternaryFEDInstruction {
MatrixObject U = ec.getMatrixObject(input2);
MatrixObject V = ec.getMatrixObject(input3);
- if(!(X.isFederated() && !U.isFederated() && !V.isFederated()))
+ if(!(X.isFederated(FType.ROW) && !U.isFederated() &&
!V.isFederated()))
throw new DMLRuntimeException("Unsupported federated
inputs (X, U, V) = (" + X.isFederated() + ", "
+ U.isFederated() + ", " + V.isFederated() +
")");
@@ -67,8 +69,7 @@ public class QuaternaryWSigmoidFEDInstruction extends
QuaternaryFEDInstruction {
FederatedRequest frInit2 = fedMap.broadcast(V);
FederatedRequest frCompute1 =
FederationUtils.callInstruction(instString,
- output,
- new CPOperand[] {input1, input2, input3},
+ output, new CPOperand[] {input1, input2, input3},
new long[] {fedMap.getID(), frInit1[0].getID(),
frInit2.getID()});
// get partial results from federated workers
@@ -84,6 +85,5 @@ public class QuaternaryWSigmoidFEDInstruction extends
QuaternaryFEDInstruction {
// bind partial results from federated responses
ec.setMatrixOutput(output.getName(),
FederationUtils.bind(response, false));
-
}
}
diff --git
a/src/test/java/org/apache/sysds/test/functions/federated/primitives/FederatedWeightedDivMatrixMultTest.java
b/src/test/java/org/apache/sysds/test/functions/federated/primitives/FederatedWeightedDivMatrixMultTest.java
new file mode 100644
index 0000000..39a79bb
--- /dev/null
+++
b/src/test/java/org/apache/sysds/test/functions/federated/primitives/FederatedWeightedDivMatrixMultTest.java
@@ -0,0 +1,311 @@
+/*
+ * 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.federated.primitives;
+
+import org.apache.sysds.common.Types.ExecMode;
+import org.apache.sysds.runtime.matrix.data.MatrixValue.CellIndex;
+import org.apache.sysds.runtime.meta.MatrixCharacteristics;
+import org.apache.sysds.runtime.util.HDFSTool;
+import org.apache.sysds.test.AutomatedTestBase;
+import org.apache.sysds.test.TestConfiguration;
+import org.apache.sysds.test.TestUtils;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+
+@RunWith(value = Parameterized.class)
[email protected]
+public class FederatedWeightedDivMatrixMultTest extends AutomatedTestBase
+{
+ private final static String LEFT_TEST_NAME = "FederatedWDivMMLeftTest";
+ private final static String RIGHT_TEST_NAME =
"FederatedWDivMMRightTest";
+ private final static String LEFT_EPS_TEST_NAME =
"FederatedWDivMMLeftEpsTest";
+ private final static String LEFT_EPS_2_TEST_NAME =
"FederatedWDivMMLeftEps2Test";
+ private final static String LEFT_EPS_3_TEST_NAME =
"FederatedWDivMMLeftEps3Test";
+ private final static String RIGHT_EPS_TEST_NAME =
"FederatedWDivMMRightEpsTest";
+ private final static String BASIC_MULT_TEST_NAME =
"FederatedWDivMMBasicMultTest";
+ private final static String LEFT_MULT_TEST_NAME =
"FederatedWDivMMLeftMultTest";
+ private final static String RIGHT_MULT_TEST_NAME =
"FederatedWDivMMRightMultTest";
+ private final static String LEFT_MULT_MINUS_TEST_NAME =
"FederatedWDivMMLeftMultMinusTest";
+ private final static String RIGHT_MULT_MINUS_TEST_NAME =
"FederatedWDivMMRightMultMinusTest";
+ private final static String LEFT_MULT_MINUS_4_TEST_NAME =
"FederatedWDivMMLeftMultMinus4Test";
+ private final static String RIGHT_MULT_MINUS_4_TEST_NAME =
"FederatedWDivMMRightMultMinus4Test";
+ private final static String TEST_DIR =
"functions/federated/quaternary/";
+ private final static String TEST_CLASS_DIR = TEST_DIR +
FederatedWeightedDivMatrixMultTest.class.getSimpleName() + "/";
+
+ private final static String OUTPUT_NAME = "Z";
+
+ private final static double TOLERANCE = 1e-9;
+
+ private final static int blocksize = 1024;
+
+ @Parameterized.Parameter()
+ public int rows;
+ @Parameterized.Parameter(1)
+ public int cols;
+ @Parameterized.Parameter(2)
+ public int rank;
+ @Parameterized.Parameter(3)
+ public double epsilon;
+ @Parameterized.Parameter(4)
+ public double sparsity;
+
+ @Override
+ public void setUp() {
+ addTestConfiguration(LEFT_TEST_NAME, new
TestConfiguration(TEST_CLASS_DIR, LEFT_TEST_NAME, new String[]{OUTPUT_NAME}));
+ addTestConfiguration(RIGHT_TEST_NAME, new
TestConfiguration(TEST_CLASS_DIR, RIGHT_TEST_NAME, new String[]{OUTPUT_NAME}));
+ addTestConfiguration(LEFT_EPS_TEST_NAME, new
TestConfiguration(TEST_CLASS_DIR, LEFT_EPS_TEST_NAME, new
String[]{OUTPUT_NAME}));
+ addTestConfiguration(LEFT_EPS_2_TEST_NAME, new
TestConfiguration(TEST_CLASS_DIR, LEFT_EPS_2_TEST_NAME, new
String[]{OUTPUT_NAME}));
+ addTestConfiguration(LEFT_EPS_3_TEST_NAME, new
TestConfiguration(TEST_CLASS_DIR, LEFT_EPS_3_TEST_NAME, new
String[]{OUTPUT_NAME}));
+ addTestConfiguration(RIGHT_EPS_TEST_NAME, new
TestConfiguration(TEST_CLASS_DIR, RIGHT_EPS_TEST_NAME, new
String[]{OUTPUT_NAME}));
+ addTestConfiguration(BASIC_MULT_TEST_NAME, new
TestConfiguration(TEST_CLASS_DIR, BASIC_MULT_TEST_NAME, new
String[]{OUTPUT_NAME}));
+ addTestConfiguration(LEFT_MULT_TEST_NAME, new
TestConfiguration(TEST_CLASS_DIR, LEFT_MULT_TEST_NAME, new
String[]{OUTPUT_NAME}));
+ addTestConfiguration(RIGHT_MULT_TEST_NAME, new
TestConfiguration(TEST_CLASS_DIR, RIGHT_MULT_TEST_NAME, new
String[]{OUTPUT_NAME}));
+ addTestConfiguration(LEFT_MULT_MINUS_TEST_NAME, new
TestConfiguration(TEST_CLASS_DIR, LEFT_MULT_MINUS_TEST_NAME, new
String[]{OUTPUT_NAME}));
+ addTestConfiguration(RIGHT_MULT_MINUS_TEST_NAME, new
TestConfiguration(TEST_CLASS_DIR, RIGHT_MULT_MINUS_TEST_NAME, new
String[]{OUTPUT_NAME}));
+ addTestConfiguration(LEFT_MULT_MINUS_4_TEST_NAME, new
TestConfiguration(TEST_CLASS_DIR, LEFT_MULT_MINUS_4_TEST_NAME, new
String[]{OUTPUT_NAME}));
+ addTestConfiguration(RIGHT_MULT_MINUS_4_TEST_NAME, new
TestConfiguration(TEST_CLASS_DIR, RIGHT_MULT_MINUS_4_TEST_NAME, new
String[]{OUTPUT_NAME}));
+ }
+
+ @Parameterized.Parameters
+ public static Collection<Object[]> data() {
+ // rows must be even
+ return Arrays.asList(new Object[][] {
+ // {rows, cols, rank, epsilon, sparsity}
+ {1202, 1003, 5, 1.321, 0.001},
+ {1202, 1003, 5, 1.321, 0.45}
+ });
+ }
+
+ @BeforeClass
+ public static void init() {
+ TestUtils.clearDirectory(TEST_DATA_DIR + TEST_CLASS_DIR);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultLeftSingleNode() {
+ federatedWeightedDivMatrixMult(LEFT_TEST_NAME,
ExecMode.SINGLE_NODE);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultLeftSpark() {
+ federatedWeightedDivMatrixMult(LEFT_TEST_NAME, ExecMode.SPARK);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultRightSingleNode() {
+ federatedWeightedDivMatrixMult(RIGHT_TEST_NAME,
ExecMode.SINGLE_NODE);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultRightSpark() {
+ federatedWeightedDivMatrixMult(RIGHT_TEST_NAME, ExecMode.SPARK);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultLeftEpsSingleNode() {
+ federatedWeightedDivMatrixMult(LEFT_EPS_TEST_NAME,
ExecMode.SINGLE_NODE);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultLeftEpsSpark() {
+ federatedWeightedDivMatrixMult(LEFT_EPS_TEST_NAME,
ExecMode.SPARK);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultLeftEps2SingleNode() {
+ federatedWeightedDivMatrixMult(LEFT_EPS_2_TEST_NAME,
ExecMode.SINGLE_NODE);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultLeftEps2Spark() {
+ federatedWeightedDivMatrixMult(LEFT_EPS_2_TEST_NAME,
ExecMode.SPARK);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultLeftEps3SingleNode() {
+ federatedWeightedDivMatrixMult(LEFT_EPS_3_TEST_NAME,
ExecMode.SINGLE_NODE);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultLeftEps3Spark() {
+ federatedWeightedDivMatrixMult(LEFT_EPS_3_TEST_NAME,
ExecMode.SPARK);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultRightEpsSingleNode() {
+ federatedWeightedDivMatrixMult(RIGHT_EPS_TEST_NAME,
ExecMode.SINGLE_NODE);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultRightEpsSpark() {
+ federatedWeightedDivMatrixMult(RIGHT_EPS_TEST_NAME,
ExecMode.SPARK);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultBasicMultSingleNode() {
+ federatedWeightedDivMatrixMult(BASIC_MULT_TEST_NAME,
ExecMode.SINGLE_NODE);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultBasicMultSpark() {
+ federatedWeightedDivMatrixMult(BASIC_MULT_TEST_NAME,
ExecMode.SPARK);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultLeftMultSingleNode() {
+ federatedWeightedDivMatrixMult(LEFT_MULT_TEST_NAME,
ExecMode.SINGLE_NODE);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultLeftMultSpark() {
+ federatedWeightedDivMatrixMult(LEFT_MULT_TEST_NAME,
ExecMode.SPARK);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultRightMultSingleNode() {
+ federatedWeightedDivMatrixMult(RIGHT_MULT_TEST_NAME,
ExecMode.SINGLE_NODE);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultRightMultSpark() {
+ federatedWeightedDivMatrixMult(RIGHT_MULT_TEST_NAME,
ExecMode.SPARK);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultLeftMultMinusSingleNode() {
+ federatedWeightedDivMatrixMult(LEFT_MULT_MINUS_TEST_NAME,
ExecMode.SINGLE_NODE);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultLeftMultMinusSpark() {
+ federatedWeightedDivMatrixMult(LEFT_MULT_MINUS_TEST_NAME,
ExecMode.SPARK);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultRightMultMinusSingleNode() {
+ federatedWeightedDivMatrixMult(RIGHT_MULT_MINUS_TEST_NAME,
ExecMode.SINGLE_NODE);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultRightMultMinusSpark() {
+ federatedWeightedDivMatrixMult(RIGHT_MULT_MINUS_TEST_NAME,
ExecMode.SPARK);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultLeftMultMinus4SingleNode() {
+ federatedWeightedDivMatrixMult(LEFT_MULT_MINUS_4_TEST_NAME,
ExecMode.SINGLE_NODE);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultLeftMultMinus4Spark() {
+ federatedWeightedDivMatrixMult(LEFT_MULT_MINUS_4_TEST_NAME,
ExecMode.SPARK);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultRightMultMinus4SingleNode() {
+ federatedWeightedDivMatrixMult(RIGHT_MULT_MINUS_4_TEST_NAME,
ExecMode.SINGLE_NODE);
+ }
+
+ @Test
+ public void federatedWeightedDivMatrixMultRightMultMinus4Spark() {
+ federatedWeightedDivMatrixMult(RIGHT_MULT_MINUS_4_TEST_NAME,
ExecMode.SPARK);
+ }
+
+//
-----------------------------------------------------------------------------
+
+ public void federatedWeightedDivMatrixMult(String test_name, ExecMode
exec_mode)
+ {
+ // store the previous platform config to restore it after the
test
+ ExecMode platform_old = setExecMode(exec_mode);
+
+ getAndLoadTestConfiguration(test_name);
+ String HOME = SCRIPT_DIR + TEST_DIR;
+
+ int fed_rows = rows / 2;
+ int fed_cols = cols;
+
+ // generate dataset
+ // matrix handled by two federated workers
+ double[][] X1 = getRandomMatrix(fed_rows, fed_cols, 0, 1,
sparsity, 3);
+ double[][] X2 = getRandomMatrix(fed_rows, fed_cols, 0, 1,
sparsity, 7);
+
+ double[][] U = getRandomMatrix(rows, rank, 0, 1, 1, 512);
+ double[][] V = getRandomMatrix(cols, rank, 0, 1, 1, 5040);
+
+ writeInputMatrixWithMTD("X1", X1, false, new
MatrixCharacteristics(fed_rows, fed_cols, blocksize, fed_rows * fed_cols));
+ writeInputMatrixWithMTD("X2", X2, false, new
MatrixCharacteristics(fed_rows, fed_cols, blocksize, fed_rows * fed_cols));
+
+ writeInputMatrixWithMTD("U", U, true, new
MatrixCharacteristics(rows, rank, blocksize, rows * rank));
+ writeInputMatrixWithMTD("V", V, true, new
MatrixCharacteristics(cols, rank, blocksize, rows * rank));
+
+ // empty script name because we don't execute any script, just
start the worker
+ fullDMLScriptName = "";
+ int port1 = getRandomAvailablePort();
+ int port2 = getRandomAvailablePort();
+ Thread thread1 = startLocalFedWorkerThread(port1,
FED_WORKER_WAIT_S);
+ Thread thread2 = startLocalFedWorkerThread(port2);
+
+ getAndLoadTestConfiguration(test_name);
+
+ try {
+ // Run reference dml script with normal matrix
+ fullDMLScriptName = HOME + test_name + "Reference.dml";
+ programArgs = new String[] {"-nvargs", "in_X1=" +
input("X1"), "in_X2=" + input("X2"),
+ "in_U=" + input("U"), "in_V=" + input("V"),
"in_W=" + Double.toString(epsilon),
+ "out_Z=" + expected(OUTPUT_NAME)};
+ runTest(true, false, null, -1);
+
+ // Run actual dml script with federated matrix
+ fullDMLScriptName = HOME + test_name + ".dml";
+ programArgs = new String[] {"-stats", "-nvargs",
+ "in_X1=" + TestUtils.federatedAddress(port1,
input("X1")),
+ "in_X2=" + TestUtils.federatedAddress(port2,
input("X2")),
+ "in_U=" + input("U"),
+ "in_V=" + input("V"),
+ "in_W=" + Double.toString(epsilon),
+ "rows=" + fed_rows, "cols=" + fed_cols,
"out_Z=" + output(OUTPUT_NAME)};
+ runTest(true, false, null, -1);
+
+ // compare the results via files
+ HashMap<CellIndex, Double> refResults =
readDMLMatrixFromExpectedDir(OUTPUT_NAME);
+ HashMap<CellIndex, Double> fedResults =
readDMLMatrixFromOutputDir(OUTPUT_NAME);
+ TestUtils.compareMatrices(fedResults, refResults,
TOLERANCE, "Fed", "Ref");
+
+ // check for federated operations
+
Assert.assertTrue(heavyHittersContainsString("fed_wdivmm"));
+
+ // check that federated input files are still existing
+
Assert.assertTrue(HDFSTool.existsFileOnHDFS(input("X1")));
+
Assert.assertTrue(HDFSTool.existsFileOnHDFS(input("X2")));
+ }
+ finally {
+ TestUtils.shutdownThreads(thread1, thread2);
+
+ resetExecMode(platform_old);
+ }
+ }
+}
diff --git
a/src/test/java/org/apache/sysds/test/functions/federated/primitives/FederatedWeightedUnaryMatrixMultTest.java
b/src/test/java/org/apache/sysds/test/functions/federated/primitives/FederatedWeightedUnaryMatrixMultTest.java
new file mode 100644
index 0000000..581d27d
--- /dev/null
+++
b/src/test/java/org/apache/sysds/test/functions/federated/primitives/FederatedWeightedUnaryMatrixMultTest.java
@@ -0,0 +1,202 @@
+/*
+ * 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.federated.primitives;
+
+import org.apache.sysds.common.Types.ExecMode;
+import org.apache.sysds.runtime.matrix.data.MatrixValue.CellIndex;
+import org.apache.sysds.runtime.meta.MatrixCharacteristics;
+import org.apache.sysds.runtime.util.HDFSTool;
+import org.apache.sysds.test.AutomatedTestBase;
+import org.apache.sysds.test.TestConfiguration;
+import org.apache.sysds.test.TestUtils;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+
+@RunWith(value = Parameterized.class)
[email protected]
+public class FederatedWeightedUnaryMatrixMultTest extends AutomatedTestBase
+{
+ private final static String EXP_MULT_TEST_NAME =
"FederatedWUMMExpMultTest";
+ private final static String EXP_DIV_TEST_NAME =
"FederatedWUMMExpDivTest";
+ private final static String POW_2_TEST_NAME = "FederatedWUMMPow2Test";
+ private final static String MULT_2_TEST_NAME = "FederatedWUMMMult2Test";
+ private final static String TEST_DIR =
"functions/federated/quaternary/";
+ private final static String TEST_CLASS_DIR = TEST_DIR +
FederatedWeightedUnaryMatrixMultTest.class.getSimpleName() + "/";
+
+ private final static String OUTPUT_NAME = "Z";
+
+ private final static double TOLERANCE = 0;
+
+ private final static int blocksize = 1024;
+
+ @Parameterized.Parameter()
+ public int rows;
+ @Parameterized.Parameter(1)
+ public int cols;
+ @Parameterized.Parameter(2)
+ public int rank;
+ @Parameterized.Parameter(3)
+ public double sparsity;
+
+ @Override
+ public void setUp() {
+ addTestConfiguration(EXP_MULT_TEST_NAME, new
TestConfiguration(TEST_CLASS_DIR, EXP_MULT_TEST_NAME, new
String[]{OUTPUT_NAME}));
+ addTestConfiguration(EXP_DIV_TEST_NAME, new
TestConfiguration(TEST_CLASS_DIR, EXP_DIV_TEST_NAME, new
String[]{OUTPUT_NAME}));
+ addTestConfiguration(POW_2_TEST_NAME, new
TestConfiguration(TEST_CLASS_DIR, POW_2_TEST_NAME, new String[]{OUTPUT_NAME}));
+ addTestConfiguration(MULT_2_TEST_NAME, new
TestConfiguration(TEST_CLASS_DIR, MULT_2_TEST_NAME, new String[]{OUTPUT_NAME}));
+ }
+
+ @Parameterized.Parameters
+ public static Collection<Object[]> data()
+ {
+ // rows must be even
+ return Arrays.asList(new Object[][] {
+ // {rows, cols, rank, sparsity}
+ {1202, 1003, 5, 0.001},
+ {1202, 1003, 5, 0.6}
+ });
+ }
+
+ @BeforeClass
+ public static void init() {
+ TestUtils.clearDirectory(TEST_DATA_DIR + TEST_CLASS_DIR);
+ }
+
+ @Test
+ public void federatedWeightedUnaryMatrixMultExpMultSingleNode() {
+ federatedWeightedUnaryMatrixMult(EXP_MULT_TEST_NAME,
ExecMode.SINGLE_NODE);
+ }
+
+ @Test
+ public void federatedWeightedUnaryMatrixMultExpMultSpark() {
+ federatedWeightedUnaryMatrixMult(EXP_MULT_TEST_NAME,
ExecMode.SPARK);
+ }
+
+ @Test
+ public void federatedWeightedUnaryMatrixMultExpDivSingleNode() {
+ federatedWeightedUnaryMatrixMult(EXP_DIV_TEST_NAME,
ExecMode.SINGLE_NODE);
+ }
+
+ @Test
+ public void federatedWeightedUnaryMatrixMultExpDivSpark() {
+ federatedWeightedUnaryMatrixMult(EXP_DIV_TEST_NAME,
ExecMode.SPARK);
+ }
+
+ @Test
+ public void federatedWeightedUnaryMatrixMultPow2SingleNode() {
+ federatedWeightedUnaryMatrixMult(POW_2_TEST_NAME,
ExecMode.SINGLE_NODE);
+ }
+
+ @Test
+ public void federatedWeightedUnaryMatrixMultPow2Spark() {
+ federatedWeightedUnaryMatrixMult(POW_2_TEST_NAME,
ExecMode.SPARK);
+ }
+
+ @Test
+ public void federatedWeightedUnaryMatrixMultMult2SingleNode() {
+ federatedWeightedUnaryMatrixMult(MULT_2_TEST_NAME,
ExecMode.SINGLE_NODE);
+ }
+
+ @Test
+ public void federatedWeightedUnaryMatrixMultMult2Spark() {
+ federatedWeightedUnaryMatrixMult(MULT_2_TEST_NAME,
ExecMode.SPARK);
+ }
+
+//
-----------------------------------------------------------------------------
+
+ public void federatedWeightedUnaryMatrixMult(String test_name, ExecMode
exec_mode)
+ {
+ // store the previous platform config to restore it after the
test
+ ExecMode platform_old = setExecMode(exec_mode);
+
+ getAndLoadTestConfiguration(test_name);
+ String HOME = SCRIPT_DIR + TEST_DIR;
+
+ int fed_rows = rows / 2;
+ int fed_cols = cols;
+
+ // generate dataset
+ // matrix handled by two federated workers
+ double[][] X1 = getRandomMatrix(fed_rows, fed_cols, 0, 1,
sparsity, 3);
+ double[][] X2 = getRandomMatrix(fed_rows, fed_cols, 0, 1,
sparsity, 7);
+
+ double[][] U = getRandomMatrix(rows, rank, 0, 1, 1, 512);
+ double[][] V = getRandomMatrix(cols, rank, 0, 1, 1, 5040);
+
+ writeInputMatrixWithMTD("X1", X1, false, new
MatrixCharacteristics(fed_rows, fed_cols, blocksize, fed_rows * fed_cols));
+ writeInputMatrixWithMTD("X2", X2, false, new
MatrixCharacteristics(fed_rows, fed_cols, blocksize, fed_rows * fed_cols));
+
+ writeInputMatrixWithMTD("U", U, false, new
MatrixCharacteristics(rows, rank, blocksize, rows * rank));
+ writeInputMatrixWithMTD("V", V, false, new
MatrixCharacteristics(cols, rank, blocksize, rows * rank));
+
+ // empty script name because we don't execute any script, just
start the worker
+ fullDMLScriptName = "";
+ int port1 = getRandomAvailablePort();
+ int port2 = getRandomAvailablePort();
+ Thread thread1 = startLocalFedWorkerThread(port1,
FED_WORKER_WAIT_S);
+ Thread thread2 = startLocalFedWorkerThread(port2);
+
+ getAndLoadTestConfiguration(test_name);
+
+ try {
+ // Run reference dml script with normal matrix
+ fullDMLScriptName = HOME + test_name + "Reference.dml";
+ programArgs = new String[] {"-nvargs", "in_X1=" +
input("X1"), "in_X2=" + input("X2"),
+ "in_U=" + input("U"), "in_V=" + input("V"),
+ "out_Z=" + expected(OUTPUT_NAME)};
+ runTest(true, false, null, -1);
+
+ // Run actual dml script with federated matrix
+ fullDMLScriptName = HOME + test_name + ".dml";
+ programArgs = new String[] {"-stats", "-nvargs",
+ "in_X1=" + TestUtils.federatedAddress(port1,
input("X1")),
+ "in_X2=" + TestUtils.federatedAddress(port2,
input("X2")),
+ "in_U=" + input("U"),
+ "in_V=" + input("V"),
+ "rows=" + fed_rows, "cols=" + fed_cols,
"out_Z=" + output(OUTPUT_NAME)};
+ runTest(true, false, null, -1);
+
+ // compare the results via files
+ HashMap<CellIndex, Double> refResults =
readDMLMatrixFromExpectedDir(OUTPUT_NAME);
+ HashMap<CellIndex, Double> fedResults =
readDMLMatrixFromOutputDir(OUTPUT_NAME);
+ TestUtils.compareMatrices(fedResults, refResults,
TOLERANCE, "Fed", "Ref");
+
+ // check for federated operations
+
Assert.assertTrue(heavyHittersContainsString("fed_wumm"));
+
+ // check that federated input files are still existing
+
Assert.assertTrue(HDFSTool.existsFileOnHDFS(input("X1")));
+
Assert.assertTrue(HDFSTool.existsFileOnHDFS(input("X2")));
+ }
+ finally {
+ TestUtils.shutdownThreads(thread1, thread2);
+
+ resetExecMode(platform_old);
+ }
+ }
+
+}
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMBasicMultTest.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMBasicMultTest.dml
new file mode 100644
index 0000000..beb6b20
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMBasicMultTest.dml
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = federated(addresses=list($in_X1, $in_X2),
+ ranges=list(list(0, 0), list($rows, $cols), list($rows, 0), list($rows * 2,
$cols)))
+
+U = read($in_U)
+V = read($in_V)
+
+Z = X * (U %*% t(V));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMBasicMultTestReference.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMBasicMultTestReference.dml
new file mode 100644
index 0000000..895b339
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMBasicMultTestReference.dml
@@ -0,0 +1,28 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = rbind(read($in_X1), read($in_X2))
+U = read($in_U)
+V = read($in_V)
+
+Z = X * (U %*% t(V));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEps2Test.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEps2Test.dml
new file mode 100644
index 0000000..4f66854
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEps2Test.dml
@@ -0,0 +1,31 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = federated(addresses=list($in_X1, $in_X2),
+ ranges=list(list(0, 0), list($rows, $cols), list($rows, 0), list($rows * 2,
$cols)))
+
+U = read($in_U)
+V = read($in_V)
+eps = $in_W
+
+Z = t(t(U) %*% (X / (eps + U %*% t(V))));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEps2TestReference.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEps2TestReference.dml
new file mode 100644
index 0000000..df66035
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEps2TestReference.dml
@@ -0,0 +1,29 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = rbind(read($in_X1), read($in_X2))
+U = read($in_U)
+V = read($in_V)
+eps = $in_W
+
+Z = t(t(U) %*% (X / (eps + U %*% t(V))));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEps3Test.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEps3Test.dml
new file mode 100644
index 0000000..81875d9
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEps3Test.dml
@@ -0,0 +1,31 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = federated(addresses=list($in_X1, $in_X2),
+ ranges=list(list(0, 0), list($rows, $cols), list($rows, 0), list($rows * 2,
$cols)))
+
+U = read($in_U)
+V = read($in_V)
+eps = $in_W
+
+Z = t(t(U) %*% (X / (U %*% t(V) - eps)));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEps3TestReference.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEps3TestReference.dml
new file mode 100644
index 0000000..5d3bac1
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEps3TestReference.dml
@@ -0,0 +1,29 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = rbind(read($in_X1), read($in_X2))
+U = read($in_U)
+V = read($in_V)
+eps = $in_W
+
+Z = t(t(U) %*% (X / (U %*% t(V) - eps)));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEpsTest.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEpsTest.dml
new file mode 100644
index 0000000..3cf45e5
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEpsTest.dml
@@ -0,0 +1,31 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = federated(addresses=list($in_X1, $in_X2),
+ ranges=list(list(0, 0), list($rows, $cols), list($rows, 0), list($rows * 2,
$cols)))
+
+U = read($in_U)
+V = read($in_V)
+eps = $in_W
+
+Z = t(t(U) %*% (X / (U %*% t(V) + eps)));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEpsTestReference.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEpsTestReference.dml
new file mode 100644
index 0000000..363988d
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftEpsTestReference.dml
@@ -0,0 +1,29 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = rbind(read($in_X1), read($in_X2))
+U = read($in_U)
+V = read($in_V)
+eps = $in_W
+
+Z = t(t(U) %*% (X / (U %*% t(V) + eps)));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultMinus4Test.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultMinus4Test.dml
new file mode 100644
index 0000000..a6e12a6
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultMinus4Test.dml
@@ -0,0 +1,32 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = federated(addresses=list($in_X1, $in_X2),
+ ranges=list(list(0, 0), list($rows, $cols), list($rows, 0), list($rows * 2,
$cols)))
+
+U = read($in_U)
+V = read($in_V)
+
+MX = X / 0.7;
+
+Z = t(t(U) %*% (X * (U %*% t(V) - MX)));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultMinus4TestReference.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultMinus4TestReference.dml
new file mode 100644
index 0000000..89546b7
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultMinus4TestReference.dml
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = rbind(read($in_X1), read($in_X2))
+U = read($in_U)
+V = read($in_V)
+
+MX = X / 0.7;
+
+Z = t(t(U) %*% (X * (U %*% t(V) - MX)));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultMinusTest.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultMinusTest.dml
new file mode 100644
index 0000000..ad81c52
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultMinusTest.dml
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = federated(addresses=list($in_X1, $in_X2),
+ ranges=list(list(0, 0), list($rows, $cols), list($rows, 0), list($rows * 2,
$cols)))
+
+U = read($in_U)
+V = read($in_V)
+
+Z = t(t(U) %*% ((X != 0) * (U %*% t(V) - X)));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultMinusTestReference.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultMinusTestReference.dml
new file mode 100644
index 0000000..95211e6
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultMinusTestReference.dml
@@ -0,0 +1,28 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = rbind(read($in_X1), read($in_X2))
+U = read($in_U)
+V = read($in_V)
+
+Z = t(t(U) %*% ((X != 0) * (U %*% t(V) - X)));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultTest.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultTest.dml
new file mode 100644
index 0000000..732f17a
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultTest.dml
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = federated(addresses=list($in_X1, $in_X2),
+ ranges=list(list(0, 0), list($rows, $cols), list($rows, 0), list($rows * 2,
$cols)))
+
+U = read($in_U)
+V = read($in_V)
+
+Z = t(t(U) %*% (X * (U %*% t(V))));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultTestReference.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultTestReference.dml
new file mode 100644
index 0000000..8f0ca6d
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftMultTestReference.dml
@@ -0,0 +1,28 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = rbind(read($in_X1), read($in_X2))
+U = read($in_U)
+V = read($in_V)
+
+Z = t(t(U) %*% (X * (U %*% t(V))));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftTest.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftTest.dml
new file mode 100644
index 0000000..4df09a0
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftTest.dml
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = federated(addresses=list($in_X1, $in_X2),
+ ranges=list(list(0, 0), list($rows, $cols), list($rows, 0), list($rows * 2,
$cols)))
+
+U = read($in_U)
+V = read($in_V)
+
+Z = t(t(U) %*% (X / (U %*% t(V))));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftTestReference.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftTestReference.dml
new file mode 100644
index 0000000..cc23631
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMLeftTestReference.dml
@@ -0,0 +1,28 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = rbind(read($in_X1), read($in_X2))
+U = read($in_U)
+V = read($in_V)
+
+Z = t(t(U) %*% (X / (U %*% t(V))));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightEpsTest.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightEpsTest.dml
new file mode 100644
index 0000000..a457ff1
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightEpsTest.dml
@@ -0,0 +1,31 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = federated(addresses=list($in_X1, $in_X2),
+ ranges=list(list(0, 0), list($rows, $cols), list($rows, 0), list($rows * 2,
$cols)))
+
+U = read($in_U)
+V = read($in_V)
+eps = $in_W
+
+Z = (X / (U %*% t(V) + eps)) %*% V;
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightEpsTestReference.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightEpsTestReference.dml
new file mode 100644
index 0000000..1c9efa2
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightEpsTestReference.dml
@@ -0,0 +1,29 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = rbind(read($in_X1), read($in_X2))
+U = read($in_U)
+V = read($in_V)
+eps = $in_W
+
+Z = (X / (U %*% t(V) + eps)) %*% V;
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultMinus4Test.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultMinus4Test.dml
new file mode 100644
index 0000000..ff5fdc2
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultMinus4Test.dml
@@ -0,0 +1,32 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = federated(addresses=list($in_X1, $in_X2),
+ ranges=list(list(0, 0), list($rows, $cols), list($rows, 0), list($rows * 2,
$cols)))
+
+U = read($in_U)
+V = read($in_V)
+
+MX = X / 0.3
+
+Z = (X * (U %*% t(V) - MX)) %*% V;
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultMinus4TestReference.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultMinus4TestReference.dml
new file mode 100644
index 0000000..e49f4d9
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultMinus4TestReference.dml
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = rbind(read($in_X1), read($in_X2))
+U = read($in_U)
+V = read($in_V)
+
+MX = X / 0.3
+
+Z = (X * (U %*% t(V) - MX)) %*% V;
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultMinusTest.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultMinusTest.dml
new file mode 100644
index 0000000..203415e
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultMinusTest.dml
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = federated(addresses=list($in_X1, $in_X2),
+ ranges=list(list(0, 0), list($rows, $cols), list($rows, 0), list($rows * 2,
$cols)))
+
+U = read($in_U)
+V = read($in_V)
+
+Z = ((X != 0) * (U %*% t(V) - X)) %*% V;
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultMinusTestReference.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultMinusTestReference.dml
new file mode 100644
index 0000000..8f114d1
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultMinusTestReference.dml
@@ -0,0 +1,28 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = rbind(read($in_X1), read($in_X2))
+U = read($in_U)
+V = read($in_V)
+
+Z = ((X != 0) * (U %*% t(V) - X)) %*% V;
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultTest.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultTest.dml
new file mode 100644
index 0000000..cab65d5
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultTest.dml
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = federated(addresses=list($in_X1, $in_X2),
+ ranges=list(list(0, 0), list($rows, $cols), list($rows, 0), list($rows * 2,
$cols)))
+
+U = read($in_U)
+V = read($in_V)
+
+Z = (X * (U %*% t(V))) %*% V;
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultTestReference.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultTestReference.dml
new file mode 100644
index 0000000..535b7f5
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightMultTestReference.dml
@@ -0,0 +1,28 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = rbind(read($in_X1), read($in_X2))
+U = read($in_U)
+V = read($in_V)
+
+Z = (X * (U %*% t(V))) %*% V;
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightTest.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightTest.dml
new file mode 100644
index 0000000..de64cf1
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightTest.dml
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = federated(addresses=list($in_X1, $in_X2),
+ ranges=list(list(0, 0), list($rows, $cols), list($rows, 0), list($rows * 2,
$cols)))
+
+U = read($in_U)
+V = read($in_V)
+
+Z = (X / (U %*% t(V))) %*% V;
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightTestReference.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightTestReference.dml
new file mode 100644
index 0000000..1fa64e8
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWDivMMRightTestReference.dml
@@ -0,0 +1,28 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = rbind(read($in_X1), read($in_X2))
+U = read($in_U)
+V = read($in_V)
+
+Z = (X / (U %*% t(V))) %*% V;
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWUMMExpDivTest.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWUMMExpDivTest.dml
new file mode 100644
index 0000000..80bbe4c
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWUMMExpDivTest.dml
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = federated(addresses=list($in_X1, $in_X2),
+ ranges=list(list(0, 0), list($rows, $cols), list($rows, 0), list($rows * 2,
$cols)))
+
+U = read($in_U)
+V = read($in_V)
+
+Z = X / exp(U %*% t(V));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWUMMExpDivTestReference.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWUMMExpDivTestReference.dml
new file mode 100644
index 0000000..3d67597
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWUMMExpDivTestReference.dml
@@ -0,0 +1,28 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = rbind(read($in_X1), read($in_X2))
+U = read($in_U)
+V = read($in_V)
+
+Z = X / exp(U %*% t(V));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWUMMExpMultTest.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWUMMExpMultTest.dml
new file mode 100644
index 0000000..7a33915
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWUMMExpMultTest.dml
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = federated(addresses=list($in_X1, $in_X2),
+ ranges=list(list(0, 0), list($rows, $cols), list($rows, 0), list($rows * 2,
$cols)))
+
+U = read($in_U)
+V = read($in_V)
+
+Z = X * exp(U %*% t(V));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWUMMExpMultTestReference.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWUMMExpMultTestReference.dml
new file mode 100644
index 0000000..56bc818
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWUMMExpMultTestReference.dml
@@ -0,0 +1,28 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = rbind(read($in_X1), read($in_X2))
+U = read($in_U)
+V = read($in_V)
+
+Z = X * exp(U %*% t(V));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWUMMMult2Test.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWUMMMult2Test.dml
new file mode 100644
index 0000000..da5b318
--- /dev/null
+++ b/src/test/scripts/functions/federated/quaternary/FederatedWUMMMult2Test.dml
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = federated(addresses=list($in_X1, $in_X2),
+ ranges=list(list(0, 0), list($rows, $cols), list($rows, 0), list($rows * 2,
$cols)))
+
+U = read($in_U)
+V = read($in_V)
+
+Z = X * (2 * (U %*% t(V)));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWUMMMult2TestReference.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWUMMMult2TestReference.dml
new file mode 100644
index 0000000..45d7ffc
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWUMMMult2TestReference.dml
@@ -0,0 +1,28 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = rbind(read($in_X1), read($in_X2))
+U = read($in_U)
+V = read($in_V)
+
+Z = X * (2 * (U %*% t(V)));
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWUMMPow2Test.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWUMMPow2Test.dml
new file mode 100644
index 0000000..b31050e
--- /dev/null
+++ b/src/test/scripts/functions/federated/quaternary/FederatedWUMMPow2Test.dml
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = federated(addresses=list($in_X1, $in_X2),
+ ranges=list(list(0, 0), list($rows, $cols), list($rows, 0), list($rows * 2,
$cols)))
+
+U = read($in_U)
+V = read($in_V)
+
+Z = X / (U %*% t(V))^2;
+
+write(Z, $out_Z)
diff --git
a/src/test/scripts/functions/federated/quaternary/FederatedWUMMPow2TestReference.dml
b/src/test/scripts/functions/federated/quaternary/FederatedWUMMPow2TestReference.dml
new file mode 100644
index 0000000..294b112
--- /dev/null
+++
b/src/test/scripts/functions/federated/quaternary/FederatedWUMMPow2TestReference.dml
@@ -0,0 +1,28 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+X = rbind(read($in_X1), read($in_X2))
+U = read($in_U)
+V = read($in_V)
+
+Z = X / (U %*% t(V))^2;
+
+write(Z, $out_Z)