Skip to content

Commit 0b72a91

Browse files
CopilotQuafadas
andcommitted
Support row-major deepCopy and use array *= for hadamard
Co-authored-by: Quafadas <24899792+Quafadas@users.noreply.github.com>
1 parent 9bdee4d commit 0b72a91

5 files changed

Lines changed: 73 additions & 34 deletions

File tree

vecxt/src-js/array_native.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,17 @@ object JsNativeDoubleArrays:
456456
res
457457
end *
458458

459+
inline def *=(d: NArray[Double])(using inline boundsCheck: BoundsCheck): Unit =
460+
dimCheck(vec, d)
461+
val n = vec.length
462+
463+
var i = 0
464+
while i < n do
465+
vec(i) = vec(i) * d(i)
466+
i += 1
467+
end while
468+
end *=
469+
459470
inline def outer(other: NArray[Double])(using ClassTag[Double]): Matrix[Double] =
460471
val n = vec.length
461472
val m = other.length

vecxt/src-jvm/arrays.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,23 @@ object arrays:
11761176
out
11771177
end *
11781178

1179+
inline def *=(d: Array[Double])(using inline boundsCheck: BoundsCheck): Unit =
1180+
dimCheck(vec, d)
1181+
var i = 0
1182+
while i < spd.loopBound(vec.length) do
1183+
DoubleVector
1184+
.fromArray(spd, vec, i)
1185+
.mul(DoubleVector.fromArray(spd, d, i))
1186+
.intoArray(vec, i)
1187+
i += spdl
1188+
end while
1189+
1190+
while i < vec.length do
1191+
vec(i) = vec(i) * d(i)
1192+
i = i + 1
1193+
end while
1194+
end *=
1195+
11791196
inline def /(d: Array[Double])(using inline boundsCheck: BoundsCheck): Array[Double] =
11801197
dimCheck(vec, d)
11811198
val out = new Array[Double](vec.length)

vecxt/src-native/array_js_native.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,17 @@ object JsNativeDoubleArrays:
456456
res
457457
end *
458458

459+
inline def *=(d: NArray[Double])(using inline boundsCheck: BoundsCheck): Unit =
460+
dimCheck(vec, d)
461+
val n = vec.length
462+
463+
var i = 0
464+
while i < n do
465+
vec(i) = vec(i) * d(i)
466+
i += 1
467+
end while
468+
end *=
469+
459470
inline def outer(other: NArray[Double])(using ClassTag[Double]): Matrix[Double] =
460471
val n = vec.length
461472
val m = other.length

vecxt/src/MatrixInstance.scala

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,23 @@ object MatrixInstance:
127127
* @return
128128
*/
129129
def deepCopy(using ct: ClassTag[A]): Matrix[A] =
130+
deepCopy(asRowMajor = false)
131+
end deepCopy
132+
133+
/** Returns a deep copy of the matrix with specified layout. Copies elements one by one.
134+
*
135+
* @param asRowMajor
136+
* If true, returns row-major layout; if false, returns column-major layout
137+
* @param ct
138+
* @return
139+
*/
140+
def deepCopy(asRowMajor: Boolean)(using ct: ClassTag[A]): Matrix[A] =
130141
// println(s"Deep copying matrix with shape ${m.shape} and offset ${m.offset}")
131142
import BoundsCheck.DoBoundsCheck.no
132143
val newRaw = NArray.ofSize[A](m.numel)
133-
val newMat = Matrix(newRaw, m.rows, m.cols, 1, m.rows, 0)
144+
val newMat =
145+
if asRowMajor then Matrix(newRaw, m.rows, m.cols, m.cols, 1, 0) // row-major: rowStride = cols, colStride = 1
146+
else Matrix(newRaw, m.rows, m.cols, 1, m.rows, 0) // column-major: rowStride = 1, colStride = rows
134147
var i = 0
135148
for row <- 0 until m.rows do
136149
for col <- 0 until m.cols do

vecxt/src/doublematrix.scala

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -146,44 +146,31 @@ object DoubleMatrix:
146146
val newArr = vecxt.arrays.*(m.raw)(m2.raw)
147147
Matrix[Double](newArr, m.rows, m.cols, m.rowStride, m.colStride, m.offset)(using BoundsCheck.DoBoundsCheck.no)
148148
else
149-
// Different memory layouts: materialize only one matrix and multiply in-place
150-
// Choose which matrix to materialize based on which is already dense column-major
149+
// Different memory layouts: materialize one matrix to match the other's layout
151150
if m.isDenseColMajor then
152-
// m is already dense, materialize m2 and multiply in-place
153-
val m2Dense = m2.deepCopy
154-
// Multiply m2Dense in-place with m
155-
var idx = 0
156-
var j = 0
157-
while j < m.cols do
158-
var i = 0
159-
while i < m.rows do
160-
m2Dense.raw(idx) = m2Dense.raw(idx) * m(i, j)
161-
i += 1
162-
idx += 1
163-
end while
164-
j += 1
165-
end while
151+
// m is dense column-major, materialize m2 to column-major and multiply in-place
152+
val m2Dense = m2.deepCopy(asRowMajor = false)
153+
vecxt.arrays.*=(m2Dense.raw)(m.raw)
154+
m2Dense
155+
else if m.isDenseRowMajor then
156+
// m is dense row-major, materialize m2 to row-major and multiply in-place
157+
val m2Dense = m2.deepCopy(asRowMajor = true)
158+
vecxt.arrays.*=(m2Dense.raw)(m.raw)
166159
m2Dense
167160
else if m2.isDenseColMajor then
168-
// m2 is already dense, materialize m and multiply in-place
169-
val mDense = m.deepCopy
170-
// Multiply mDense in-place with m2
171-
var idx = 0
172-
var j = 0
173-
while j < m.cols do
174-
var i = 0
175-
while i < m.rows do
176-
mDense.raw(idx) = mDense.raw(idx) * m2(i, j)
177-
i += 1
178-
idx += 1
179-
end while
180-
j += 1
181-
end while
161+
// m2 is dense column-major, materialize m to column-major and multiply in-place
162+
val mDense = m.deepCopy(asRowMajor = false)
163+
vecxt.arrays.*=(mDense.raw)(m2.raw)
164+
mDense
165+
else if m2.isDenseRowMajor then
166+
// m2 is dense row-major, materialize m to row-major and multiply in-place
167+
val mDense = m.deepCopy(asRowMajor = true)
168+
vecxt.arrays.*=(mDense.raw)(m2.raw)
182169
mDense
183170
else
184-
// Neither is dense column-major, materialize m and use SIMD multiplication
185-
val mDense = m.deepCopy
186-
val m2Dense = m2.deepCopy
171+
// Neither is dense, materialize both to column-major and use SIMD multiplication
172+
val mDense = m.deepCopy(asRowMajor = false)
173+
val m2Dense = m2.deepCopy(asRowMajor = false)
187174
val newArr = vecxt.arrays.*(mDense.raw)(m2Dense.raw)
188175
Matrix[Double](newArr, m.rows, m.cols)(using BoundsCheck.DoBoundsCheck.no)
189176
end if

0 commit comments

Comments
 (0)