From b18c06928ccf6faa47e577ba98c6e8302c521101 Mon Sep 17 00:00:00 2001 From: qiuxin2012 Date: Wed, 19 Oct 2016 13:15:26 +0800 Subject: [PATCH 1/3] bug fix for gemm --- .../sparkdl/tensor/DenseTensorBLAS.scala | 19 ++++++++++++------- .../sparkdl/tensor/DenseTensorMath.scala | 4 ++-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/dl/src/main/scala/com/intel/analytics/sparkdl/tensor/DenseTensorBLAS.scala b/dl/src/main/scala/com/intel/analytics/sparkdl/tensor/DenseTensorBLAS.scala index 15e010fdc65..1840a01ef78 100644 --- a/dl/src/main/scala/com/intel/analytics/sparkdl/tensor/DenseTensorBLAS.scala +++ b/dl/src/main/scala/com/intel/analytics/sparkdl/tensor/DenseTensorBLAS.scala @@ -35,12 +35,16 @@ object DenseTensorBLAS { var time = 0L - def dgemm[@specialized(Float, Double) T](transa: String, transb: String, m: Int, n: Int, - k: Int, alpha: T, a: Array[T], aOffset: Int, - lda: Int, b: Array[T], bOffset: Int, ldb: Int, beta: T, c: Array[T], cOffset: Int, - ldc: Int)(implicit ev: TensorNumeric[T]): Unit = { + def gemm[@specialized(Float, Double) T](transa: String, transb: String, + m: Int, n: Int, k: Int, + alpha: T, + a: Array[T], aOffset: Int, lda: Int, + b: Array[T], bOffset: Int, ldb: Int, + beta: T, + c: Array[T], cOffset: Int, ldc: Int + )(implicit ev: TensorNumeric[T]): Unit = { val _transa = (transa == "t" || transa == "T") - val _transb = (transa == "t" || transa == "T") + val _transb = (transb == "t" || transb == "T") var _ldc = ldc if (n == 1) { @@ -75,8 +79,9 @@ object DenseTensorBLAS { time += (System.nanoTime() - start) } - def dgemv[@specialized(Float, Double) T](alpha: T, matrix: Tensor[T], vector: Tensor[T], - beta: T, r: Tensor[T])(implicit ev: TensorNumeric[T]): Unit = { + def gemv[@specialized(Float, Double) T](alpha: T, matrix: Tensor[T], vector: Tensor[T], + beta: T, r: Tensor[T] + )(implicit ev: TensorNumeric[T]): Unit = { require(matrix.size(2) == vector.size(1), "matrix vector size doesn't match") require(matrix.size(1) == r.size(1), "matrix result size doesn't match") if (matrix.stride(1) == 1) { diff --git a/dl/src/main/scala/com/intel/analytics/sparkdl/tensor/DenseTensorMath.scala b/dl/src/main/scala/com/intel/analytics/sparkdl/tensor/DenseTensorMath.scala index c46171758b7..5eb6a349ba5 100644 --- a/dl/src/main/scala/com/intel/analytics/sparkdl/tensor/DenseTensorMath.scala +++ b/dl/src/main/scala/com/intel/analytics/sparkdl/tensor/DenseTensorMath.scala @@ -243,7 +243,7 @@ object DenseTensorMath { new DenseTensor(new ArrayStorage(Array(result))) } else if (self.nDimension() == 2 && t.nDimension() == 1) { val result = new DenseTensor[T](self.size(1)) - DenseTensorBLAS.dgemv[T](ev.fromType[Int](1), self, t, ev.fromType[Int](0), result) + DenseTensorBLAS.gemv[T](ev.fromType[Int](1), self, t, ev.fromType[Int](0), result) result } else if (self.nDimension() == 2 && t.nDimension() == 2) { val result = new DenseTensor[T](t.size(2), self.size(1)).t() @@ -367,7 +367,7 @@ object DenseTensorMath { __m2 = _m2.contiguous() } - DenseTensorBLAS.dgemm[T](transpose_m1, transpose_m2, _r.size(index1), _r.size(index2), + DenseTensorBLAS.gemm[T](transpose_m1, transpose_m2, _r.size(index1), _r.size(index2), __m1.size(index2), alpha, __m1.storage().array(), __m1.storageOffset() - 1, if (transpose_m1 == "n") __m1.stride(index2) else __m1.stride(index1), __m2.storage().array(), __m2.storageOffset() - 1, From ac2781347654c294bcc78318bb7444ea731053b5 Mon Sep 17 00:00:00 2001 From: qiuxin2012 Date: Wed, 19 Oct 2016 18:02:17 +0800 Subject: [PATCH 2/3] adjust indent for DenseTensorBLAS --- .../sparkdl/tensor/DenseTensorBLAS.scala | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dl/src/main/scala/com/intel/analytics/sparkdl/tensor/DenseTensorBLAS.scala b/dl/src/main/scala/com/intel/analytics/sparkdl/tensor/DenseTensorBLAS.scala index 1840a01ef78..e40951eeb82 100644 --- a/dl/src/main/scala/com/intel/analytics/sparkdl/tensor/DenseTensorBLAS.scala +++ b/dl/src/main/scala/com/intel/analytics/sparkdl/tensor/DenseTensorBLAS.scala @@ -36,13 +36,13 @@ object DenseTensorBLAS { var time = 0L def gemm[@specialized(Float, Double) T](transa: String, transb: String, - m: Int, n: Int, k: Int, - alpha: T, - a: Array[T], aOffset: Int, lda: Int, - b: Array[T], bOffset: Int, ldb: Int, - beta: T, - c: Array[T], cOffset: Int, ldc: Int - )(implicit ev: TensorNumeric[T]): Unit = { + m: Int, n: Int, k: Int, + alpha: T, + a: Array[T], aOffset: Int, lda: Int, + b: Array[T], bOffset: Int, ldb: Int, + beta: T, + c: Array[T], cOffset: Int, ldc: Int)(implicit ev: TensorNumeric[T]): Unit = { + val _transa = (transa == "t" || transa == "T") val _transb = (transb == "t" || transb == "T") @@ -80,8 +80,8 @@ object DenseTensorBLAS { } def gemv[@specialized(Float, Double) T](alpha: T, matrix: Tensor[T], vector: Tensor[T], - beta: T, r: Tensor[T] - )(implicit ev: TensorNumeric[T]): Unit = { + beta: T, r: Tensor[T])(implicit ev: TensorNumeric[T]): Unit = { + require(matrix.size(2) == vector.size(1), "matrix vector size doesn't match") require(matrix.size(1) == r.size(1), "matrix result size doesn't match") if (matrix.stride(1) == 1) { From 112df4257113d5e7f647a009fc561be8612e3993 Mon Sep 17 00:00:00 2001 From: qiuxin2012 Date: Wed, 19 Oct 2016 18:02:57 +0800 Subject: [PATCH 3/3] Unit test for DenseTensorBLAS.gemm --- .../sparkdl/tensor/DenseTensorMathSpec.scala | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/dl/src/test/scala/com/intel/analytics/sparkdl/tensor/DenseTensorMathSpec.scala b/dl/src/test/scala/com/intel/analytics/sparkdl/tensor/DenseTensorMathSpec.scala index 1701851dbea..b371b183b75 100644 --- a/dl/src/test/scala/com/intel/analytics/sparkdl/tensor/DenseTensorMathSpec.scala +++ b/dl/src/test/scala/com/intel/analytics/sparkdl/tensor/DenseTensorMathSpec.scala @@ -595,4 +595,116 @@ class DenseTensorMathSpec extends FlatSpec with Matchers { r should be(Tensor[Float](Storage[Float]( Array(1.0986123f, 1.3862944f, 1.609438f)), 1, Array(1, 3))) } + + "gemm(N, N)" should "return correct value" in { + val matrixA = Tensor[Float](2, 3) + val matrixB = Tensor[Float](3, 2) + + var i = 0 + matrixA.apply1(_ => { + i = i + 1; + i + }) + matrixB.copy(matrixA) + + val matrixC = Tensor[Float](2, 2) + + DenseTensorBLAS.gemm[Float]( + "N", "N", + 2, 2, 3, + 1, + matrixA.storage().array(), matrixA.storageOffset() - 1, 2, + matrixB.storage().array(), matrixB.storageOffset() - 1, 3, + 0, + matrixC.storage().array(), matrixC.storageOffset() - 1, 2 + ) + + val result = Tensor[Float](Storage(Array[Float](22, 28, 49, 64)), 1, Array(2, 2)) + + matrixC should be (result) + } + + "gemm(N, T)" should "return correct value" in { + val matrixA = Tensor[Float](2, 3) + val matrixB = Tensor[Float](2, 3) + + var i = 0 + matrixA.apply1(_ => { + i = i + 1; + i + }) + matrixB.copy(matrixA) + + val matrixC = Tensor[Float](2, 2) + + DenseTensorBLAS.gemm[Float]( + "N", "T", + 2, 2, 3, + 1, + matrixA.storage().array(), matrixA.storageOffset() - 1, 2, + matrixB.storage().array(), matrixB.storageOffset() - 1, 2, + 0, + matrixC.storage().array(), matrixC.storageOffset() - 1, 2 + ) + + val result = Tensor[Float](Storage(Array[Float](35, 44, 44, 56)), 1, Array(2, 2)) + + matrixC should be (result) + } + + "gemm(T, N)" should "return correct value" in { + val matrixA = Tensor[Float](3, 2) + val matrixB = Tensor[Float](3, 2) + + var i = 0 + matrixA.apply1(_ => { + i = i + 1; + i + }) + matrixB.copy(matrixA) + + val matrixC = Tensor[Float](2, 2) + + DenseTensorBLAS.gemm[Float]( + "T", "N", + 2, 2, 3, + 1, + matrixA.storage().array(), matrixA.storageOffset() - 1, 3, + matrixB.storage().array(), matrixB.storageOffset() - 1, 3, + 0, + matrixC.storage().array(), matrixC.storageOffset() - 1, 2 + ) + + val result = Tensor[Float](Storage(Array[Float](14, 32, 32, 77)), 1, Array(2, 2)) + + matrixC should be (result) + } + + "gemm(T, T)" should "return correct value" in { + val matrixA = Tensor[Float](3, 2) + val matrixB = Tensor[Float](2, 3) + + var i = 0 + matrixA.apply1(_ => { + i = i + 1; + i + }) + matrixB.copy(matrixA) + + val matrixC = Tensor[Float](2, 2) + + DenseTensorBLAS.gemm[Float]( + "T", "T", + 2, 2, 3, + 1, + matrixA.storage().array(), matrixA.storageOffset() - 1, 3, + matrixB.storage().array(), matrixB.storageOffset() - 1, 2, + 0, + matrixC.storage().array(), matrixC.storageOffset() - 1, 2 + ) + + val result = Tensor[Float](Storage(Array[Float](22, 49, 28, 64)), 1, Array(2, 2)) + + matrixC should be (result) + } }