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)

Reply via email to