Giter Site home page Giter Site logo

Comments (4)

lehins avatar lehins commented on August 25, 2024

If there is a will, there is a way :D You bring up an interesting question. A solution with exact type signature you presented is not possible without some major change to underlying structure of the library, but that would be a wrong way to go about it anyways.

I am not sure if I will add any of the solutions to the library, but free to use either one of them

Here is a naive and less optimal solution to the problem:

defaultResizeNaive :: (Construct r ix' e, Source r ix e) => e -> ix' -> Array r ix e -> Array D ix' e
defaultResizeNaive e newsz arr =
  makeArray (getComp arr) newsz $
  handleBorderIndex (Fill e) oldsz (unsafeIndex arr) . fromLinearIndex oldsz . toLinearIndex newsz
  where oldsz = size arr

It is sub-optimal because it has to check if index doesn't go out of bounds for every element of new array. But the good thing is that resulting array is D so no intermediate array has been created and further computation can be fused. Which is also known as "pull" array.

A more involved solution is to actually iterate over the old array while loading it's elements into the new array, and if there is any unfilled space leftover fill it with default value:

defaultResize :: (Source r ix e, Mutable r' ix' e) => e -> ix' -> Array r ix e -> Array r' ix' e
defaultResize e newsz' arr =
  unsafePerformIO $ do
    let newsz = liftIndex (max 0) newsz'
        oldsz = size arr
        knew = totalElem newsz
        kold = min (totalElem oldsz) knew
        comp = getComp arr
    marr <- unsafeNew newsz
    case comp of
      Seq -> do
        loopM_ 0 (< kold) (+ 1) $ \i -> unsafeLinearWrite marr i (unsafeLinearIndex arr i)
        loopM_ kold (< knew) (+ 1) $ \i -> unsafeLinearWrite marr i e
      ParOn wIds ->
        withScheduler_ wIds $ \scheduler -> do
          splitLinearlyWith_
            (numWorkers scheduler)
            (scheduleWork scheduler)
            kold
            (unsafeLinearIndex arr)
            (unsafeLinearWrite marr)
          let slack = knew - kold
          splitLinearlyWith_
            (numWorkers scheduler)
            (scheduleWork scheduler)
            slack
            (const e)
            (unsafeLinearWrite marr . (+ kold))
    unsafeFreeze comp marr

The interesting part about the problem and this last solution is that it would be possible to create a delayed array as well, but of a different kind, namely a "push" array. I've been pondering on this idea for couple of weeks now and considering implementing this new kind of delayed array, we'll see. This would allow nicer solutions for a new class of problems, including this one.

cc @ocramz Thanks for pointing out the topic of Pull/Push arrays to me at Haskell Exchange, it already comes in handy ;)

from massiv.

kozross avatar kozross commented on August 25, 2024

Wow, I didn't realize it was this tricky! Ultimately, I'd be after a D array for my current use case, so I'll try both options and see which one works better.

Also, do you have any links about push/pull arrays I could read?

from massiv.

lehins avatar lehins commented on August 25, 2024

Here is a paper that gives a nice introduction to push pull arrays, but then goes into more stuff: https://svenssonjoel.github.io/writing/defuncEmb.pdf

from massiv.

lehins avatar lehins commented on August 25, 2024

Now that push arrays are available in massiv we can easily implement this function.

from massiv.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.