Added the code and tests for forming problems involving replication, but currently one of the two (or both) is buggy
This commit is contained in:
parent
663cbaeaa1
commit
ed8033833b
|
@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along
|
||||||
with this program. If not, see <http://www.gnu.org/licenses/>.
|
with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-}
|
-}
|
||||||
|
|
||||||
module ArrayUsageCheck (checkArrayUsage, FlattenedExp(..), makeEquations, VarMap) where
|
module ArrayUsageCheck (checkArrayUsage, FlattenedExp(..), makeEquations, makeReplicatedEquations, VarMap) where
|
||||||
|
|
||||||
import Control.Monad.Error
|
import Control.Monad.Error
|
||||||
import Control.Monad.State
|
import Control.Monad.State
|
||||||
|
@ -175,7 +175,81 @@ makeExpSet = foldM makeExpSet' Set.empty
|
||||||
|
|
||||||
type VarMap = Map.Map FlattenedExp Int
|
type VarMap = Map.Map FlattenedExp Int
|
||||||
|
|
||||||
|
-- | Given a list of (replicated variable, start, count), a list of parallel array accesses, the length of the array,
|
||||||
|
-- returns the problems
|
||||||
|
makeReplicatedEquations :: [(A.Variable, A.Expression, A.Expression)] -> [A.Expression] -> A.Expression ->
|
||||||
|
Either String [(VarMap, (EqualityProblem, InequalityProblem))]
|
||||||
|
makeReplicatedEquations repVars accesses bound
|
||||||
|
= do flattenedAccesses <- mapM flatten accesses
|
||||||
|
let flattenedAccessesMirror = concatMap (\(v,_,_) -> mapMaybe (setIndexVar v 1) flattenedAccesses) repVars
|
||||||
|
-- TODO only compare with a mirror that involves the same replicated variable (TODO or not?)
|
||||||
|
bound' <- flatten bound
|
||||||
|
((v,h,repVars'),s) <- (flip runStateT) Map.empty $
|
||||||
|
do accesses' <- liftM2 (++) (mapM makeEquation flattenedAccesses) (mapM makeEquation flattenedAccessesMirror)
|
||||||
|
high <- makeEquation bound' >>= getSingleItem "Multiple possible upper bounds not supported"
|
||||||
|
repVars' <- mapM (\(v,s,c) ->
|
||||||
|
do s' <- lift (flatten s) >>= makeEquation >>= getSingleItem "Modulo or Divide not allowed in replication start"
|
||||||
|
c' <- lift (flatten c) >>= makeEquation >>= getSingleItem "Modulo or Divide not allowed in replication count"
|
||||||
|
return (v,s',c')) repVars
|
||||||
|
return (accesses',high, repVars')
|
||||||
|
repBounds <- makeRepBound repVars' s
|
||||||
|
return $ concatMap (\repBound -> squareAndPair repBound s v (amap (const 0) h, addConstant (-1) h)) repBounds
|
||||||
|
|
||||||
|
where
|
||||||
|
setIndexVar :: A.Variable -> Int -> [FlattenedExp] -> Maybe [FlattenedExp]
|
||||||
|
setIndexVar tv ti es = case mapAccumL (setIndexVar' tv ti) False es of
|
||||||
|
(True, es') -> Just es'
|
||||||
|
_ -> Nothing
|
||||||
|
|
||||||
|
setIndexVar' :: A.Variable -> Int -> Bool -> FlattenedExp -> (Bool,FlattenedExp)
|
||||||
|
setIndexVar' tv ti b s@(Scale n (v,_))
|
||||||
|
| EQ == customVarCompare tv v = (True,Scale n (v,ti))
|
||||||
|
| otherwise = (b,s)
|
||||||
|
setIndexVar' _ _ b e = (b,e)
|
||||||
|
|
||||||
|
makeRepBound ::
|
||||||
|
[(A.Variable, EqualityConstraintEquation, EqualityConstraintEquation)] ->
|
||||||
|
VarMap ->
|
||||||
|
Either String [InequalityProblem]
|
||||||
|
makeRepBound repVars vm = doPairs $ map (makeBound vm) repVars
|
||||||
|
where
|
||||||
|
doPairs :: Monad m => [m (InequalityProblem,InequalityProblem)] -> m [InequalityProblem]
|
||||||
|
doPairs prs = do prs' <- sequence prs
|
||||||
|
return $ doPairs' prs'
|
||||||
|
where
|
||||||
|
doPairs' :: [([a],[a])] -> [[a]]
|
||||||
|
doPairs' [] = [[]]
|
||||||
|
doPairs' ((a,b):abs) = map (a ++) (doPairs' abs) ++ map (b ++) (doPairs' abs)
|
||||||
|
|
||||||
|
makeBound :: VarMap -> (A.Variable, EqualityConstraintEquation, EqualityConstraintEquation) -> Either String (InequalityProblem,InequalityProblem)
|
||||||
|
makeBound vm (repVar, start, count)
|
||||||
|
= do plain <- findIndex repVar 0
|
||||||
|
prime <- findIndex repVar 1
|
||||||
|
return
|
||||||
|
(
|
||||||
|
-- start <= i gives i - start >= 0
|
||||||
|
[add (plain,1) (amap negate start)
|
||||||
|
-- i <= j - 1 gives j - 1 - i >= 0
|
||||||
|
,simpleArray [(0,-1),(prime,1),(plain,-1)]
|
||||||
|
-- j <= start + count - 1 gives start + count - j - 1 >= 0
|
||||||
|
,add (0,-1) $ add (prime, -1) $ arrayZipWith (+) start count]
|
||||||
|
,
|
||||||
|
-- start <= j gives j - start >= 0
|
||||||
|
[add (prime,1) (amap negate start)
|
||||||
|
-- j <= i - 1 gives i - 1 - j >= 0
|
||||||
|
,simpleArray [(0,-1),(plain,1),(prime,-1)]
|
||||||
|
-- i <= start + count - 1 gives start + count - i - 1 >= 0
|
||||||
|
,add (0,-1) $ add (plain, -1) $ arrayZipWith (+) start count]
|
||||||
|
)
|
||||||
|
where
|
||||||
|
findIndex v n = Map.lookup (Scale 1 (v,n)) vm
|
||||||
|
|
||||||
|
add :: (Int,Integer) -> Array Int Integer -> Array Int Integer
|
||||||
|
add (ind,val) a = (makeSize (newMin, newMax) 0 a) // [(ind, (arrayLookupWithDefault 0 a ind) + val)]
|
||||||
|
where
|
||||||
|
newMin = minimum [fst $ bounds a, ind]
|
||||||
|
newMax = maximum [snd $ bounds a, ind]
|
||||||
|
|
||||||
-- Note that in all these functions, the divisor should always be positive!
|
-- Note that in all these functions, the divisor should always be positive!
|
||||||
|
|
||||||
-- Takes an expression, and transforms it into an expression like:
|
-- Takes an expression, and transforms it into an expression like:
|
||||||
|
|
|
@ -330,6 +330,19 @@ testMakeEquations = TestList
|
||||||
leq [j ++ con 1, i ++ k, con 0] &&& leq [con 0, i ++ k, con 7] &&& leq [con 0, con 3, con 7])
|
leq [j ++ con 1, i ++ k, con 0] &&& leq [con 0, i ++ k, con 7] &&& leq [con 0, con 3, con 7])
|
||||||
], [buildExpr $ Dy (Var "i") A.Rem (Var "j"), intLiteral 3], intLiteral 8)
|
], [buildExpr $ Dy (Var "i") A.Rem (Var "j"), intLiteral 3], intLiteral 8)
|
||||||
|
|
||||||
|
,testRep (200,both_rep_i ([i === j],leq [con 1, i, j ++ con (-1), con 5] &&& leq [con 0, i, con 7] &&& leq [con 0, j, con 7]),
|
||||||
|
[(variable "i", intLiteral 1, intLiteral 6)],[exprVariable "i"],intLiteral 8)
|
||||||
|
|
||||||
|
,testRep (201,both_rep_i ([i === j],leq [con 1, i, j ++ con (-1), con 5] &&& leq [con 0, i, con 7] &&& leq [con 0, j, con 7])
|
||||||
|
++ [(rep_i_mapping,[i === con 3], leq [con 1,i, con 6] &&& leq [con 0, i, con 7] &&& leq [con 0, con 3, con 7])],
|
||||||
|
[(variable "i", intLiteral 1, intLiteral 6)],[exprVariable "i", intLiteral 3],intLiteral 8)
|
||||||
|
|
||||||
|
,testRep (202,[
|
||||||
|
(rep_i_mapping,[i === j ++ con 1],leq [con 1, i, j ++ con (-1), con 5] &&& leq [con 0, i, con 7] &&& leq [con 0, j, con 7])
|
||||||
|
,(rep_i_mapping,[i ++ con 1 === j],leq [con 1, i, j ++ con (-1), con 5] &&& leq [con 0, i, con 7] &&& leq [con 0, j, con 7])]
|
||||||
|
++ replicate 2 (rep_i_mapping,[i === j],leq [con 1, i, j ++ con (-1), con 5] &&& leq [con 0, i, con 7] &&& leq [con 0, j, con 7])
|
||||||
|
,[(variable "i", intLiteral 1, intLiteral 6)],[exprVariable "i", buildExpr $ Dy (Var "i") A.Add (Lit $ intLiteral 1)],intLiteral 8)
|
||||||
|
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
test :: (Integer,[(VarMap,[HandyEq],[HandyIneq])],[A.Expression],A.Expression) -> Test
|
test :: (Integer,[(VarMap,[HandyEq],[HandyIneq])],[A.Expression],A.Expression) -> Test
|
||||||
|
@ -337,7 +350,16 @@ testMakeEquations = TestList
|
||||||
TestCase $ assertEquivalentProblems ("testMakeEquations " ++ show ind)
|
TestCase $ assertEquivalentProblems ("testMakeEquations " ++ show ind)
|
||||||
(map (transformPair id (uncurry makeConsistent)) $ map pairLatterTwo problems) =<< (checkRight $ makeEquations exprs upperBound)
|
(map (transformPair id (uncurry makeConsistent)) $ map pairLatterTwo problems) =<< (checkRight $ makeEquations exprs upperBound)
|
||||||
|
|
||||||
|
testRep :: (Integer,[(VarMap,[HandyEq],[HandyIneq])],[(A.Variable, A.Expression, A.Expression)],[A.Expression],A.Expression) -> Test
|
||||||
|
testRep (ind, problems, reps, exprs, upperBound) =
|
||||||
|
TestCase $ assertEquivalentProblems ("testMakeEquations " ++ show ind)
|
||||||
|
(map (transformPair id (uncurry makeConsistent)) $ map pairLatterTwo problems)
|
||||||
|
=<< (checkRight $ makeReplicatedEquations reps exprs upperBound)
|
||||||
|
|
||||||
pairLatterTwo (a,b,c) = (a,(b,c))
|
pairLatterTwo (a,b,c) = (a,(b,c))
|
||||||
|
|
||||||
|
joinMapping :: [VarMap] -> ([HandyEq],[HandyIneq]) -> [(VarMap,[HandyEq],[HandyIneq])]
|
||||||
|
joinMapping vms (eq,ineq) = map (\vm -> (vm,eq,ineq)) vms
|
||||||
|
|
||||||
i_mapping = Map.singleton (Scale 1 $ (variable "i",0)) 1
|
i_mapping = Map.singleton (Scale 1 $ (variable "i",0)) 1
|
||||||
ij_mapping = Map.fromList [(Scale 1 $ (variable "i",0),1),(Scale 1 $ (variable "j",0),2)]
|
ij_mapping = Map.fromList [(Scale 1 $ (variable "i",0),1),(Scale 1 $ (variable "j",0),2)]
|
||||||
|
@ -351,7 +373,12 @@ testMakeEquations = TestList
|
||||||
,(Modulo (Set.singleton $ Scale 1 $ (variable "i",0)) (Set.singleton $ Const m),2)
|
,(Modulo (Set.singleton $ Scale 1 $ (variable "i",0)) (Set.singleton $ Const m),2)
|
||||||
,(Modulo (Set.fromList [Scale 1 $ (variable "i",0), Const 1]) (Set.singleton $ Const n),3)
|
,(Modulo (Set.fromList [Scale 1 $ (variable "i",0), Const 1]) (Set.singleton $ Const n),3)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
rep_i_mapping = Map.fromList [((Scale 1 (variable "i",0)),1), ((Scale 1 (variable "i",1)),2)]
|
||||||
|
rep_i_mapping' = Map.fromList [((Scale 1 (variable "i",0)),2), ((Scale 1 (variable "i",1)),1)]
|
||||||
|
|
||||||
|
both_rep_i = joinMapping [rep_i_mapping, rep_i_mapping']
|
||||||
|
|
||||||
-- Helper functions for i REM 2 vs (i + 1) REM 4. Each one is a pair of equalities, inequalities
|
-- Helper functions for i REM 2 vs (i + 1) REM 4. Each one is a pair of equalities, inequalities
|
||||||
rr_i_zero = ([i === con 0], leq [con 0,con 0,con 7])
|
rr_i_zero = ([i === con 0], leq [con 0,con 0,con 7])
|
||||||
rr_ip1_zero = ([i ++ con 1 === con 0], leq [con 0,con 0,con 7])
|
rr_ip1_zero = ([i ++ con 1 === con 0], leq [con 0,con 0,con 7])
|
||||||
|
|
Loading…
Reference in New Issue
Block a user