Skip to content

Commit c40f53d

Browse files
committed
improve coverage
1 parent 4750c98 commit c40f53d

11 files changed

Lines changed: 147 additions & 49 deletions

File tree

vecxt/js-native/src/array.scala

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ object JsNativeDoubleArrays:
101101
i += 1
102102
end while
103103
Matrix[Double](newArr, (m.rows, m.cols))
104-
else
105-
???
104+
else ???
105+
end if
106106
end *:*
107107

108108
inline def +=(n: Double): Unit =
@@ -140,29 +140,26 @@ object JsNativeDoubleArrays:
140140
inline def >=(d: Double): Matrix[Boolean] =
141141
if m.hasSimpleContiguousMemoryLayout then
142142
Matrix[Boolean](vecxt.arrays.>=(m.raw)(d), m.shape)(using BoundsCheck.DoBoundsCheck.no)
143-
else
144-
???
145-
143+
else ???
146144

147145
inline def >(d: Double): Matrix[Boolean] =
148146
if m.hasSimpleContiguousMemoryLayout then
149147
Matrix[Boolean](vecxt.arrays.>(m.raw)(d), m.shape)(using BoundsCheck.DoBoundsCheck.no)
150-
else
151-
???
148+
else ???
152149
end if
150+
end >
153151

154152
inline def <=(d: Double): Matrix[Boolean] =
155153
if m.hasSimpleContiguousMemoryLayout then
156154
Matrix[Boolean](vecxt.arrays.<=(m.raw)(d), m.shape)(using BoundsCheck.DoBoundsCheck.no)
157-
else
158-
???
155+
else ???
159156
end if
157+
end <=
160158

161159
inline def <(d: Double): Matrix[Boolean] =
162160
if m.hasSimpleContiguousMemoryLayout then
163161
Matrix[Boolean](vecxt.arrays.<(m.raw)(d), m.shape)(using BoundsCheck.DoBoundsCheck.no)
164-
else
165-
???
162+
else ???
166163
end extension
167164

168165
// extension [@specialized(Double, Int) A: Numeric](m: Matrix[A])

vecxt/js/src/doublematrix.scala

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,37 @@ object JsDoubleMatrix:
3434
m.rows
3535
)
3636
Matrix[Double](newArr, (m.rows, b.cols))
37-
else
38-
???
37+
else ???
38+
end if
3939

4040
end matmul
41+
42+
43+
inline def *(vec: NArray[Double])(using inline boundsCheck: BoundsCheck): NArray[Double] =
44+
if m.hasSimpleContiguousMemoryLayout then
45+
val newArr = Float64Array(m.rows)
46+
dgemv(
47+
if m.isDenseColMajor then "column-major" else "row-major",
48+
"no-transpose",
49+
m.rows,
50+
m.cols,
51+
1.0,
52+
m.raw,
53+
m.rows,
54+
vec,
55+
1,
56+
0.0,
57+
newArr,
58+
1
59+
)
60+
newArr
61+
else ???
62+
end *
63+
4164
end extension
65+
66+
67+
4268
end JsDoubleMatrix
4369

4470
object JvmDoubleMatrix:

vecxt/js/src/stdlib.facade.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,25 @@ object dgemm extends js.Object:
7272
c: Float64Array,
7373
ldc: Int
7474
): Unit = js.native
75+
7576
end dgemm
77+
78+
@js.native
79+
@JSImport("@stdlib/blas/base/dgemv/lib", JSImport.Default)
80+
object dgemv extends js.Object:
81+
def apply(
82+
ord: String,
83+
transA: String,
84+
m: Int,
85+
n: Int,
86+
alpha: Double,
87+
a: Float64Array,
88+
lda: Int,
89+
b: Float64Array,
90+
ldb: Int,
91+
beta: Double,
92+
c: Float64Array,
93+
ldc: Int
94+
): Unit = js.native
95+
96+
end dgemv

vecxt/jvm/src/doublematrix.scala

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,25 +70,31 @@ object JvmDoubleMatrix:
7070

7171
// inline def *:*=(d: Double): Unit = m.raw.multInPlace(d)
7272

73+
// TODO: Dim check
7374

74-
//TODO: Dim check
75-
76-
inline def *(vec: Array[Double])(using inline boundsCheck: BoundsCheck): Array[Double] =
77-
val newArr = Array.ofDim[Double](m.rows)
78-
blas.dgemv(
79-
"N",
80-
m.rows,
81-
m.cols,
82-
1.0,
83-
m.raw,
84-
m.rows,
85-
vec,
86-
1,
87-
0.0,
88-
newArr,
89-
1
90-
)
91-
newArr
75+
inline def *(vec: Array[Double], alpha : Double = 1.0, beta: Double = 1.0)(using inline boundsCheck: BoundsCheck): Array[Double] =
76+
77+
if m.isDenseColMajor then
78+
require(vec.length == m.cols, s"Vector length ${vec.length} != expected ${m.cols}")
79+
val newArr = Array.ofDim[Double](m.rows)
80+
val out = Array.fill(m.rows)(0.0)
81+
82+
blas.dgemv(
83+
"N",
84+
m.rows,
85+
m.cols,
86+
alpha,
87+
m.raw,
88+
m.rows,
89+
vec,
90+
1,
91+
beta,
92+
newArr,
93+
1
94+
)
95+
96+
newArr
97+
else ???
9298
end *
9399

94100
inline def >=(d: Double): Matrix[Boolean] =

vecxt/native/src/doublematrix.scala

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ object NativeDoubleMatrix:
1717
inline def matmul(b: Matrix[Double])(using inline boundsCheck: BoundsCheck): Matrix[Double] =
1818
dimMatCheck(m, b)
1919

20-
2120
if m.hasSimpleContiguousMemoryLayout && b.hasSimpleContiguousMemoryLayout then
21+
if !m.isDenseColMajor && b.isDenseColMajor then ???
22+
end if
23+
2224
val newArr = Array.ofDim[Double](m.rows * b.cols)
2325
blas.cblas_dgemm(
24-
blasEnums.CblasColMajor,
26+
if m.isDenseColMajor then blasEnums.CblasColMajor else blasEnums.CblasRowMajor,
2527
blasEnums.CblasNoTrans,
2628
blasEnums.CblasNoTrans,
2729
m.rows,
@@ -37,8 +39,31 @@ object NativeDoubleMatrix:
3739
m.rows
3840
)
3941
Matrix(newArr, (m.rows, b.cols))
40-
else
41-
???
42+
else ???
43+
end if
44+
end matmul
45+
46+
inline def *(vec: Array[Double])(using inline boundsCheck: BoundsCheck): Array[Double] =
47+
48+
if m.hasSimpleContiguousMemoryLayout then
49+
val newArr = Array.ofDim[Double](m.rows)
50+
blas.cblas_dgemv(
51+
if m.isDenseColMajor then blasEnums.CblasColMajor else blasEnums.CblasRowMajor,
52+
blasEnums.CblasNoTrans,
53+
m.rows,
54+
m.cols,
55+
1.0,
56+
m.raw.at(0),
57+
m.rows,
58+
vec.at(0),
59+
1,
60+
0.0,
61+
newArr.at(0),
62+
1
63+
)
64+
newArr
65+
else ???
66+
end *
4267

4368
end extension
4469

vecxt/src/MatrixInstance.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ object MatrixInstance:
116116
end while
117117

118118
Matrix(newArr, (newRows.size, newCols.size))(using BoundsCheck.DoBoundsCheck.no)
119-
else
120-
???
119+
else ???
120+
end if
121121

122122
end apply
123123

@@ -130,11 +130,12 @@ object MatrixInstance:
130130

131131
inline def elementIndex(row: Row, col: Col)(using inline boundsCheck: BoundsCheck): Int =
132132
indexCheckMat(m, (row, col))
133-
inline if(boundsCheck == BoundsCheck.DoBoundsCheck.yes) then
133+
inline if boundsCheck == BoundsCheck.DoBoundsCheck.yes then
134134
println(s"Element index for ($row, $col) in matrix with shape ${m.shape} is being checked")
135135
println(s"Offset: ${m.offset}, Row stride: ${m.rowStride}, Col stride: ${m.colStride}")
136136
println(s"Calculated index: ${m.offset + row * m.rowStride + col * m.colStride}")
137137
println(s"element: ${m.raw(m.offset + row * m.rowStride + col * m.colStride)}")
138+
end if
138139
m.offset + row * m.rowStride + col * m.colStride
139140

140141
end elementIndex

vecxt/src/doublematrix.scala

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,10 @@ object DoubleMatrix:
2727
inline def /(m: Matrix[Double])(using inline boundsCheck: BoundsCheck): Matrix[Double] = ???
2828

2929
inline def *=(m: Matrix[Double])(using inline boundsCheck: BoundsCheck): Unit = m *= d
30-
inline def +=(m: Matrix[Double])(using inline boundsCheck: BoundsCheck): Unit = ??? //m += d
31-
inline def -=(m: Matrix[Double])(using inline boundsCheck: BoundsCheck): Unit = ??? //m -= d
30+
inline def +=(m: Matrix[Double])(using inline boundsCheck: BoundsCheck): Unit = ??? // m += d
31+
inline def -=(m: Matrix[Double])(using inline boundsCheck: BoundsCheck): Unit = ??? // m -= d
3232
inline def /=(m: Matrix[Double])(using inline boundsCheck: BoundsCheck): Unit = ???
3333

34-
35-
3634
end extension
3735

3836
extension (m: Matrix[Double])

vecxt/src/matrix.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@ object matrix:
9292
)
9393
end apply
9494

95-
/**
96-
* Assumes column major order.
95+
/** Assumes column major order.
9796
*
9897
* @param raw
9998
* @param rows

vecxt/src/matrixutil.scala

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ object matrixUtil:
8282
Matrix[B](newArr, (1, m.cols))
8383
end mapColsToScalar
8484

85-
// TODO: Horrible performance
8685
inline def transpose: Matrix[A] = Matrix(
8786
raw = m.raw,
8887
rows = m.cols, // swap dimensions
@@ -135,8 +134,7 @@ object matrixUtil:
135134
newArr
136135
end diag
137136

138-
/**
139-
* Returns a row of the matrix as an NArray.
137+
/** Returns a row of the matrix as an NArray.
140138
*
141139
* Note that this copies the data. m.submatrix(i, ::) returns a zero copy view.
142140
*
@@ -165,8 +163,7 @@ object matrixUtil:
165163
arrArr.mkString("\n")
166164
end printMat
167165

168-
/**
169-
* Note that m.submatrix(::, i) will give back a zero-copy matrix with the correct strides.
166+
/** Note that m.submatrix(::, i) will give back a zero-copy matrix with the correct strides.
170167
*
171168
* It is probably more efficient
172169
*

vecxt/test/src/matrix.test.scala

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,30 @@ class MatrixExtensionSuite extends FunSuite:
181181

182182
}
183183

184+
test("dgemv precedance col major") {
185+
val mat1 = Matrix.fromRows(
186+
NArray(1.0, 2.0, 3.0),
187+
NArray(4.0, 5.0, 6.0)
188+
)
189+
190+
val arr1 = NArray[Double](1.0, 2.0, 3.0)
191+
192+
val arr2 = NArray[Double](1.0, 2.0)
193+
194+
assertVecEquals(mat1 * arr1, NArray[Double](14.0, 32.0))
195+
196+
// println("Mat1")
197+
// println(mat1.transpose.printMat)
198+
// println("Arr1")
199+
// println(arr2.printArr)
200+
201+
// println("result")
202+
// println((mat1.transpose * arr2).printArr)
203+
// assertVecEquals(mat1.transpose * arr2, NArray[Double](6.0, 30.0))
204+
205+
206+
}
207+
184208
test("zeros") {
185209
val tensor = Matrix.zeros[Double](2, 2)
186210
assertVecEquals[Double](tensor.raw, NArray[Double](0.0, 0.0, 0.0, 0.0))

0 commit comments

Comments
 (0)