futhark-0.26.1: src-testing/Futhark/Optimise/ArrayLayout/AnalyseTests.hs
module Futhark.Optimise.ArrayLayout.AnalyseTests (tests) where
import Data.Map.Strict qualified as M
import Futhark.Analysis.AccessPattern
import Futhark.IR.GPU
import Futhark.IR.GPUTests ()
import Futhark.IR.SyntaxTests ()
import Test.Tasty
import Test.Tasty.HUnit
tests :: TestTree
tests = testGroup "Analyse" [analyseStmTests]
analyseStmTests :: TestTree
analyseStmTests =
testGroup
"analyseStm"
[analyseIndexTests, analyseDimAccessesTests]
analyseIndexTests :: TestTree
analyseIndexTests =
testGroup
"analyseIndex"
$ do
let arr_name = "xss_5144"
-- ============================= TestCase0 =============================
-- Most simple case where we want to manifest an array, hence, we record
-- the Index in the IndexTable.
let testCase0 = testCase "2D manifest" $ do
let ctx =
mempty
{ parents =
[ SegOpName (SegmentedMap "defunc_0_map_res_5204"),
LoopBodyName "defunc_0_f_res_5208"
],
assignments =
M.fromList
[ ("gtid_5205", VariableInfo mempty 0 mempty ThreadID),
("i_5209", VariableInfo mempty 1 mempty LoopVar)
]
}
let patternNames = ["b_5211"]
let dimFixes =
[ DimFix (Var "gtid_5205"),
DimFix (Var "i_5209")
]
let indexTable =
M.fromList
[ ( SegmentedMap "defunc_0_map_res_5204",
M.fromList
[ ( (arr_name, [], [0 .. 1]),
M.fromList
[ ( "b_5211",
[ DimAccess (M.fromList [("gtid_5205", Dependency 0 ThreadID)]) (Just "gtid_5205"),
DimAccess (M.fromList [("i_5209", Dependency 1 LoopVar)]) (Just "i_5209")
]
)
]
)
]
)
]
let (_, indexTable') = analyseIndex ctx patternNames arr_name dimFixes
indexTable' @?= indexTable
-- ============================= TestCase2 =============================
-- We don't want to manifest an array with only one dimension, so we don't
-- record anything in the IndexTable.
let testCase1 = testCase "1D manifest" $ do
let ctx =
mempty
{ parents =
[ SegOpName (SegmentedMap "defunc_0_map_res_5204"),
LoopBodyName "defunc_0_f_res_5208"
]
}
let patternNames = ["b_5211"]
let dimFixes = [DimFix "i_5209"]
let (_, indexTable') = analyseIndex ctx patternNames arr_name dimFixes
indexTable' @?= mempty
-- ============================= TestCase1 =============================
-- We don't want to record anything to the IndexTable when the array is
-- not accessed inside a SegMap
-- TODO: Create a similar one for MC with loops
let testCase2 = testCase "Not inside SegMap" $ do
let ctx = mempty
let patternNames = ["b_5211"]
let dimFixes =
[ DimFix "gtid_5205",
DimFix "i_5209"
]
let (_, indexTable') = analyseIndex ctx patternNames arr_name dimFixes
indexTable' @?= mempty
-- ============================= TestCase3 =============================
-- If an array is allocated inside a loop or SegMap, we want to record that
-- information in the ArrayName of the IndexTable.
let testCase3 = testCase "Allocated inside SegMap" $ do
let parents' =
[ SegOpName (SegmentedMap "defunc_0_map_res_5204"),
LoopBodyName "defunc_0_f_res_5208"
]
let ctx =
mempty
{ parents = parents',
assignments =
M.fromList
[ ("gtid_5205", VariableInfo mempty 0 mempty ThreadID),
("i_5209", VariableInfo mempty 1 mempty LoopVar),
(arr_name, VariableInfo mempty 0 parents' Variable)
]
}
let patternNames = ["b_5211"]
let dimFixes =
[ DimFix "gtid_5205",
DimFix "i_5209"
]
let indexTable =
M.fromList
[ ( SegmentedMap "defunc_0_map_res_5204",
M.fromList
[ ( (arr_name, parents', [0 .. 1]),
M.fromList
[ ( "b_5211",
[ DimAccess (M.fromList [("gtid_5205", Dependency 0 ThreadID)]) (Just "gtid_5205"),
DimAccess (M.fromList [("i_5209", Dependency 1 LoopVar)]) (Just "i_5209")
]
)
]
)
]
)
]
let (_, indexTable') = analyseIndex ctx patternNames arr_name dimFixes
indexTable' @?= indexTable
-- ============================= TestCase4 =============================
-- If the vars in the index are temporaries, we want to reduce them to
-- to the thread IDs and or loop counters they are functions of.
let testCase4 = testCase "Reduce dependencies" $ do
let ctx =
mempty
{ parents =
[ SegOpName (SegmentedMap "defunc_0_map_res_5204"),
LoopBodyName "defunc_0_f_res_5208"
],
assignments =
M.fromList
[ ("gtid_5205", VariableInfo mempty 0 mempty ThreadID),
("i_5209", VariableInfo mempty 1 mempty LoopVar),
("tmp0_5210", VariableInfo (namesFromList ["gtid_5205"]) 2 mempty Variable),
("tmp1_5211", VariableInfo (namesFromList ["i_5209"]) 3 mempty Variable),
("k_5212", VariableInfo mempty 1 mempty ConstType)
]
}
let patternNames = ["b_5211"]
let dimFixes =
[ DimFix "tmp0_5210",
DimFix "tmp1_5211",
DimFix "k_5212"
]
let indexTable =
M.fromList
[ ( SegmentedMap "defunc_0_map_res_5204",
M.fromList
[ ( (arr_name, [], [0 .. 2]),
M.fromList
[ ( "b_5211",
[ DimAccess (M.fromList [("gtid_5205", Dependency 0 ThreadID)]) (Just "tmp0_5210"),
DimAccess (M.fromList [("i_5209", Dependency 1 LoopVar)]) (Just "tmp1_5211"),
DimAccess mempty (Just "k_5212")
]
)
]
)
]
)
]
let (_, indexTable') = analyseIndex ctx patternNames arr_name dimFixes
indexTable' @?= indexTable
[testCase0, testCase1, testCase2, testCase3, testCase4]
analyseDimAccessesTests :: TestTree
analyseDimAccessesTests = testGroup
"analyseDimAccesses"
$ do
let testCase0 = testCase "Fold" $ do
let indexTable =
M.fromList
[ ( SegmentedMap "defunc_0_map_res_5204",
M.fromList
[ ( ("xss_5144", [], [0, 1]),
M.fromList
[ ( "b_5211",
[ DimAccess (M.fromList [("gtid_5205", Dependency 0 ThreadID)]) (Just "gtid_5205"),
DimAccess (M.fromList [("i_5209", Dependency 1 LoopVar)]) (Just "i_5209")
]
)
]
)
]
)
]
let indexTable' = (analyseDimAccesses @GPU) prog0
indexTable' @?= indexTable
[testCase0]
where
prog0 :: Prog GPU
prog0 =
"\
\fun\
\ entry_main (n_5142 : i64,\
\ m_5143 : i64,\
\ xss_5144 : [n_5142][m_5143]i64)\
\ : {[n_5142]i64#([2], [0])} = {\
\ let {segmap_group_size_5202 : i64} =\
\ get_size(segmap_group_size_5190, thread_block_size)\
\ let {segmap_usable_groups_5203 : i64} =\
\ sdiv_up64(n_5142, segmap_group_size_5202)\
\ let {defunc_0_map_res_5204 : [n_5142]i64} =\
\ segmap(thread; ; grid=segmap_usable_groups_5203; blocksize=segmap_group_size_5202)\
\ (gtid_5205 < n_5142) (~phys_tid_5206) : {i64} {\
\ let {defunc_0_f_res_5208 : i64} =\
\ loop {acc_5210 : i64} = {0i64}\
\ for i_5209:i64 < m_5143 do {\
\ let {b_5211 : i64} =\
\ xss_5144[gtid_5205, i_5209]\
\ let {defunc_0_f_res_5212 : i64} =\
\ add64(acc_5210, b_5211)\
\ in {defunc_0_f_res_5212}\
\ }\
\ return {returns defunc_0_f_res_5208}\
\ }\
\ in {defunc_0_map_res_5204}\
\}"