Repository: intel/ipex-llm
Pull request: Concat check input size check
## What changes were proposed in this pull request?

Each module output inside concat is supposed to have the same dim size exception the one for concatenating, this change is to do the sanity check to make it more user friendly when exception happens

## How was this patch tested?

Unit test

## Related links or issues (optional)
fixed https://github.com/intel-analytics/BigDL/issues/2027



Problem statement:
Concate layer should pop proper infor to users if size mismatch
Concat  requires only size of `dimension` for each output variable and other size should be the same among each output, we should do the size checking otherwise user may get unexpected exception

Hints from issue discussion:

Commit message: add dim check

Patch to review:
diff --git a/spark/dl/src/main/scala/com/intel/analytics/bigdl/nn/Concat.scala b/spark/dl/src/main/scala/com/intel/analytics/bigdl/nn/Concat.scala
index fb5e5ec8833..8cb0060629f 100644
--- a/spark/dl/src/main/scala/com/intel/analytics/bigdl/nn/Concat.scala
+++ b/spark/dl/src/main/scala/com/intel/analytics/bigdl/nn/Concat.scala
@@ -73,6 +73,8 @@ class Concat[T: ClassTag](val dimension: Int)(
       results = new Array[Future[Unit]](this.modules.length)
     }
 
+    checkOutputs(outs, dimension)
+
     var offset = 1
     i = 0
     while (i < this.modules.length) {
@@ -108,6 +110,27 @@ class Concat[T: ClassTag](val dimension: Int)(
     this.output
   }
 
+  private def checkOutputs(outputs : Array[Tensor[T]], dim : Int) : Unit = {
+    if (outputs == null || outputs.length == 0) {
+      return
+    }
+    val size = outputs(0).size()
+    val dim = size.length
+    for ( i <- 1 until outputs.length) {
+      val currSize = outputs(i).size()
+      require(currSize.length == dim, s"output for each concat " +
+        s"module should have the same dim, ${i}th output dim" +
+        s"not equals to first output dim ${currSize.length} != ${dim}")
+      for (j <- 0 until dim) {
+        if (j != (dim - 1)) {
+          require(size(j) == currSize(j), s"output for each concat module should be of the " +
+            s"same size at dimension ${dim}, while ${i}th output at ${j} dimension not" +
+            s"equals to first output at ${j}th dimension ${currSize(j)} != ${size(j)}")
+        }
+      }
+    }
+  }
+
   override def getTimes(): Array[(AbstractModule[_ <: Activity, _ <: Activity, T], Long, Long)] = {
     this.modules.flatMap(_.getTimes()).toArray ++
       Array((this, forwardTimeOverhead, backwardTime))


Code review comments:
diff_hunk: @@ -108,6 +110,27 @@ class Concat[T: ClassTag](val dimension: Int)(
     this.output
   }
 
+  private def checkOutputs(outputs : Array[Tensor[T]], dim : Int) : Unit = {
path: spark/dl/src/main/scala/com/intel/analytics/bigdl/nn/Concat.scala
text: @user1:
Can we do this check at line 66? when update this.size also check other dimensinos

@author:
@user1  makes sense,  we don't need to wait all module to compute before check, coming back shortly with refinement

diff_hunk: @@ -108,6 +110,27 @@ class Concat[T: ClassTag](val dimension: Int)(
     this.output
   }
 
+  private def checkOutputs(outputs : Array[Tensor[T]], dim : Int) : Unit = {
+    if (outputs == null || outputs.length == 0) {
+      return
+    }
+    val size = outputs(0).size()
+    val dim = size.length
+    for ( i <- 1 until outputs.length) {
path: spark/dl/src/main/scala/com/intel/analytics/bigdl/nn/Concat.scala
text: @user1:
avoid to use for here.