2

Say, I have the following functions that allow me to create matrices:

inline fun <reified T> Matrix2D(w: Int, h: Int, init: (Int, Int) -> T) =
    Array(w){ x -> Array(h){ y -> init(x, y) } }

inline fun <reified T> Matrix2D(w: Int, h: Int, value: T) =
    Array(w){ Array(h){ value } }

// For example:
val m = Matrix2D(400, 400) { x, y ->
    Color(x.toDouble() / 400.0, y.toDouble() / 400.0, 0.0)
}

I also don't want to allow for nullability, cause it's going to be a pain to deal with element access later.

How would I initialize such a matrix using multiple threads/coroutines, where each one initializes its own tile of the matrix, without allowing for nullability of the matrix cells?

Vitaly
  • 4,358
  • 7
  • 47
  • 59

1 Answers1

1

Yes, you can create a Matrix2D in parallel, for example:

val threads = Matrix2D(10, 3){x, y-> Thread.currentThread() }.flatten().distinct()

//              v--- size > 1
println(threads.size)

inline fun <reified T> Matrix2D(w: Int, h: Int, crossinline init: (Int, Int) -> T)=
       //                     v--- create array in parallel
       generatorOf(w){x -> Array(h) {y -> init(x, y) } }.map{ it() }.toTypedArray()
       //                          get the final result `Matrix2D` ---^

//                     v--- create array generator
inline fun <reified T> generatorOf(size: Int, crossinline init:(Int) -> T) = 
  //v--- you can use `ForkJoinPool#commonPool`, but it will run task in work thread
   ForkJoinPool(20).let {
       Array(size) { i -> it.submit(Callable { init(i) }).let { { it.get() } } }
       //                 return the lambda generator ()->T  ---^
   }

You also can write an extension function toArray to remove the middle map operation & promote the performance, for example:

inline fun <reified T> Matrix2D(w: Int, h: Int, crossinline init: (Int, Int) -> T)=
        //                         v--- init array elements in parallel
        generatorOf(w) { x -> Array(h) { y -> init(x, y) } }.toArray{it()}
        //           transform to the `Matrix2D` directly  ---^

//                                v--- convert Array<T> to Array<R>
inline fun <T,reified R> Array<T>.toArray(transform:(T)->R):Array<R>{
    return Array(size){i->transform(get(i))}
}

Why did the Matrix2D start threads in outer array initialization, you can see sum two double[][] with parallel stream as further.

holi-java
  • 29,655
  • 7
  • 72
  • 83