Repository: intel/ipex-llm
Pull request: bug fix for cmul
## What changes were proposed in this pull request?

fix cmul error when batchsize equals one of element number. (e.g. input size (64, 64, 112, 112))

## How was this patch tested?

unit tests and example tests

## Related links or issues (optional)
fixed https://github.com/intel-analytics/BigDL/issues/2812



Problem statement:
ResNet50 MKLDNN accuracy issue
Analytics-zoo model (converted from caffe) could be directly load by `loadModule`, but the accuracy gets bad(**top1/5 55%/77%** compared to bigdl model **top1/5 75%/92%**)

The model used is resnet50 pretrained one, using mkldnn as backend

However there is no error raised, seems the weights and bias are loaded correctly. What happens?

Hints from issue discussion:
@Litchilitchy Hi, I use examples in zoo to test model (converted from caffe) accuracy.
**With MKLDNN and MKLBLAS backend, I got same accuracy for Imagenet validation dataset.**
Top1Accuracy is Accuracy(correct: 36433, count: 50000, accuracy: 0.72866)
Top5Accuracy is Accuracy(correct: 45571, count: 50000, accuracy: 0.91142)

So please check your test code. Please let me know if there is still accuracy inconsistent.

Commit message: bugfix for cmul

Patch to review:
diff --git a/spark/dl/src/main/scala/com/intel/analytics/bigdl/nn/CMul.scala b/spark/dl/src/main/scala/com/intel/analytics/bigdl/nn/CMul.scala
index 1ab34031115..5c148d5022a 100644
--- a/spark/dl/src/main/scala/com/intel/analytics/bigdl/nn/CMul.scala
+++ b/spark/dl/src/main/scala/com/intel/analytics/bigdl/nn/CMul.scala
@@ -82,13 +82,19 @@ class CMul[T: ClassTag](
   }
 
   private def mulOneDimWeight(dim: Int, expand: Tensor[T], output: Tensor[T]): Unit = {
-    val multiplyDimSize = expand.size(dim)
-    var dimOfOutput : Int = 1
-    while(output.size(dimOfOutput) != multiplyDimSize) {
-
-      dimOfOutput += 1
-      require(dimOfOutput <= output.dim(), s"OutOfBound : " +
-        s"Output does not have a dimension of $multiplyDimSize elements")
+    var dimOfOutput : Int = dim
+    if (expand.dim() > output.dim()) {
+      val multiplyDimSize = expand.size(dim)
+      var dimTemp : Int = 1
+      while(output.size(dimTemp) != multiplyDimSize) {
+        dimTemp += 1
+        require(dimTemp <= output.dim(), s"OutOfBound : " +
+          s"Output does not have a dimension of $multiplyDimSize elements")
+      }
+      dimOfOutput = dimTemp
+    } else {
+      require(output.size(dim) == expand.size(dim), s"OutOfBound : " +
+        s"Output does not have a dimension of ${expand.size(dim)} elements")
     }
     val (innerNum, outerNum) = Utils.getInnerOuterNum(dimOfOutput, output)
     val weightData = expand.storage().array()
diff --git a/spark/dl/src/test/scala/com/intel/analytics/bigdl/nn/CMulSpec.scala b/spark/dl/src/test/scala/com/intel/analytics/bigdl/nn/CMulSpec.scala
index 1f21f990c63..29292f42589 100644
--- a/spark/dl/src/test/scala/com/intel/analytics/bigdl/nn/CMulSpec.scala
+++ b/spark/dl/src/test/scala/com/intel/analytics/bigdl/nn/CMulSpec.scala
@@ -16,6 +16,7 @@
 
 package com.intel.analytics.bigdl.nn
 
+import com.intel.analytics.bigdl.nn
 import com.intel.analytics.bigdl.tensor.Tensor
 import org.scalatest.{FlatSpec, Matchers}
 import com.intel.analytics.bigdl.utils.RandomGenerator._
@@ -65,6 +66,22 @@ class CMulSpec extends FlatSpec with Matchers {
     gradInput3 should be (gradInput4)
     layer2.gradWeight should be (layer1.gradWeight.mul(0.5))
   }
+
+  "CMUl" should "work good on batch input" in {
+    val model = nn.CMul[Float](Array(1, 64, 1, 1))
+    val model2 = model.cloneModule()
+
+    val batchInput = Tensor[Float](64, 64, 112, 112).rand()
+    val input = batchInput.select(1, 1).resize(Array(1, 64, 112, 112))
+
+    model.evaluate()
+    model2.evaluate()
+
+    val out1 = model.forward(batchInput)
+    val out2 = model2.forward(input).resize(Array(64, 112, 112))
+
+    out2 should be(out1.select(1, 1))
+  }
 }
 
 class CMulSerialTest extends ModuleSerializationTest {


Code review comments:
diff_hunk: @@ -82,13 +82,19 @@ class CMul[T: ClassTag](
   }
 
   private def mulOneDimWeight(dim: Int, expand: Tensor[T], output: Tensor[T]): Unit = {
-    val multiplyDimSize = expand.size(dim)
-    var dimOfOutput : Int = 1
-    while(output.size(dimOfOutput) != multiplyDimSize) {
-
-      dimOfOutput += 1
-      require(dimOfOutput <= output.dim(), s"OutOfBound : " +
-        s"Output does not have a dimension of $multiplyDimSize elements")
+    var dimOfOutput : Int = dim
path: spark/dl/src/main/scala/com/intel/analytics/bigdl/nn/CMul.scala
text: @user1:
`outputDim` ?

@author:
ok, changed