Code generation for array map is wasteful #742
RyanGlScott
started this conversation in
General
Replies: 1 comment
-
|
One thing to note is that different languages have different ways of performing array maps idiomatically. In C, this would be accomplished with something like a |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Consider the following, minimized Copilot example:
{-# LANGUAGE DataKinds #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE TypeApplications #-} module Main where import Data.Proxy (Proxy(..)) import GHC.TypeLits (natVal) import Copilot.Compile.C99 (compile) import Language.Copilot type N = 3 arr1, arr2 :: Stream (Array N Word32) arr1 = extern "arr1" Nothing arr2 = foldr (\idx acc -> acc !! constW32 idx =$ (+ constW32 (idx + 100))) arr1 [0..(n-1)] where n :: Word32 n = fromInteger $ natVal $ Proxy @N spec :: Spec spec = trigger "trig" true [arg arr2] main :: IO () main = do spec' <- reify spec compile "array-update" spec'This takes an external array (
arr1) and produces a new arrayarr2by addingidx + 100to each element ofarr1, whereidxis the corresponding element's index. In the example above whereN(the size of the array) is3, this means that we would add0 + 100,1 + 100, and2 + 100, respectively, to each element ofarr1. In principle, this should only require three additions, but if you look at the generated C code:There are seven additions! As you increase the value of
N, the number of additions grows exponentially:NIt appears that Copilot isn't sharing
Arraysub-expressions like I would expect it to. If you add explicit sharing by using thelocalcombinator:Then the generated code produces exactly
Nadditions, as expected.Could we modify Copilot's handling of array accesses/updates to ensure that we don't needlessly duplicate sub-expressions?
Beta Was this translation helpful? Give feedback.
All reactions