@@ -124,23 +124,59 @@ type CSRMatrix<'a when 'a : struct and 'a : equality>(csrTuples: CSRFormat<'a>)
124124 override this.Transpose () = failwith " Not Implemented"
125125 override this.Kronecker a b c = failwith " Not Implemented"
126126
127- and COOMatrix < 'a when 'a : struct and 'a : equality >( rowCount : int , columnCount : int , rows : int [], columns : int [], values : 'a []) =
127+ and COOMatrix < 'a when 'a : struct and 'a : equality >( rowCount : int , columnCount : int , indices : uint64 [], values : 'a []) =
128128 inherit Matrix< 'a>( rowCount, columnCount)
129129
130- let mutable rows , columns , values = rows, columns, values
131- member this.Rows with get() = rows
132- member this.Columns with get() = columns
130+ let mutable indices = indices
131+ let mutable values = values
132+ // member this.Rows with get() = rows
133+ // member this.Columns with get() = columns
134+ member this.Indices with get() = indices
133135 member this.Values with get() = values
134- member this.Elements with get() = ( rows, columns, values) |||> Array.zip3
136+
137+ new ( rowCount : int , columnCount : int , rows : int [], columns : int [], values : 'a []) =
138+ let indices =
139+ [| for i in 0 .. rows.Length do
140+ yield ( uint64) rows.[ i] <<< 32 ||| ( uint64) columns.[ i] |]
141+ COOMatrix( rowCount, columnCount, indices, values)
135142
136143 override this.Clear () = failwith " Not Implemented"
137144 override this.Copy () = failwith " Not Implemented"
138145 override this.Resize a b = failwith " Not Implemented"
139146 override this.GetNNZ () = failwith " Not Implemented"
140147
141148 override this.GetTuples () =
149+
150+ let indicesLength = indices.Length
151+
152+ let unpack =
153+ <@
154+ fun ( ndRange : _1D )
155+ ( indicesBuffer : uint64 [])
156+ ( rowsBuffer : int [])
157+ ( columnsBuffer : int []) ->
158+
159+ let i = ndRange.GlobalID0
160+ if i < indicesLength then
161+ let doubleIndex = indicesBuffer.[ i]
162+ rowsBuffer.[ i] <- ( int)( doubleIndex >>> 32 )
163+ columnsBuffer.[ i] <- ( int) doubleIndex
164+ @>
165+
166+ let rows = Array.zeroCreate indicesLength
167+ let columns = Array.zeroCreate indicesLength
168+
169+ let binder kernelP =
170+ let ndRange = _ 1D( workSize indicesLength, workGroupSize)
171+ kernelP
172+ ndRange
173+ indices
174+ rows
175+ columns
176+
142177 opencl {
143- return {| Rows = this.Rows; Columns = this.Columns; Values = this.Values |}
178+ do ! RunCommand unpack binder
179+ return {| Rows = rows; Columns = columns; Values = this.Values |}
144180 }
145181
146182 override this.GetMask (? isComplemented : bool ) =
@@ -149,9 +185,10 @@ and COOMatrix<'a when 'a : struct and 'a : equality>(rowCount: int, columnCount:
149185
150186 override this.ToHost () =
151187 opencl {
152- let! _ = ToHost this.Rows
153- let! _ = ToHost this.Columns
154- let! _ = ToHost this.Values
188+ let! tuples = this.GetTuples ()
189+ let! _ = ToHost tuples.Rows
190+ let! _ = ToHost tuples.Columns
191+ let! _ = ToHost tuples.Values
155192
156193 return upcast this
157194 }
@@ -181,43 +218,39 @@ and COOMatrix<'a when 'a : struct and 'a : equality>(rowCount: int, columnCount:
181218 let zero = semiring.PlusMonoid.Zero
182219
183220 //It is useful to consider that the first array is longer than the second one
184- let firstRows , firstColumns , firstValues , secondRows , secondColumns , secondValues , plus =
185- if this.Rows .Length > matrix.Rows .Length then
186- this.Rows , this.Columns , this. Values, matrix.Rows , matrix.Columns , matrix.Values, append
221+ let firstIndices , firstValues , secondIndices , secondValues , plus =
222+ if this.Indices .Length > matrix.Indices .Length then
223+ this.Indices , this.Values, matrix.Indices , matrix.Values, append
187224 else
188- matrix.Rows , matrix.Columns , matrix. Values, this.Rows , this.Columns , this.Values, <@ fun x y -> (% append) y x @>
225+ matrix.Indices , matrix.Values, this.Indices , this.Values, <@ fun x y -> (% append) y x @>
189226
190227 let filterThroughMask =
191228 opencl {
192229 //TODO
193230 ()
194231 }
195232
196- let allRows = Array.zeroCreate <| firstRows.Length + secondRows.Length
197- let allColumns = Array.zeroCreate <| firstColumns.Length + secondColumns.Length
233+ let allIndices = Array.zeroCreate <| firstIndices.Length + secondIndices.Length
198234 let allValues = Array.create ( firstValues.Length + secondValues.Length) zero
199235
200- let longSide = firstRows .Length
201- let shortSide = secondRows .Length
236+ let longSide = firstIndices .Length
237+ let shortSide = secondIndices .Length
202238
203- let allRowsLength = allRows .Length
239+ let allIndicesLength = allIndices .Length
204240
205241 let createSortedConcatenation =
206242 <@
207243 fun ( ndRange : _1D )
208- ( firstRowsBuffer : int [])
209- ( firstColumnsBuffer : int [])
244+ ( firstIndicesBuffer : uint64 [])
210245 ( firstValuesBuffer : 'a [])
211- ( secondRowsBuffer : int [])
212- ( secondColumnsBuffer : int [])
246+ ( secondIndicesBuffer : uint64 [])
213247 ( secondValuesBuffer : 'a [])
214- ( allRowsBuffer : int [])
215- ( allColumnsBuffer : int [])
248+ ( allIndicesBuffer : uint64 [])
216249 ( allValuesBuffer : 'a []) ->
217250
218251 let i = ndRange.GlobalID0
219252
220- if i < allRowsLength then
253+ if i < allIndicesLength then
221254 let f n = if 0 > n + 1 - shortSide then 0 else n + 1 - shortSide
222255 let mutable leftEdge = f i
223256
@@ -226,83 +259,70 @@ and COOMatrix<'a when 'a : struct and 'a : equality>(rowCount: int, columnCount:
226259
227260 while leftEdge <= rightEdge do
228261 let middleIdx = ( leftEdge + rightEdge) / 2
229- let firstRow = firstRowsBuffer.[ middleIdx]
230- let firstColumn = firstColumnsBuffer.[ middleIdx]
231- let secondRow = secondRowsBuffer.[ i - middleIdx]
232- let secondColumn = secondColumnsBuffer.[ i - middleIdx]
233- if firstRow < secondRow || firstRow = secondRow && firstColumn < secondColumn then leftEdge <- middleIdx + 1 else rightEdge <- middleIdx - 1
262+ let firstIndex = firstIndicesBuffer.[ middleIdx]
263+ let secondIndex = secondIndicesBuffer.[ i - middleIdx]
264+ if firstIndex < secondIndex then leftEdge <- middleIdx + 1 else rightEdge <- middleIdx - 1
234265
235266 let boundaryX = rightEdge
236267 let boundaryY = i - leftEdge
237268
238269 if boundaryX < 0 then
239- allRowsBuffer.[ i] <- secondRowsBuffer.[ boundaryY]
240- allColumnsBuffer.[ i] <- secondColumnsBuffer.[ boundaryY]
270+ allIndicesBuffer.[ i] <- secondIndicesBuffer.[ boundaryY]
241271 allValuesBuffer.[ i] <- secondValuesBuffer.[ boundaryY]
242272 elif boundaryY < 0 then
243- allRowsBuffer.[ i] <- firstRowsBuffer.[ boundaryX]
244- allColumnsBuffer.[ i] <- firstColumnsBuffer.[ boundaryX]
273+ allIndicesBuffer.[ i] <- firstIndicesBuffer.[ boundaryX]
245274 allValuesBuffer.[ i] <- firstValuesBuffer.[ boundaryX]
246275 else
247- let firstRow = firstRowsBuffer.[ boundaryX]
248- let firstColumn = firstColumnsBuffer.[ boundaryX]
249- let secondRow = secondRowsBuffer.[ boundaryY]
250- let secondColumn = secondColumnsBuffer.[ boundaryY]
251- if firstRow < secondRow || firstRow = secondRow && firstColumn < secondColumn then
252- allRowsBuffer.[ i] <- secondRow
253- allColumnsBuffer.[ i] <- secondColumn
276+ let firstIndex = firstIndicesBuffer.[ boundaryX]
277+ let secondIndex = secondIndicesBuffer.[ boundaryY]
278+ if firstIndex < secondIndex then
279+ allIndicesBuffer.[ i] <- secondIndex
254280 allValuesBuffer.[ i] <- secondValuesBuffer.[ boundaryY]
255281 else
256- allRowsBuffer.[ i] <- firstRow
257- allColumnsBuffer.[ i] <- firstColumn
282+ allIndicesBuffer.[ i] <- firstIndex
258283 allValuesBuffer.[ i] <- firstValuesBuffer.[ boundaryX]
259284 @>
260285
261286 let createSortedConcatenation =
262287 opencl {
263288 let binder kernelP =
264- let ndRange = _ 1D( workSize allRows .Length, workGroupSize)
289+ let ndRange = _ 1D( workSize allIndices .Length, workGroupSize)
265290 kernelP
266291 ndRange
267- firstRows
268- firstColumns
292+ firstIndices
269293 firstValues
270- secondRows
271- secondColumns
294+ secondIndices
272295 secondValues
273- allRows
274- allColumns
296+ allIndices
275297 allValues
276298 do ! RunCommand createSortedConcatenation binder
277299 }
278300
279- let auxiliaryArray = Array.create allRows .Length 1
301+ let auxiliaryArray = Array.create allIndices .Length 1
280302
281303 let fillAuxiliaryArray =
282304 <@
283305 fun ( ndRange : _1D )
284- ( allRowsBuffer : int [])
285- ( allColumnsBuffer : int [])
306+ ( allIndicesBuffer : uint64 [])
286307 ( allValuesBuffer : 'a [])
287308 ( auxiliaryArrayBuffer : int []) ->
288309
289- let i = ndRange.GlobalID0 + 1
310+ let i = ndRange.GlobalID0
290311
291- if i < allRowsLength && allRowsBuffer .[ i - 1 ] = allRowsBuffer .[ i ] && allColumnsBuffer .[ i - 1 ] = allColumnsBuffer .[ i] then
292- auxiliaryArrayBuffer.[ i] <- 0
293- let localResultBuffer = (% plus) allValuesBuffer.[ i - 1 ] allValuesBuffer.[ i]
312+ if i < allIndicesLength - 1 && allIndicesBuffer .[ i] = allIndicesBuffer .[ i + 1 ] then
313+ auxiliaryArrayBuffer.[ i + 1 ] <- 0
314+ let localResultBuffer = (% plus) allValuesBuffer.[ i] allValuesBuffer.[ i + 1 ]
294315 //Drop explicit zeroes
295316 if localResultBuffer = zero then auxiliaryArrayBuffer.[ i] <- 0 else allValuesBuffer.[ i] <- localResultBuffer
296317 @>
297318
298319 let fillAuxiliaryArray =
299320 opencl {
300321 let binder kernelP =
301- let ndRange = _ 1D( workSize ( allRows.Length - 1 ), workGroupSize)
322+ let ndRange = _ 1D( workSize ( allIndicesLength - 1 ), workGroupSize)
302323 kernelP
303324 ndRange
304- allRows
305- allColumns
325+ allIndices
306326 allValues
307327 auxiliaryArray
308328 do ! RunCommand fillAuxiliaryArray binder
@@ -313,27 +333,23 @@ and COOMatrix<'a when 'a : struct and 'a : equality>(rowCount: int, columnCount:
313333 let createUnion =
314334 <@
315335 fun ( ndRange : _1D )
316- ( allRowsBuffer : int [])
317- ( allColumnsBuffer : int [])
336+ ( allIndicesBuffer : uint64 [])
318337 ( allValuesBuffer : 'a [])
319338 ( auxiliaryArrayBuffer : int [])
320339 ( prefixSumArrayBuffer : int [])
321- ( resultRowsBuffer : int [])
322- ( resultColumnsBuffer : int [])
340+ ( resultIndicesBuffer : uint64 [])
323341 ( resultValuesBuffer : 'a []) ->
324342
325343 let i = ndRange.GlobalID0
326344
327345 if i < auxiliaryArrayLength && auxiliaryArrayBuffer.[ i] = 1 then
328346 let index = prefixSumArrayBuffer.[ i] - 1
329347
330- resultRowsBuffer.[ index] <- allRowsBuffer.[ i]
331- resultColumnsBuffer.[ index] <- allColumnsBuffer.[ i]
348+ resultIndicesBuffer.[ index] <- allIndicesBuffer.[ i]
332349 resultValuesBuffer.[ index] <- allValuesBuffer.[ i]
333350 @>
334351
335- let resultRows = Array.zeroCreate allRows.Length
336- let resultColumns = Array.zeroCreate allColumns.Length
352+ let resultIndices = Array.zeroCreate allIndices.Length
337353 let resultValues = Array.create allValues.Length zero
338354
339355 let createUnion =
@@ -343,13 +359,11 @@ and COOMatrix<'a when 'a : struct and 'a : equality>(rowCount: int, columnCount:
343359 let ndRange = _ 1D( workSize auxiliaryArray.Length, workGroupSize)
344360 kernelP
345361 ndRange
346- allRows
347- allColumns
362+ allIndices
348363 allValues
349364 auxiliaryArray
350365 prefixSumArray
351- resultRows
352- resultColumns
366+ resultIndices
353367 resultValues
354368 do ! RunCommand createUnion binder
355369 }
@@ -360,7 +374,7 @@ and COOMatrix<'a when 'a : struct and 'a : equality>(rowCount: int, columnCount:
360374 do ! fillAuxiliaryArray
361375 do ! createUnion
362376
363- return upcast COOMatrix< 'a>( this.RowCount, this.ColumnCount, resultRows , resultColumns , resultValues)
377+ return upcast COOMatrix< 'a>( this.RowCount, this.ColumnCount, resultIndices , resultValues)
364378 }
365379
366380 override this.EWiseAdd
0 commit comments